Java ZonedDateTime到即时转换
我计划按照以下逻辑将ZonedDateTime转换为即时。
说,我在PST时区,目前的时间是11A.M. 如果我现在转换(截至2018年3月4日没有夏令时),toInstant将是7P.M.
对于同样的上午11点,toInstant将在2018年4月4日下午6点返回,因为将观察到夏令时。
所以,下面的代码正确返回。
ZonedDateTime dateTime = ZonedDateTime.now(); --->>> March 04th 2018 at 11 AM PST dateTime.plusMonths(1).toInstant(); -->> returns April 04th 2018 at 6 PM PST as daylight saving will be observed
但,
如果我转换为Instant然后再添加一个月,结果将会有所不同。
Instant dateTime = ZonedDateTime.now().toInstant(); --->>> March 04th 2018 at 7 PM UTC dateTime.plus(1,ChronoUnit.MONTHS).toInstant(); -->> returns April 04th 2018 at 7 PM UTC ( but the actual time should be 6 PM UTC ).
这没关系,因为我们已经转换为UTC,它只是从那里添加。
因此,要包括夏令时,我需要添加几天或几个月或几年……到ZonedDateTime然后转换为Instant。
ZonedDateTime dateTime = ZonedDateTime.now(); ---> March 04th 2018 at 11A.M dateTime.plusDays(10).toInstant(); ---> March 14th 2018 at 6P.M dateTime.plusMonths(1).toInstant(); ---> April 04th 2018 at 6P.M
上面的代码按预期工作。 但下面的一个不是返回6 P.M,但它返回7P.M.
dateTime.plusSeconds(org.joda.time.Period.days(1).multipliedBy(10).toStandardSeconds().getSeconds()) .toInstant()) --> ---> March 14th 2018 at 7P.M
不确定,这有什么问题,以及如何使它工作几秒钟。
原因可以在ZonedDateTime
类的文档中找到。 对于方法plusDays
我们在方法文档中看到了这一点:
这在当地时间线上运行,增加了当地日期时间。 然后使用区域ID将其转换回ZonedDateTime以获取偏移量。
当转换回ZonedDateTime时,如果本地日期时间处于重叠状态,则如果可能,将保留偏移量,否则将使用较早的偏移量。 如果在间隙中,则本地日期时间将根据间隙的长度向前调整。
但是,在plusSeconds
方法的文档中,我们看到:
这在即时时间线上操作,使得增加一秒将始终是一秒之后的持续时间。 这可能导致本地日期时间改变不超过一秒的量。 请注意,这与日,月和年使用的方法不同。
因此,这两种方法的设计行为不同,在选择使用哪种方法以满足您的目的时需要考虑这一点。
据我了解您的要求,您可以在几分钟或几小时内添加时间
long minutesToAdd = Duration.ofDays(10).toMinutes();
我正在使用java.time,因为我没有Joda-Time的经验。 如果你愿意,也许你可以将我的想法翻译成Joda-Time。
我进一步了解,添加上述分钟的结果不应该是分钟后的分钟数。 相反,它应该与添加10天相同。 因此,如果是在加利福尼亚州的晚上9点,那么10天后你想在加利福尼亚州的晚上9点。 我建议您在添加分钟或小时之前转换为LocalDateTime
,然后转换回ZonedDateTime
。
ZonedDateTime now = ZonedDateTime.now(ZoneId.of("America/Los_Angeles")); System.out.println(now); System.out.println(now.toInstant()); Instant inTenDays = now.toLocalDateTime() .plusMinutes(minutesToAdd) .atZone(now.getZone()) .toInstant(); System.out.println(inTenDays);
这只是印刷
2018-03-04T21:16:19.187690-08:00[America/Los_Angeles] 2018-03-05T05:16:19.187690Z 2018-03-15T04:16:19.187690Z
由于夏令时(DST)于3月15日(今年3月11日起)生效,因此您不会在UTC中获得相同的小时,而是在您的时区中获得相同的小时。