您要问的问题是hh
(两次)在格式模式字符串中使用小写字母。您需要HH
从00到23的小时中的大写字母,hh
是从01到12的AM或PM中的小时数。因此出了问题,java.time不知道12
您的字符串中是12 AM还是12 PM并拒绝为您猜测。
如果您仔细阅读异常消息,您还会注意到该异常消息已HourOfAmPm=0
被解析。没有说HourOfDay
。
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
String timestampString = LocalDateTime.Now().format(formatter);
System.out.println("timestampString: " + timestampString);
Instant instant = LocalDateTime.parse(timestampString, formatter)
.toInstant(ZoneOffset.UTC);
System.out.println("instant: " + instant);
timestampString: 2019-06-08 19:22:51
instant: 2019-06-08T19:22:51Z
这是 错的 !我在世界标准时间17:22而非19:22左右运行了代码段。由于丹麦仍在使用夏令时(该死),因此此处的当地时间为19:22,用于显示结果,并转换为UTC的相同挂钟时间,而不是同一时刻。您应该始终 将所需的时区传递给该Now
方法,以避免此类错误。由于您想要UTC:
String timestampString = LocalDateTime.Now(ZoneOffset.UTC).format(formatter);
timestampString: 2019-06-08 17:27:57
instant: 2019-06-08T17:27:57Z
更好的是,不要LocalDateTime
用于保留您想暂时使用的东西。使用Instant
,OffsetDateTime
或zoneddatetime
代替。
在此问题及其答案中hh
,有更多有关使用HH
或kk
用于格式化和解析小时值的信息:SimpleDateFormat上的java HH:mm和hh:mm之间的区别。问题是问的出了名的麻烦SimpleDateFormat
,但答案也同样有效DateTimeFormatter
。