【问题标题】:Calculate end date with java.time.Duration (ISO 8601) as input? [closed]使用 java.time.Duration (ISO 8601) 作为输入计算结束日期? [关闭]
【发布时间】:2019-07-30 03:46:00
【问题描述】:

我已经解析并准备好了持续时间,持续时间是 java.time.Duration 类型,并以此作为输入我试图通过添加 LocalDateTime.now() 和持续时间 (java.time.duration) 来计算结束日期时间。但是没有得到合适的结果

能够看到与 ReadableDuration 类似的内容,但没有太多关于如何使用它的文档。

java.time.Duration duration = java.time.Duration.parse(timeinISOSTD);
Date localDate =  (Date) duration.addTo(java.time.LocalDateTime.now());
String stringDate = localDate.toString();

我需要一个结束日期时间或结束日期对象,这将帮助我确定 SLA 结束日期时间。

【问题讨论】:

  • “没有得到适当的结果”不是一个有用的描述。具体来说,你期待什么,具体来说,你得到了什么? timeinISOSTD的值是多少?
  • 不应该强制转换为Date 失败吗?
  • 还有更多,Date 是什么(java.util 或 java.sql,或...) - 实际上应该不可能投射 LocalDateTime(由 addto 返回)到Date - 为什么不LocalDateTime.now().plus(duration) 不需要演员......
  • 不要。利用。 Date 你已经在使用 java.time 包中的类,但你也应该完全放弃 Date。除非你绝对必须——但你没有。
  • 请注意,LocalDateTime 适用于一般的 24 小时工作日,适用于实际时刻。如果您的跟踪实际经过的时间,您应该使用InstantOffsetDateTimeZonedDateTime 而不是LocalDateTime

标签: java date duration


【解决方案1】:

我会假设解析正在工作,也就是说,duration 有一个有效值。声明

(Date) duration.addTo(java.time.LocalDateTime.now());

应该抛出异常。根据addTo的文档

这将返回与输入具有相同可观察类型的时间对象...

它必须返回一个LocalDateTime 而不是Date,也就是说,演员会抛出一个异常(应该已经发布了问题,所以我只能假设这是问题所在)。

简单的解决方案:

LocalDateTime localDate = (LocalDateTime) duration.addTo(java.time.LocalDateTime.now());

或者,甚至更好,也如同一文档所建议的那样

在大多数情况下,颠倒调用模式会更清楚......

即:

LocalDateTime localDate = LocalDateTime.now().plus(duration);

注意:要将其格式化为字符串,请使用 format 方法和 DateTimeFormatter 来获取所需的表示形式,例如localDate.format(DateTimeFormatter.ofPattern("HH:mm:ss"))

【讨论】:

    【解决方案2】:

    tl;博士

    Instant                   // Represent a moment in UTC, with a resolution of nanoseconds.
    .now()                    // Capture the current moment as seen in UTC. Returns an `Instant` object.
    .plus(                    // Add a span-of-time, resulting in a different moment.
        Duration              // Represent a span-of-time unattached to the timeline on the scale of hours-minutes-seconds.
        .parse( "PT3H" )      // Parse a string in standard ISO 8601 format. Returns a `Duration` object.
    )                         // Returns another `Instant` object.
    

    详情

    您似乎不明智地混合了不同类型的数据类型。

    • LocalDateTime 表示没有时区或与 UTC 偏移的日期和时间。所以它不能代表片刻。如果您要实时跟踪实际时刻,请不要使用此类。
    • Datejava.util.Datejava.sql.Date,都是不应该使用的可怕的遗留类。几年前,随着 JSR 310 的采用,它们被现代 java.time 类所取代。具体来说,Instant 替换了第一个,LocalDate 替换了第二个。
    • Duration 表示天的跨度(以 24 小时的时间段表示,不是日历天)、小时、分钟、秒和小数秒。对于以年-月-日表示的时间跨度,请使用Period

    LocalDateTime.now()

    我想不出任何情况下这个电话是正确的做法。如上所述,根据定义,此类不能代表片刻。因此,试图将当前时刻捕捉为LocalDateTime 几乎可以肯定是错误的做法。

    显然你想解析一个代表小时-分钟-秒数的字符串。如果您的输入字符串是标准的ISO 8601 格式,这很容易做到。

    String input = "PT4H30M" ;           // Four-and-a-half hours.
    Duration duration = Duration.parse( input ) ;
    

    那么你显然想要捕捉当前的时刻。

    Instant instant = Instant.now() ;    // Capture the current moment as seen in UTC.
    

    最后,您想将时间跨度添加到当前时刻。

    Instant later = instant.plus( duration ) ;
    

    为这个新的时刻生成标准ISO 8601 格式的字符串。

    String output = later.toString() ;
    

    【讨论】:

      猜你喜欢
      • 2020-02-21
      • 2016-06-16
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-05-14
      • 2013-02-03
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多