我有以下代码将Instant转换为String,然后将其转换回I
String timestampString = LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyy-MM-dd hh:mm:ss"));
LOGGER.info("timestampString: " + timestampString);
Instant instant =
LocalDateTime.parse(timestampString,
DateTimeFormatter.ofPattern("yyyy-MM-dd hh:mm:ss")).toInstant(ZoneOffset.UTC);
它将timestampString打印为:2019-06-07 12:45:57
并且无法解析字符串:
java.time.format.DateTimeParseException: Text '2019-06-07 12:45:57' could not be parsed: Unable to obtain LocalDateTime from TemporalAccessor: {MinuteOfHour=45, HourOfAmPm=0, NanoOfSecond=0, SecondOfMinute=57, MilliOfSecond=0, MicroOfSecond=0},ISO resolved to 2019-06-07 of type java.time.format.Parsed
为什么即使我将时间戳转换成相同的格式也无法解析它?
答案 0 :(得分:2)
您要询问的问题是(两次)在格式模式字符串中使用小写的hh
。您需要从00到23的一天中的大写HH
。hh
是从01到12的AM或PM中的一个小时。因此,出问题的是java.time不知道{{1 }}中的字符串提到12 AM或12 PM,并拒绝为您猜测。
如果您仔细阅读异常消息,您还将注意到它指出12
已被解析。它没有说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);
这是错误!我在世界标准时间17:22而非19:22左右运行了代码段。由于丹麦仍在使用夏令时(该死),因此此处的当地时间为19:22,用于显示结果,并转换为UTC的相同挂钟时间,而不是同一时刻。您应该始终将所需的时区传递给timestampString: 2019-06-08 19:22:51
instant: 2019-06-08T19:22:51Z
方法,以避免此类错误。由于您需要UTC:
now
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
格式化和解析小时值in this question and its answers: Difference between java HH:mm and hh:mm on SimpleDateFormat的更多信息。问题是要问的是kk
非常麻烦的问题,但答案也对SimpleDateFormat
同样有效。