本文主要是介绍Unable to obtain ZonedDateTime from TemporalAccessor: {},ISO resolved to xxx of type...,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!
环境
java:1.8
Intellij IDEA:2019.2.4
前言
想把字符串格式的时间转为OffsetDateTime
时,报了以下错误:
Unable to obtain ZonedDateTime from TemporalAccessor: {},
ISO resolved to 2019-10-13T00:00 of type java.time.format.Parsed
代码
看看我的解析代码:
public static void main(String[] args) {String value = "2019-10-13 00:00:00";String DATE_TIME_SECOND_STRING = "yyyy-MM-dd HH:mm:ss";DateTimeFormatter dateTimeFormatter = DateTimeFormatter.ofPattern(DATE_TIME_SECOND_STRING);OffsetDateTime offsetDateTime = ZonedDateTime.parse(value, dateTimeFormatter).toOffsetDateTime();System.out.println(offsetDateTime);
}
为什么会报错呢?
我们要知道,世界完整的时间,只有三种表示方式:
① Instant
② OffsetDateTime
③ ZoneDateTime
其中Instant
给机器看的,OffsetDateTime
是以时区偏移量来表示世界完整时间;
ZoneDateTime
是通过指定时区的方式来表示世界完整时间.
回到我上面的例子:
字符串:
String value = "2019-10-10 00:00:00";
是个时间字符串,但是呢,中国人看这个时间和美国人看这个时间是不一样的,因为中国和美国有时差,具体点,就是上面这段时间字符串,没有指定时区。
所以在用上面的解析代码时,就报错了。
解决办法也很简单,就是加上时区就行了。
方法一
将上面的代码补上时区:
DateTimeFormatter dateTimeFormatter = DateTimeFormatter.ofPattern(DATE_TIME_SECOND_STRING)
.withZone(ZoneId.systemDefault());
方法二
DateTimeFormatter formatter = new DateTimeFormatterBuilder().appendPattern(DATE_TIME_SECOND_STRING)
.parseDefaulting(ChronoField.NANO_OF_DAY,0).toFormatter().withZone(ZoneId.systemDefault());
这段代码和方法一类似,就是多了.parseDefaulting(ChronoField.NANO_OF_DAY,0)
。这个意思是,从纳秒开始,没有指定的值,用0
填充。
方法三
上面的时间字符串,在java8
中对应的类是LocalDateTime
,它和世界完整时间的差距就是缺一个时区。
思路就是:
① 我们先转成LocalDateTime
② 再补上时区
String value = "2019-10-13 00:00:00";
String DATE_TIME_SECOND_STRING = "yyyy-MM-dd HH:mm:ss";
// 先将时间字符串转成LocalDateTime
LocalDateTime parse = LocalDateTime.parse(value, dateTimeFormatter);
// 再补上时区得到完整世界时间
OffsetDateTime offsetDateTime1 = ZonedDateTime.of(parse, ZoneId.systemDefault()).toOffsetDateTime();
System.out.println(offsetDateTime1);
结果:
2019-10-13T00:00+08:00
总结
这次的异常,再次让我对java8
的时间有了更深的认识。
以前java7
中的时间,对应是LocalDate
或者LocalDateTime
这两个类。
java8
引入了时区的概念后,就有了世界完整时间的表示:
① Instant
② OffsetDateTime
③ ZoneDateTime
其中Instant
给机器看的;
OffsetDateTime
是以时区偏移量来表示世界完整时间;比如我们中国东8区,
就是+8(偏移量)
ZoneDateTime
是通过指定时区的方式来表示世界完整时间。
比如:ZoneId.of("Asia/Shanghai")
时差可以参考:
https://www.zeitverschiebung.net/cn/city/1816670
参考地址:
Java8学习笔记:LocalDateTime、Instant 和 OffsetDateTime 相互转换
http://www.it1352.com/616373.html
这篇关于Unable to obtain ZonedDateTime from TemporalAccessor: {},ISO resolved to xxx of type...的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!