Java 8 如何在一个DateTimeFormat Java 8中处理所有区域偏移

Java 8 如何在一个DateTimeFormat Java 8中处理所有区域偏移,java-8,java-time,datetime-parsing,zoneddatetime,Java 8,Java Time,Datetime Parsing,Zoneddatetime,我需要为以下有效日期创建一个DateTimeFormatter String date1 = "2017-06-20T17:25:28"; String date2 = "2017-06-20T17:25:28.477777"; String date3 = "2017-06-20T17:25:28.477777Z"; String date4 = "2017-06-20T17:25:28.477777UTC"; String date5 = "2017-06-20T17:2

我需要为以下有效日期创建一个
DateTimeFormatter

  String date1 = "2017-06-20T17:25:28";
  String date2 = "2017-06-20T17:25:28.477777";
  String date3 = "2017-06-20T17:25:28.477777Z";
  String date4 = "2017-06-20T17:25:28.477777UTC";
  String date5 = "2017-06-20T17:25:28.477777-05";
  String date6 = "2017-06-20T17:25:28.477777+05";
  String date7 = "2017-06-20T17:25:28.477777+05:30";
  String date8 = "2017-06-20T17:25:28.477777-05:30";
  String date9 = "2017-06-20T17:25:28.477777+0530";
  String date10 = "2017-06-20T17:25:28.477777-0530";
我尝试了以下日期-时间格式化程序,但在最后两个日期(
date9
date10
)都失败了

date1
date8
的所有日期都可以正常工作,但我在尝试解析最后两个日期时遇到了
DateTimeParseException

线程“main”java.time.format.DateTimeParseException中的异常:无法分析文本“2017-06-20T17:25:28.477777+0530”,在索引29中找到未分析的文本

用于解析我正在使用的日期,如下所示

LocalDateTime.parse(date1, DATE_TIME_FORMATTER);
偏移距
offsetidParser
的有效模式:

static final class OffsetIdPrinterParser implements DateTimePrinterParser {
        static final String[] PATTERNS = new String[] {
            "+HH", "+HHmm", "+HH:mm", "+HHMM", "+HH:MM", "+HHMMss", "+HH:MM:ss", "+HHMMSS", "+HH:MM:SS",
        };  // order used in pattern builder

当我使用有效的区域偏移模式时,我无法理解我最近两次约会失败的原因。

只需颠倒可选部分的顺序即可:

private static final DateTimeFormatter DATE_TIME_FORMATTER = new DateTimeFormatterBuilder()
        .appendPattern("yyyy-MM-dd'T'HH:mm:ss")
        .appendFraction(ChronoField.MICRO_OF_SECOND, 0, 6, true)
        .optionalStart().appendZoneId().optionalEnd()
        .optionalStart().appendOffset("+HHmm", "+0000").optionalEnd()
        .optionalStart().appendOffset("+HH:mm", "+00:00").optionalEnd()
        .optionalStart().appendOffset("+HH", "+00").optionalEnd()
        .toFormatter();
这将解析所有10个示例日期时间字符串


我不太清楚它为什么有效。我假设它现在尝试在
+HH
之前使用
+HHmm
,这确保它在有四个数字时得到所有四个数字,而不是保留最后两个未解析的数字。

另一种选择是使用可选部分,由
[]
分隔,以及相应的(
VV
x
):

每对
[]
相当于一个
可选开始
可选结束
部分。请注意,我还必须将大写的
S
(秒的分数)作为可选项,以解析不存在此字段的情况

其他模式(
VV
x
)对应于您需要的各种偏移。从:

模式计数等效生成器方法
-------  -----  --------------------------
VV 2 appendZoneId()
x 1附件偏移量(“+HHmm”,“+00”)
xx 2附录偏移量(“+HHMM”、“+0000”)
xxx 3附录偏移量(“+HH:MM”,“+00:00”)
这适用于所有输入日期


唯一的区别是
[.SSSSSS]
秒数字段中准确地接受6位数字(或零位数字,因为它是可选部分),而
appendFraction
接受从0到6位的任何数量。要获得完全相同的行为,必须使用
DateTimeFormatterBuilder

static final class OffsetIdPrinterParser implements DateTimePrinterParser {
        static final String[] PATTERNS = new String[] {
            "+HH", "+HHmm", "+HH:mm", "+HHMM", "+HH:MM", "+HHMMss", "+HH:MM:ss", "+HHMMSS", "+HH:MM:SS",
        };  // order used in pattern builder
DATE\u TIME\u FORMATTER=new DateTimeFormatterBuilder()
//日期和时间
.appendPattern(“yyyy-MM-dd'T'HH:MM:ss”)
//秒的分数,从0到6位
.appendFraction(ChronoField.MICRO_/u秒,0,6,真)
//可选偏移模式
.appendPattern(“[VV][x][xx][xxx]”)
.toFormatter();

@Eugene但我们仍然需要找到Java为什么这么做。顺序中有一点逻辑在起作用。正则表达式没有直接的可比性,仍然是“猫”。replaceFirst(“cat | cats”,“bird”)产生
鸟,而相反的顺序是
“cats”。replaceFirst(“cat | cat”,“bird”)
,只产生
鸟。日期时间格式化程序甚至没有给我们一个或,就像在正则表达式中一样,只是一系列的部分,每个部分都是可选的,所以我想除了按顺序尝试它们之外别无选择。
DATE_TIME_FORMATTER = DateTimeFormatter
                         // pattern with optional sections: fraction of seconds and offsets
                         .ofPattern("yyyy-MM-dd'T'HH:mm:ss[.SSSSSS][VV][x][xx][xxx]");