gpt4 book ai didi

java-8 - 如何以毫秒为单位返回 LocalDate.now()?

转载 作者:行者123 更新时间:2023-12-03 23:29:22 25 4
gpt4 key购买 nike

我现在创建日期:

ZoneId gmt = ZoneId.of("GMT");
LocalDateTime localDateTime = LocalDateTime.now();
LocalDate localDateNow = localDateTime.toLocalDate();

然后我想以毫秒为单位返回这个日期:
localDateNow.atStartOfDay(gmt) - 22.08.2017
localDateNow.atStartOfDay(gmt).toEpochSecond(); - 1503360000 (18.01.70)

如何返回 LocalDate.now()以毫秒为单位?

最佳答案

调用toInstant().toEpochMilli() ,正如 @JB Nizet's comment 所建议的那样, 是正确的答案,但是您必须注意有关使用本地日期的一些棘手的细节。

但在此之前,还有一些其他的小细节:

  • 而不是 ZoneId.of("GMT")您可以使用内置常量 ZoneOffset.UTC .它们是等价的,但如果 API 已经提供了完全相同的对象,则无需创建额外的冗余对象。
  • 而不是调用 LocalDateTime.now()然后 .toLocalDate() ,您可以调用LocalDate.now()直接 - 它们是等价的。


  • 现在是棘手的细节:当您调用 now()方法(对于 LocalDateTimeLocalDate ),它使用 JVM 的默认时区来获取当前日期的值,并且该值可能会根据 JVM 中配置的时区而有所不同。

    在我使用的 JVM 中,默认时区是 America/Sao_Paulo ,这里的本地时间是 上午 09:37 .所以 LocalDate.now()返回 2017-08-22 (2017 年 8 月 22 日 )。

    但是如果我将默认时区更改为 Pacific/Kiritimati , 它返回 2017-08-23 .那是因为在Kiritimati,现在已经是八月了 23日 2017 年(在我写这篇文章的那一刻,那里的本地时间是 02:37 AM )。

    因此,如果我在默认时区为 Pacific/Kiritimati 时运行此代码:
    LocalDate dtNow = LocalDate.now(); // 2017-08-23
    System.out.println(dtNow.atStartOfDay(ZoneOffset.UTC).toInstant().toEpochMilli());

    输出是:

    1503446400000



    相当于 8 月 23日 UTC 时间 2017 年午夜。

    如果我在默认时区为 America/Sao_Paulo 时运行相同的代码,结果将是:

    1503360000000



    相当于 8 月 22日 UTC 时间 2017 年午夜。

    使用 now()使您的代码依赖于 JVM 的默认时区。而这个配置 can be changed without notice, even at runtime ,使您的代码在发生此类更改时返回不同的结果。

    而且您不需要这样的极端情况(例如有人将 JVM 错误配置为“非常远”的时区)。例如,在我的情况下,在 America/Sao_Paulo时区,如果我在 运行代码晚上 11 点 , LocalDate将返回 8 月 22日 ,但 UTC 中的当前日期已经是 8 月 23日 .这是因为圣保罗的晚上 11 点与 的凌晨 2 点相同。第二天世界标准时间:
    // August 22th 2017, at 11 PM in Sao Paulo
    ZonedDateTime z = ZonedDateTime.of(2017, 8, 22, 23, 0, 0, 0, ZoneId.of("America/Sao_Paulo"));
    System.out.println(z); // 2017-08-22T23:00-03:00[America/Sao_Paulo]
    System.out.println(z.toInstant()); // 2017-08-23T02:00:00Z (in UTC is already August 23th)

    所以使用 LocalDate.now()不是 保证我将永远拥有 UTC 当前日期 .

    如果你想要 UTC 当前日期 (不考虑 JVM 默认时区)并将时间设置为午夜,最好使用 ZonedDateTime :
    // current date in UTC, no matter what the JVM default timezone is 
    ZonedDateTime zdtNow = ZonedDateTime.now(ZoneOffset.UTC);
    // set time to midnight and get the epochMilli
    System.out.println(zdtNow.with(LocalTime.MIDNIGHT).toInstant().toEpochMilli());

    输出是:

    1503360000000



    相当于 8 月 22日 UTC 时间 2017 年午夜。

    另一种选择是将时区传递给 LocalDate.now ,因此它可以获得指定区域上当前日期的正确值:
    // current date in UTC, no matter what the JVM default timezone is 
    LocalDate dtNowUtc = LocalDate.now(ZoneOffset.UTC);
    // set time to midnight and get the epochMilli
    System.out.println(dtNow.atStartOfDay(ZoneOffset.UTC).toInstant().toEpochMilli());

    关于java-8 - 如何以毫秒为单位返回 LocalDate.now()?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/45813379/

    25 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com