添加一个 Java 8 ISO 8601 持续时间表达式到 java.util.Date
Add a Java 8 ISO 8601 time duration expression to java.util.Date
我有一个表达式,如 "PT20.345S"
、"P2DT3H4M"
等,如此处所述 https://docs.oracle.com/javase/8/docs/api/java/time/Duration.html#parse-java.lang.CharSequence-
我如何解析它,将它添加到当前时间并得到一个 java.util.Date
对象?
均无效:
Date d1 = Date.from(LocalDateTime.now().plus(Duration.parse(_expression)));
Date d2 = Date.from(Duration.parse(_expression).addTo(LocalDateTime.now()));
在您的代码中,如果您使用 ZoneOffset
将 LocalDateTime
转换为 Instant
(例如 UTC,或使用 ZoneOffset.systemDefault()
的系统默认值,则第一个解决方案应该有效) 如下所示:
Date d1 = Date.from(LocalDateTime.now().plus(Duration.parse(_expression)).toInstant(OffsetDateTime.now().getOffset());
但是,LocalDateTime
在这种情况下是错误使用的,因为它不代表一个时刻,不是时间轴上的一个点
来自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.
但是,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.
因此,如果您使用 Instant,则无论时区如何,您都可以准确知道所指的时间点。由于您要处理业务逻辑,例如将时间量添加到当前时间并转换为日期,因此使用起来很方便 class。
Date date1 = Date.from(Instant.now().plus(Duration.parse("PT20.345S")));
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
从现代 java.time class 转换为传统 class.
Date date1 = Date.from(otherMoment);
System.out.println(date1);
运行刚才在Europe/Copenhagen时区我得到:
Sat Jun 30 21:34:47 CEST 2018
如果我使用您的其他示例持续时间字符串 P2DT3H4M
,我得到:
Tue Jul 03 00:38:26 CEST 2018
或者如果你喜欢单线:
Date date1 = Date.from(Instant.now().plus(Duration.parse("PT20.345S")));
java.util.Date
class 早就过时了,所以理想情况下你不应该想要一个。如果您无论如何都需要一个,通常是您现在无法更改或不想更改的遗留 API,那么在使用 java.time
执行尽可能多的逻辑时,您的想法是正确的,现代 Java 日期和时间 API,最后只转换为 Date
。 Date
在现代世界的近亲是 Instant
,Instant
和 Date
之间存在直接转换,这就是我使用这个 class 的原因。 Instant
独立于区域偏移量和时区也很可爱。
我有一个表达式,如 "PT20.345S"
、"P2DT3H4M"
等,如此处所述 https://docs.oracle.com/javase/8/docs/api/java/time/Duration.html#parse-java.lang.CharSequence-
我如何解析它,将它添加到当前时间并得到一个 java.util.Date
对象?
均无效:
Date d1 = Date.from(LocalDateTime.now().plus(Duration.parse(_expression)));
Date d2 = Date.from(Duration.parse(_expression).addTo(LocalDateTime.now()));
在您的代码中,如果您使用 ZoneOffset
将 LocalDateTime
转换为 Instant
(例如 UTC,或使用 ZoneOffset.systemDefault()
的系统默认值,则第一个解决方案应该有效) 如下所示:
Date d1 = Date.from(LocalDateTime.now().plus(Duration.parse(_expression)).toInstant(OffsetDateTime.now().getOffset());
但是,LocalDateTime
在这种情况下是错误使用的,因为它不代表一个时刻,不是时间轴上的一个点
来自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.
但是,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.
因此,如果您使用 Instant,则无论时区如何,您都可以准确知道所指的时间点。由于您要处理业务逻辑,例如将时间量添加到当前时间并转换为日期,因此使用起来很方便 class。
Date date1 = Date.from(Instant.now().plus(Duration.parse("PT20.345S")));
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
从现代 java.time class 转换为传统 class.
Date date1 = Date.from(otherMoment);
System.out.println(date1);
运行刚才在Europe/Copenhagen时区我得到:
Sat Jun 30 21:34:47 CEST 2018
如果我使用您的其他示例持续时间字符串 P2DT3H4M
,我得到:
Tue Jul 03 00:38:26 CEST 2018
或者如果你喜欢单线:
Date date1 = Date.from(Instant.now().plus(Duration.parse("PT20.345S")));
java.util.Date
class 早就过时了,所以理想情况下你不应该想要一个。如果您无论如何都需要一个,通常是您现在无法更改或不想更改的遗留 API,那么在使用 java.time
执行尽可能多的逻辑时,您的想法是正确的,现代 Java 日期和时间 API,最后只转换为 Date
。 Date
在现代世界的近亲是 Instant
,Instant
和 Date
之间存在直接转换,这就是我使用这个 class 的原因。 Instant
独立于区域偏移量和时区也很可爱。