Java Instant.parse 日期 java 8
Java Instant.parse on Date java 8
我有一些包含时间戳条目的旧版 KML 文档。
为什么使用 Instant 解析时以下日期无效?这两种方法都假设解析 ISO 8601 格式的日期。
String dateString = "2017-12-04T08:06:60Z"
使用
java.time.Instant.parse(dateString)
引发错误
"DateTimeParseException Text 2017-12-04T08:06:60Z could not be parsed at index 0."
但是,当使用
Date myDate = javax.xml.bind.DatatypeConverter.parseDateTime( dateString )
myDate 被正确解析....
60
秒不是有效时间。这意味着这是无效的 2017-12-04T08:06:60Z
,如果它是 60 秒,那么分钟应该增加并且 你的 时间将是 2017-12-04T08:07:00Z
使用有效日期然后解析 String 就可以了:
String date = "2017-12-04T08:07:00Z";
System.out.println(Instant.parse(date));
同时 java.time 忽略 leap 秒。来自 docs:
Implementations of the Java time-scale using the JSR-310 API are not
required to provide any clock that is sub-second accurate, or that
progresses monotonically or smoothly. Implementations are therefore
not required to actually perform the UTC-SLS slew or to otherwise be
aware of leap seconds. JSR-310 does, however, require that
implementations must document the approach they use when defining a
clock representing the current instant. See Clock for details on the
available clocks.
接受的答案很好。我只有两件事要补充:
- 您可以 使用
ResolverStyle.LENIENT
. 解析具有无效第二个值60 的字符串
- 由于 Jon Skeet 在评论中提到了可能的闰秒:这不是有效的闰秒。 java.time 支持解析(有效的)闰秒。
正在解析您的字符串
DateTimeFormatter lenientFormatter
= DateTimeFormatter.ISO_OFFSET_DATE_TIME
.withResolverStyle(ResolverStyle.LENIENT);
String dateString = "2018-12-04T08:06:60Z";
Instant myInstant = lenientFormatter.parse(dateString, Instant::from);
System.out.println(myInstant);
输出:
2018-12-04T08:07:00Z
因此溢出的秒值 60 已滚入整整一分钟。
顺便说一句,javax.xml.bind.DatatypeConverter.parseDateTime
解析为 Calendar
(不是 Date
),这就是返回的对象实际上可以保存第二个值 60 的方式。看起来它通常接受第二个值 60,但在 61 时抛出异常。
解析有效闰秒
这并不能回答您的问题,但我认为它可能对未来的读者有用。闰秒始终是当天的最后一秒,因此 23:59:60。一个Instant
不能持有这个值,但是你可以查询一个是否被解析。通过 DateTimeFormatterBuilder.appendInstant(),
和 DateTimeFormatter.parsedLeapSecond()
.
支持
DateTimeFormatter leapSecondFormatter = new DateTimeFormatterBuilder()
.appendInstant()
.toFormatter();
Instant myInstant
= leapSecondFormatter.parse("2018-12-04T23:59:60Z", Instant::from);
System.out.println(myInstant);
TemporalAccessor parsed = leapSecondFormatter.parse("2018-12-04T23:59:60Z");
System.out.println("Instant: " + parsed.query(Instant::from));
System.out.println("Was a leap second parsed? "
+ parsed.query(DateTimeFormatter.parsedLeapSecond()));
输出:
2018-12-04T23:59:59Z
Instant: 2018-12-04T23:59:59Z
Was a leap second parsed? true
我不知道为什么要这么复杂,但它确实有效。
我有一些包含时间戳条目的旧版 KML 文档。 为什么使用 Instant 解析时以下日期无效?这两种方法都假设解析 ISO 8601 格式的日期。
String dateString = "2017-12-04T08:06:60Z"
使用
java.time.Instant.parse(dateString)
引发错误
"DateTimeParseException Text 2017-12-04T08:06:60Z could not be parsed at index 0."
但是,当使用
Date myDate = javax.xml.bind.DatatypeConverter.parseDateTime( dateString )
myDate 被正确解析....
60
秒不是有效时间。这意味着这是无效的2017-12-04T08:06:60Z
,如果它是 60 秒,那么分钟应该增加并且 你的 时间将是2017-12-04T08:07:00Z
使用有效日期然后解析 String 就可以了:
String date = "2017-12-04T08:07:00Z"; System.out.println(Instant.parse(date));
同时 java.time 忽略 leap 秒。来自 docs:
Implementations of the Java time-scale using the JSR-310 API are not required to provide any clock that is sub-second accurate, or that progresses monotonically or smoothly. Implementations are therefore not required to actually perform the UTC-SLS slew or to otherwise be aware of leap seconds. JSR-310 does, however, require that implementations must document the approach they use when defining a clock representing the current instant. See Clock for details on the available clocks.
接受的答案很好。我只有两件事要补充:
- 您可以 使用
ResolverStyle.LENIENT
. 解析具有无效第二个值60 的字符串
- 由于 Jon Skeet 在评论中提到了可能的闰秒:这不是有效的闰秒。 java.time 支持解析(有效的)闰秒。
正在解析您的字符串
DateTimeFormatter lenientFormatter
= DateTimeFormatter.ISO_OFFSET_DATE_TIME
.withResolverStyle(ResolverStyle.LENIENT);
String dateString = "2018-12-04T08:06:60Z";
Instant myInstant = lenientFormatter.parse(dateString, Instant::from);
System.out.println(myInstant);
输出:
2018-12-04T08:07:00Z
因此溢出的秒值 60 已滚入整整一分钟。
顺便说一句,javax.xml.bind.DatatypeConverter.parseDateTime
解析为 Calendar
(不是 Date
),这就是返回的对象实际上可以保存第二个值 60 的方式。看起来它通常接受第二个值 60,但在 61 时抛出异常。
解析有效闰秒
这并不能回答您的问题,但我认为它可能对未来的读者有用。闰秒始终是当天的最后一秒,因此 23:59:60。一个Instant
不能持有这个值,但是你可以查询一个是否被解析。通过 DateTimeFormatterBuilder.appendInstant(),
和 DateTimeFormatter.parsedLeapSecond()
.
DateTimeFormatter leapSecondFormatter = new DateTimeFormatterBuilder()
.appendInstant()
.toFormatter();
Instant myInstant
= leapSecondFormatter.parse("2018-12-04T23:59:60Z", Instant::from);
System.out.println(myInstant);
TemporalAccessor parsed = leapSecondFormatter.parse("2018-12-04T23:59:60Z");
System.out.println("Instant: " + parsed.query(Instant::from));
System.out.println("Was a leap second parsed? "
+ parsed.query(DateTimeFormatter.parsedLeapSecond()));
输出:
2018-12-04T23:59:59Z Instant: 2018-12-04T23:59:59Z Was a leap second parsed? true
我不知道为什么要这么复杂,但它确实有效。