【问题标题】:The difference between 2 Instants in Calendar Days日历日中 2 个瞬间之间的差异
【发布时间】:2018-12-25 13:35:27
【问题描述】:

所以我试图用我的代码获取一个特定的数字。现在我有:

Instant Today = 2018-07-17T13:45:00Z
Instant Expiration1 = 2018-07-18T11:00:00Z
long daysTilExp = Today.until(Expiration, Chronounit.DAYS)

问题在于,因为这不是完全相隔 24 小时,它最终会返回 daysTilExp = 0 但我想要 daysTilExp = 1 我试图让两个 Instant 的实际天数分开,即使我改变了Expiration 的值如下:

Instant Expiration1 = 2018-07-18T06:00:00Z

现在是daysTilExp = 2。我在 StackOverflow 上查看了其他一些答案,但看起来人们并没有使用 Instant,他们也不希望以同样的方式有所不同

【问题讨论】:

  • 你确定你的第二个例子的结果是2吗?
  • @DominikSandjaja 不,我希望结果是 2 它会返回 1 作为真正的答案
  • 请贴出编译的代码。您不能将2018-07-17T13:45:00Z 直接解析为Instant,它甚至不是字符串,它应该如何工作?使用带有小写首字母的 camelCase 作为变量名。 Chronounit 不应该是 ChronoUnit 吗?
  • 请解释从周二下午 1:45 到第二天早上 6 点的时间间隔如何构成两天。这甚至不是一整天。你的意思是写2018-07-19
  • 您需要为此选择一个时区。地球上任何地方的日历日期都不会相同。

标签: java temporal java.time.instant


【解决方案1】:

试试这个:

long daysTilExp = (long) Math.ceil(now.until(goodTo, ChronoUnit.HOURS) / 24.0);

【讨论】:

    【解决方案2】:

    LocalDate 将删除时间部分,LocalDate 对象比较将产生预期的结果:

    LocalDateTime  today = LocalDateTime.parse("2018-07-17T13:45:00");
    LocalDateTime  expiration = LocalDateTime.parse("2018-07-18T11:00:00");
    LocalDate todayDate = today.toLocalDate();
    LocalDate expirationDate = expiration.toLocalDate();
    long days = todayDate.until(expirationDate, ChronoUnit.DAYS);
    System.out.println(days);
    

    【讨论】:

    • 您可以直接将其解析为本地日期,但您让我到了那里,非常感谢。
    • @TOTOROCATBUS 你可以,但只有你想要 UTC 计数才能给你正确的日期。
    • @OleV.V.是的
    • LocalDate 有一个解析方法,但它接受 2 个参数:日期作为字符串和时区。
    • @PavelMolchanov The Java 9 LocalDate documentation 提到了两个 parse 方法,但没有一个需要时区参数。请问你是什么意思?
    【解决方案3】:
        ZoneId zone = ZoneId.of("America/Chicago");
    
        Instant today = Instant.parse("2018-07-18T17:15:00Z");
        Instant expiration1 = Instant.parse("2018-07-19T05:00:00Z");
    
        ZonedDateTime todayInZone = today.atZone(zone);
        ZonedDateTime expirationInZone = expiration1.atZone(zone);
        long daysTilExp = todayInZone.toLocalDate().until(expirationInZone, ChronoUnit.DAYS);
        System.out.format("From %s to %s is %d day/s.%n", 
                          todayInZone, expirationInZone, daysTilExp);
    

    从 2018-07-18T12:15-05:00[America/Chicago] 到 2018-07-19T00:00-05:00[America/Chicago] 为 1 天/秒。

    所以从 7 月 18 日到 19 日是 1 天。如果您希望两者都包含在计数中,只需加 1。

    由于地球上任何地方的日期都不相同,因此不同时区的天数计算方式不同。尝试更改时区并保持相同的时刻:

        ZoneId zone = ZoneId.of("Asia/Tokyo");
    

    这会将输出更改为

    从 2018-07-19T02:15+09:00[Asia/Tokyo] 到 2018-07-19T14:00+09:00[Asia/Tokyo] 为 0 天/秒。

    从输出中可以看出,这是因为现在日本已经是 7 月 19 日,所以它从 7 月 19 日到 19 日计数,结果为 0。

    因此,您需要选择要在哪个时区进行计数。

    【讨论】:

      【解决方案4】:

      最好的方法是使用来自java.time.temporal.ChronoUnitDAYS.between() 方法。但这种方式仅适用于 Java 8+ 版本。示例:

      Date start = new Date();
      Date end = new Date(start.getTime() + 10_000);
      long daysCount = DAYS.between(start.toInstant(), end.toInstance());
      

      【讨论】:

      • 对 Java 8+ 的非常好的建议也适用于 Instants java.time.Instant 之间的 SECONDS(或其他单位)差异!示例: ChronoUnit.SECONDS.between( t0 ,Instant.now());小事:在你的代码中应该写成“end.toInstant()”(不是 toInstance())
      猜你喜欢
      • 2012-04-30
      • 2018-04-04
      • 2016-03-20
      • 2010-09-22
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-09-22
      相关资源
      最近更新 更多