Vic*_*lov 4 java time date iso8601
我使用DateTimeFormatter的格式字符串:uuuu-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"
result: 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);
Run Code Online (Sandbox Code Playgroud)
JDK 1.8.0_192(Oracle,而不是OpenJDK)
这有点复杂.正如jvdmr所说,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));
}
Run Code Online (Sandbox Code Playgroud)
此代码段的输出是:
Run Code Online (Sandbox Code Playgroud)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建议不要对ISO日期时间格式进行硬编码.由于编写格式模式字符串容易出错,因此这可能是一个好主意.例如:
DateTimeFormatter formatter = new DateTimeFormatterBuilder()
.append(DateTimeFormatter.ISO_LOCAL_DATE_TIME)
.appendPattern("[XXXXX][XXXX][X]")
.toFormatter();
Run Code Online (Sandbox Code Playgroud)
使用此格式化程序的输出与使用上述格式化程序的输出相同.它更啰嗦,但我们很容易认为这是值得的,因为它不易出错,可能更清晰,更容易阅读.
从文档 (重点是我的):
偏移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]"
| 归档时间: |
|
| 查看次数: |
465 次 |
| 最近记录: |