我用DateTimeFormatter格式字符串:★★★★-MM-dd'T'HH:MM:SSX
其必须支持时区的所有可能的格式偏移,包括:Z,00,00:00,0000
据官方DateTimeFormatter文件,“X”限定符必须匹配这些格式,以抵消:
X区偏移 'Z' 为零点偏移-X Z; -08; -0830; -08:30; -083015; -08:30:15;
但事实上,它不
输入字符串: “2014-01-01T00:30:00 + 00:00”
结果:java.time.format.DateTimeParseException:文本 '2014-01-01T00:30:00 + 00:00' 无法解析,索引22发现未解析文本
输入字符串: “2014-01-01T00:30:00Z”
结果:正确
编码:
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("uuuu-MM-dd'T'HH:mm:ssX");
OffsetDateTime parsed = OffsetDateTime.parse(dateTimeAsString, formatter);
JDK 1.8.0_192(甲骨文,而不是OpenJDK的)
这是一个有点复杂。 As jvdmr says,各X事项的计数。 XXXXX
将认识-08:30:15
,但不-083015
。 XXXX
会认识后者,而不是前者。
要采取一切可能的例子格式考虑,我们需要指定不同的可能性。这可以用方括号中的格式模式字符串内完成。这些包含可选部分。一些实验表明,以下模式涵盖了所有的例子:
uuuu-MM-dd'T'HH:mm:ss[XXXXX][XXXX][X]
让我们来尝试一下:
DateTimeFormatter formatter
= DateTimeFormatter.ofPattern("uuuu-MM-dd'T'HH:mm:ss[XXXXX][XXXX][X]");
for (String dts : new String[] {
"2014-01-01T00:30:00-08:30:15", "2014-01-01T00:30:00-083015",
"2014-01-01T00:30:00-08:30", "2014-01-01T00:30:00-0830",
"2014-01-01T00:30:00-08", "2014-01-01T00:30:00Z",
}) {
System.out.println(OffsetDateTime.parse(dts, formatter));
}
从这个片断的输出是:
2014-01-01T00:30-08:30:15 2014-01-01T00:30-08:30:15 2014-01-01T00:30-08:30 2014-01-01T00:30-08:30 2014-01-01T00:30-08:00 2014-01-01T00:30Z
编辑
VelNaga suggests没有硬编码ISO日期时间格式。由于书写格式模式字符串容易出错,这可能是一个好主意。例如:
DateTimeFormatter formatter = new DateTimeFormatterBuilder()
.append(DateTimeFormatter.ISO_LOCAL_DATE_TIME)
.appendPattern("[XXXXX][XXXX][X]")
.toFormatter();
使用该格式器输出是相同的,与使用上述的一个。这是wordier,但我们可以很容易地最终认为这是值得的,因为它是容易出错以下,可更清晰,更易于阅读。
从docs(重点煤矿):
偏移x和x:该格式化偏移基于模式字母的数目。一个字母就在小时的输出,如“01”,除非分钟非零在这种情况下,分也被输出,如“0130”。两个字母输出的小时和分钟,没有结肠,如“0130”。三个字母输出小时和分钟,以冒号,例如“01:30”。四个字母输出小时和分钟和任选的第二未经结肠,如“013015”。五个字母输出小时和分钟和任选的第二,以冒号,例如“01:30:15”。六个或多个字母抛出IllegalArgumentException异常。图案字母“X”(大写)会输出“Z”当偏移要输出将为零,而图案字母“X”(小写)会输出“00”,“0000”,或“00 :00' 。
这也适用于反向解析日期。你想既没有冒号解析,这意味着你将不得不使用可选的部分,因为没有单一的模式支持这一点。试试这个模式:"uuuu-MM-dd'T'HH:mm:ss[XXX][XXXX]"
不要硬编码任何ISO日期格式。 DateFormatter已经为ISO日期格式转换的静态方法。使用下面的代码,
DateTimeFormatter格式化= DateTimeFormatter.ISO_ZONED_DATE_TIME;
OffsetDateTime解析= OffsetDateTime.parse(dateTimeAsString,格式化器);
这将肯定工作。详情请见link更多的格式选项。