我的方法的输入将是一个String
,其中包含以UTC表示的日期。我需要将输入日期与当前日期和时间进行比较,并检查两个日期之间的差异。结果应该在几天之内。
我尝试以下操作均未成功。
String dateString = "2019-06-18T16:23:41.575 UTC";
final DateTimeFormatter formatter1 = DateTimeFormatter.ofPattern("yyyy-MM-dd'T'HH:mm:ss.SSS 'UTC'").withZone(ZoneId.of("UTC"));
OffsetDateTime parsedDate = OffsetDateTime.parse(dateString, formatter1);
System.out.println("======================:"+parsedDate.format(formatter1));
OffsetDateTime currentUTC = OffsetDateTime.now(ZoneOffset.UTC);
System.out.println("Until (with crono): " + parsedDate.until(currentUTC, ChronoUnit.DAYS));
我需要一个int
(即天数)中的结果。
第OffsetDateTime parsedDate = OffsetDateTime.parse(dateString, formatter1);
行引发了以下堆栈跟踪的异常:
Exception in thread "main" java.time.format.DateTimeParseException: Text '2019-06-18T16:23:41.575 UTC' could not be parsed: Unable to obtain OffsetDateTime from TemporalAccessor: {InstantSeconds=1560875021},ISO,UTC resolved to 2019-06-18T16:23:41.575 of type java.time.format.Parsed
at java.base/java.time.format.DateTimeFormatter.createError(DateTimeFormatter.java:1959)
at java.base/java.time.format.DateTimeFormatter.parse(DateTimeFormatter.java:1894)
at java.base/java.time.OffsetDateTime.parse(OffsetDateTime.java:402)
at thiagarajanramanathan.misc.App.main(App.java:86)
Caused by: java.time.DateTimeException: Unable to obtain OffsetDateTime from TemporalAccessor: {InstantSeconds=1560875021},ISO,UTC resolved to 2019-06-18T16:23:41.575 of type java.time.format.Parsed
at java.base/java.time.OffsetDateTime.from(OffsetDateTime.java:370)
at java.base/java.time.format.Parsed.query(Parsed.java:235)
at java.base/java.time.format.DateTimeFormatter.parse(DateTimeFormatter.java:1890)
... 3 more
Caused by: java.time.DateTimeException: Unable to obtain ZoneOffset from TemporalAccessor: {InstantSeconds=1560875021},ISO,UTC resolved to 2019-06-18T16:23:41.575 of type java.time.format.Parsed
at java.base/java.time.ZoneOffset.from(ZoneOffset.java:348)
at java.base/java.time.OffsetDateTime.from(OffsetDateTime.java:359)
... 5 more
答案 0 :(得分:2)
从该线程可以看到:Unable to obtain OffsetDateTime from TemporalAccessor
我更改了以下几行:
//OffsetDateTime parsedDate = OffsetDateTime.parse(dateString, formatter1);
ZonedDateTime parsedDate = ZonedDateTime.parse(dateString, formatter1);
使用此修改运行您的代码时,我可以获得以下结果
“ 2019-06-18T16:23:41.575 UTC”:
======================:2019-06-17T16:23:41.575 UTC
Until (with crono): 0
由于少于24小时,它返回0
“ 2019-06-17T16:23:41.575 UTC”:
======================:2019-06-17T16:23:41.575 UTC
Until (with crono): 1
类似地,由于时间超过24小时但不到2天,因此返回1。
我想这就是你想要的。请尝试一下,让我知道这是否适合您。
答案 1 :(得分:1)
如果要使输入符合ISO 8601标准,我将简化解析。
String input = "2019-06-18T16:23:41.575 UTC".replace( " UTC", "Z" ) ;
Instant instant = Instant.parse( input ) ;
如果您定义的经过时间是24小时,请使用Duration
。
Duration d = Duration.between( instant , Instant.now() ;
long days = d.toDays() ;
如果您希望从日历上看到经过的天数,这意味着日期而不是24小时的时间段,则必须指定一个时区。
ZoneId z = ZoneId.of( "Africa/Tunis" ) ;
ZonedDateTime zdt = instant.atZone( z ) ;
ZonedDateTime now = ZonedDateTime.now( z ) ;
提取日期。
LocalDate start = zdt.toLocalDate() ;
LocalDate stop = now.toLocalDate() ;
long days = ChronoUnit.DAYS.between( start , stop ) ;
答案 2 :(得分:1)
您已经有两个不错的答案。您正在接触java.time的一个有趣且有点棘手的部分,因此我也想做出自己的贡献。我的要点是时区和UTC偏移量不相同。要获得OffsetDateTime
,您需要一个偏移量。您通过格式化程序上的呼叫.withZone(ZoneId.of("UTC"))
提供了一个时区,但这对您没有帮助。是的,您和我都知道UTC是所有偏移量的基础,因此它本身将偏移量定义为0。但是Java并未从您的代码中发现偏移量。
我承认我惊讶地发现以下简单更改足以使您的代码在Java 9上运行:
final DateTimeFormatter formatter1
= DateTimeFormatter.ofPattern("yyyy-MM-dd'T'HH:mm:ss.SSS 'UTC'")
.withZone(ZoneOffset.UTC);
但是在Java 8上,我仍然遇到与以前相同的异常。我在Java 9.0.4上获得的输出是:
======================:2019-06-18T16:23:41.575 UTC Until (with crono): 0
唯一的变化是我现在将ZoneOffset
而不是ZoneId
对象传递给withZone
(这是可能的,因为ZoneOffset
是{{1 }}。
在Java 8上也可以使用的格式化程序就是我们提供默认偏移量的格式化程序。为此,我们需要一个ZoneId
:
DateTimeFormatterBuilder
另一个可能更简单的选择是先解析为 final DateTimeFormatter formatter1 = new DateTimeFormatterBuilder()
.append(DateTimeFormatter.ISO_LOCAL_DATE_TIME)
.appendLiteral(" UTC")
.parseDefaulting(ChronoField.OFFSET_SECONDS, 0)
.toFormatter();
(既不需要偏移量也不需要时区),然后通过调用LocalDateTime
转换为OffsetDateTime
。