OffsetDateTime解析
OffsetDateTime解析
需要从格式为2016-06-24T13:39:44.687680
的日期时间中解析出日期时间。首先尝试使用以下代码解析不带微秒的时间:\n
System.out.println(OffsetDateTime.parse("2011-12-03T10:15:30", DateTimeFormatter.ISO_LOCAL_DATE_TIME));
\n出现异常\n
Exception in thread "main" java.time.format.DateTimeParseException: 无法解析文本'2011-12-03T10:15:30':无法从TemporalAccessor获取OffsetDateTime:{},ISO解析为类型为java.time.format.Parsed的2011-12-03T10:15:30 at java.time.format.DateTimeFormatter.createError(DateTimeFormatter.java:1920) at java.time.format.DateTimeFormatter.parse(DateTimeFormatter.java:1855) at java.time.OffsetDateTime.parse(OffsetDateTime.java:402) at timeread.TimeReading.main(TimeReading.java:18) at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) at java.lang.reflect.Method.invoke(Method.java:498) at com.intellij.rt.execution.application.AppMain.main(AppMain.java:140) Caused by: java.time.DateTimeException: 无法从TemporalAccessor获取OffsetDateTime:{},ISO解析为类型为java.time.format.Parsed的2011-12-03T10:15:30 at java.time.OffsetDateTime.from(OffsetDateTime.java:370) at java.time.format.Parsed.query(Parsed.java:226) at java.time.format.DateTimeFormatter.parse(DateTimeFormatter.java:1851) ... 7 more Caused by: java.time.DateTimeException: 无法从TemporalAccessor获取ZoneOffset:{},ISO解析为类型为java.time.format.Parsed的2011-12-03T10:15:30 at java.time.ZoneOffset.from(ZoneOffset.java:348) at java.time.OffsetDateTime.from(OffsetDateTime.java:359) ... 9 more
\n尝试使用DateTimeFormatter
和TimeZone
:\n
System.out.println(OffsetDateTime.parse("2011-12-03T10:15:30", DateTimeFormatter.ISO_LOCAL_DATE_TIME.withZone(ZoneId.systemDefault())));
\n类似的异常:\n
Exception in thread "main" java.time.format.DateTimeParseException: 无法解析文本'2011-12-03T10:15:30':无法从TemporalAccessor获取OffsetDateTime:{InstantSeconds=1322892930},ISO,Europe/Moscow解析为类型为java.time.format.Parsed的2011-12-03T10:15:30 at java.time.format.DateTimeFormatter.createError(DateTimeFormatter.java:1920) at java.time.format.DateTimeFormatter.parse(DateTimeFormatter.java:1855) at java.time.OffsetDateTime.parse(OffsetDateTime.java:402) at timeread.TimeReading.main(TimeReading.java:18) at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) at java.lang.reflect.Method.invoke(Method.java:498) at com.intellij.rt.execution.application.AppMain.main(AppMain.java:140) Caused by: java.time.DateTimeException: 无法从TemporalAccessor获取OffsetDateTime:{InstantSeconds=1322892930},ISO,Europe/Moscow解析为类型为java.time.format.Parsed的2011-12-03T10:15:30 at java.time.OffsetDateTime.from(OffsetDateTime.java:370) at java.time.format.Parsed.query(Parsed.java:226) at java.time.format.DateTimeFormatter.parse(DateTimeFormatter.java:1851) ... 7 more Caused by: java.time.DateTimeException: 无法从TemporalAccessor获取ZoneOffset:{InstantSeconds=1322892930},ISO,Europe/Moscow解析为类型为java.time.format.Parsed的2011-12-03T10:15:30 at java.time.ZoneOffset.from(ZoneOffset.java:348) at java.time.OffsetDateTime.from(OffsetDateTime.java:359) ... 9 more
问题出现的原因是使用标准的DateTimeFormatter.ISO_OFFSET_DATE_TIME无法解析一个稍微非标准的ISO日期格式"2021-01-14T09:25:33+0000",因为它要求偏移量中包含冒号。解决方法是使用DateTimeFormatterBuilder来创建一个定制的日期时间格式化器,从现有的ISO格式中添加偏移量。
解决方法的代码如下:
DateTimeFormatter customFormatter = new DateTimeFormatterBuilder() .append(DateTimeFormatter.ISO_LOCAL_DATE_TIME) .appendOffset("+HHMM","Z") .toFormatter();
在这段代码中,关键的部分是使用`.appendOffset()`方法,而不是使用`.ofPattern()`方法,因为后者似乎无法处理偏移量的解析。
根据维基百科的说明,这种非标准的ISO日期格式是合法的,并且被广泛使用。DateTimeFormatter.ISO_OFFSET_DATE_TIME期望偏移量中包含冒号,而上述日期格式中的偏移量没有冒号。你可以在维基百科的ISO 8601规范中找到更多关于时间偏移量的信息。
OffsetDateTime parsing问题出现的原因是OffsetDateTime.parse方法要求传入的字符串包含一个偏移量(+/-hh:mm),而"2011-12-03T10:15:30"并没有偏移量。解决方法是使用LocalDateTime.parse解析该字符串,并使用OffsetDateTime.of方法将结果转换为OffsetDateTime类型。
代码示例:
String dateTimeString = "2011-12-03T10:15:30"; LocalDateTime localDateTime = LocalDateTime.parse(dateTimeString); OffsetDateTime offsetDateTime = OffsetDateTime.of(localDateTime, ZoneOffset.UTC);
以上代码将字符串"2011-12-03T10:15:30"解析为LocalDateTime类型的对象localDateTime,然后使用OffsetDateTime.of方法将其转换为OffsetDateTime类型的对象offsetDateTime。在转换过程中,偏移量被设置为ZoneOffset.UTC,你也可以根据需要设置其他的偏移量。
这样,就可以成功解决OffsetDateTime parsing问题。
OffsetDateTime解析的问题出现的原因是在解析日期时间时使用了错误的方法。OffsetDateTime表示带有偏移量的日期时间,需要使用zone offset来创建。如果尝试使用ZoneId来解析日期时间,则应该使用ZonedDateTime。
解决方法是根据需要选择正确的类来解析日期时间。如果需要带有偏移量的日期时间,应使用OffsetDateTime。如果需要带有时区的日期时间,应使用ZonedDateTime。如果只需要ISO-8601日历系统中没有时区信息的日期时间,可以使用LocalDateTime。
下面是一些示例代码:
OffsetDateTime.parse("2011-12-03T10:15:30+01:00", DateTimeFormatter.ISO_OFFSET_DATE_TIME);
ZonedDateTime.parse("2011-12-03T10:15:30", DateTimeFormatter.ISO_LOCAL_DATE_TIME.withZone(ZoneId.systemDefault()));
LocalDateTime.parse("2016-06-24T13:39:44.687680", DateTimeFormatter.ISO_LOCAL_DATE_TIME);
通过选择正确的类来解析日期时间,可以避免OffsetDateTime解析问题。