简体   繁体   English

将Java 8 ISO 8601持续时间表达式添加到java.util.Date

[英]Add a Java 8 ISO 8601 time duration expression to java.util.Date

I have an expression like "PT20.345S" , "P2DT3H4M" etc as described here https://docs.oracle.com/javase/8/docs/api/java/time/Duration.html#parse-java.lang.CharSequence- 我有一个像"PT20.345S""P2DT3H4M"等表达式,如https://docs.oracle.com/javase/8/docs/api/java/time/Duration.html#parse-java.lang所述。 CharSequence-

How can I parse this, add it to the current time and get a java.util.Date object? 我如何解析它,将它添加到当前时间并获取java.util.Date对象?

Neither works: 两者都不起作用:

Date d1 = Date.from(LocalDateTime.now().plus(Duration.parse(_expression)));
Date d2 = Date.from(Duration.parse(_expression).addTo(LocalDateTime.now()));
Duration amountToAdd = Duration.parse("PT20.345S");  // Represent a span of time. Here, about twenty and a third seconds.
Instant now = Instant.now() ;                        // Capture the current moment in UTC.
Instant otherMoment = now.plus(amountToAdd);         // Add the span-of-time to the current moment, for a moment in the future (or in the past if the duration is negative).
String output = otherMoment.toString():              // Generate a String in standard ISO 8601 format.

2018-06-30T19:34:47Z 2018-06-30T19:34:47Z

Convert from modern java.time class to legacy class. 从现代java.time类转换为遗留类。

Date date1 = Date.from(otherMoment);
System.out.println(date1);

Running just now in Europe/Copenhagen time zone I got: 刚刚在欧洲/哥本哈根时区运行我得到:

Sat Jun 30 21:34:47 CEST 2018 6月30日星期六21:34:47 CEST 2018

If I use your other example duration string, P2DT3H4M , I got: 如果我使用你的另一个示例持续时间字符串P2DT3H4M ,我得到:

Tue Jul 03 00:38:26 CEST 2018 星期二03月03日00:38:26 CEST 2018

Or if you're into one-liners: 或者,如果你是一个单行:

    Date date1 = Date.from(Instant.now().plus(Duration.parse("PT20.345S")));

The java.util.Date class is long outdated, so ideally you shouldn't want to have one. java.util.Date类很久了,所以理想情况下你不应该有一个。 If you need one anyway, typically for a legacy API that you cannot change or don't want to change just now, you are thinking correctly when doing as much of the logic as possible using java.time , the modern Java date and time API, and converting to Date only in the end. 如果您还需要一个,通常是对于您无法更改或不想立即更改的旧API,您在使用java.time (现代Java日期和时间API)尽可能多地执行逻辑时正在思考,最后只转换为Date Date 's closest cousin in the modern world is Instant , and direct conversions between Instant and Date exist, which is why I am using this class. 现代世界中Date最亲近的堂兄是Instant ,并且InstantDate之间存在直接转换,这就是我使用这个类的原因。 An Instant is also lovely independent of zone offsets and time zones. Instant也很可爱,不受区域偏移和时区的影响。

In your code, the first solution should work if you convert the LocalDateTime to Instant with ZoneOffset (example UTC, or default of your system using ZoneOffset.systemDefault() ) like below: 在您的代码中,如果您使用ZoneOffsetLocalDateTime转换为Instant (示例UTC,或使用ZoneOffset.systemDefault()系统默认值),第一个解决方案应该可以正常工作,如下所示:

Date d1 = Date.from(LocalDateTime.now().plus(Duration.parse(_expression)).toInstant(OffsetDateTime.now().getOffset());

However , LocalDateTime is wrongly used in this case, because it does not represent a moment, is not a point on the timeline 但是 ,在这种情况下, LocalDateTime被错误地使用,因为它不代表片刻,不是时间轴上的一个点

From javadoc : 来自javadoc

This class does not store or represent a time-zone. 此类不存储或表示时区。 Instead, it is a description of the date, as used for birthdays, combined with the local time as seen on a wall clock. 相反,它是用于生日的日期的描述,结合在挂钟上看到的当地时间。 It cannot represent an instant on the time-line without additional information such as an offset or time-zone. 如果没有附加信息(如偏移或时区),它不能代表时间线上的瞬间。

But, an Instant is a moment on the timeline in UTC 但是, Instant是UTC时间轴上的一个时刻

This class models a single instantaneous point on the time-line. 该类在时间线上模拟单个瞬时点。 This might be used to record event time-stamps in the application. 这可能用于在应用程序中记录事件时间戳。

So, if you use an Instant, you know exactly what moment in time is being referred to, regardless of time zones. 因此,如果您使用Instant,则无论时区如何,您都可以确切地知道正在引用的时刻。 Since you are going to handle the business logic like adding amount of time to current time and convert to Date, this is a handy class to be used. 由于您将处理业务逻辑,例如将时间量添加到当前时间并转换为Date,因此这是一个方便使用的类。

 Date date1 = Date.from(Instant.now().plus(Duration.parse("PT20.345S")));

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM