Java ZonedDateTime to Instant conversion

情到浓时终转凉″ 提交于 2020-01-02 05:14:08

问题


I am planning to convert ZonedDateTime to instant as per the below logic.

Say, I am in PST timeZone and the current time is 11A.M. If I convert now( no daylight saving as of today March 04 2018) and the toInstant will be 7P.M.

For the same 11 A.M, the toInstant will return 6 P.M as of April 04 2018 as daylight saving will be observed.

So, The below code returns correctly.

ZonedDateTime dateTime = ZonedDateTime.now();  --->>> March 04th 2018 at 11 A.M PST
dateTime.plusMonths(1).toInstant(); -->> returns April 04th 2018 at 6 PM PST as daylight saving will be observed

But,

The result will be different if i convert to Instant and then add a month.

Instant dateTime = ZonedDateTime.now().toInstant();  --->>> March 04th 2018 at 7 P.M UTC
dateTime.plus(1,ChronoUnit.MONTHS).toInstant(); -->> returns April 04th 2018 at 7 PM UTC ( but the actual time should be 6 PM UTC ). 

This is ok, as we already converted to UTC and it just adds from there.

Hence, To include the daylight saving time, I need to add days or months or years .... to ZonedDateTime and then convert to 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

The above code works as expected. But the below one is not returning 6P.M, But it returns 7P.M.

dateTime.plusSeconds(org.joda.time.Period.days(1).multipliedBy(10).toStandardSeconds().getSeconds())
         .toInstant())  --> ---> March 14th 2018 at 7P.M

Not sure, what is wrong with this and how to make it work with seconds.


回答1:


The cause is found in the documentation for the ZonedDateTime class. For the method plusDays we see this in the method documentation:

This operates on the local time-line, adding days to the local date-time. This is then converted back to a ZonedDateTime, using the zone ID to obtain the offset.

When converting back to ZonedDateTime, if the local date-time is in an overlap, then the offset will be retained if possible, otherwise the earlier offset will be used. If in a gap, the local date-time will be adjusted forward by the length of the gap.

However, in the documentation for the plusSeconds method we see this:

This operates on the instant time-line, such that adding one second will always be a duration of one second later. This may cause the local date-time to change by an amount other than one second. Note that this is a different approach to that used by days, months and years.

So the two methods are designed to behave differently, and you need to consider this when choosing which method to use to suit your purpose.




回答2:


As I understand your requirement you have a number of minutes or hours to add to your time, for example

    long minutesToAdd = Duration.ofDays(10).toMinutes();

I am using java.time since I haven’t got experience with Joda-Time. Maybe you can translate my idea to Joda-Time if you wish.

As I further understand, the result of adding the above minutes should not be a point in time that number of minutes later. Instead it should work the same as adding 10 days. So if it’s 9 PM in California, you want 9 PM in California 10 days later. I suggest you solve this by converting to LocalDateTime before adding the minutes or hours, and then convert back to ZonedDateTime afterwards.

    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);

This just printed

2018-03-04T21:16:19.187690-08:00[America/Los_Angeles]
2018-03-05T05:16:19.187690Z
2018-03-15T04:16:19.187690Z

Since summer time (DST) is in effect on March 15 (it is from March 11 this year), you don’t get the same hour-of-day in UTC, but instead the same hour-of-day in your time zone.



来源:https://stackoverflow.com/questions/49099735/java-zoneddatetime-to-instant-conversion

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!