代码之家  ›  专栏  ›  技术社区  ›  user1578872

Java ZoneDateTime到即时转换

  •  4
  • user1578872  · 技术社区  · 7 年前

    我计划按照以下逻辑将ZonedDateTime转换为instant。

    比方说,我在太平洋标准时间时区,当前时间是11A。M、 如果我现在转换(截至2018年3月4日,今天没有夏令时),则toInstant将为7P。M

    同一天上午11点,toInstant将于2018年4月4日下午6点返回,因为将实行夏时制。

    因此,下面的代码返回正确。

    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
    

    但是

    如果我转换为Instant,然后加上一个月,结果会有所不同。

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

    这是可以的,因为我们已经转换为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
    

    上述代码按预期工作。但下面的那个并没有返回6P。M、 但它的回报是7便士。M

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

    不确定,这有什么问题,以及如何让它在秒数内工作。

    2 回复  |  直到 7 年前
        1
  •  3
  •   Bobulous    7 年前

    原因可在的文档中找到 ZonedDateTime 班对于方法 plusDays 我们在方法文档中看到了这一点:

    这在本地时间线上运行,在本地日期时间上添加天数。然后使用分区ID获取偏移量,将其转换回ZoneDateTime。

    当转换回ZonedDateTime时,如果本地日期时间重叠,则如果可能,将保留偏移量,否则将使用较早的偏移量。如果存在间隙,则本地日期时间将根据间隙的长度向前调整。

    但是,在 plusSeconds 方法我们看到:

    这将在即时时间线上运行,因此添加一秒钟将始终是一秒钟之后的持续时间。这可能会导致本地日期时间发生非1秒的变化。请注意,这与日、月和年使用的方法不同。

    因此,这两种方法的行为是不同的,在选择适合您的目的的方法时,您需要考虑这一点。

        2
  •  0
  •   Anonymous    7 年前

    例如,据我所知,您的时间需要增加几分钟或几小时

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

    我正在使用java。时间,因为我还没有获得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的时间不相同,而时区的时间相同。