【问题标题】:Postgres convert date time difference into HH:MM:SSPostgres 将日期时间差转换为 HH:MM:SS
【发布时间】:2019-05-26 15:17:53
【问题描述】:

例如:

startTime-EndTime 

Diff 是 0 年 0 个月 5 天 20 小时 6 分 30 秒。我想将其转换为 HH:MM:SS 格式:120:06:30。

【问题讨论】:

    标签: java sql postgresql date timestamp


    【解决方案1】:

    tl;博士

    Duration                                                 // Represent a span-of-time in terms of total number of whole seconds plus a fractional second in nanos.
    .between(                                                // Calculate elapsed time.
        myResultSet.getObject( … , OffsetDateTime.class ) ,  // Start
        myResultSet.getObject( … , OffsetDateTime.class ) ,  // Stop
    )                                                        // Returns a `Duration` object.
    .toString()                                              // Generate text in standard ISO 8601 format of `PnYnMnDTnHnMnS`. 
    

    java.time

    在 Java 端使用类似于 SQL 标准 TIMESTAMP WITH TIME ZONE 的数据类型的列和符合 JDBC 4.2 或更高版本的驱动程序(为了支持现代 java.time 类)。

    OffsetDateTime

    根据JDBC 4.2 spec,将您的时刻作为OffsetDateTime 对象检索。

    OffsetDateTime start = myResultSet.getObject( … , OffsetDateTime.class ) ;
    OffsetDateTime stop = myResultSet.getObject( … , OffsetDateTime.class ) ;
    

    Duration

    将经过的时间计算为Duration 对象。

    Duration d = Duration.between( start , stop ) ;
    

    ISO 8601

    生成格式为PnYnMnDTnHnMnS 的标准ISO 8601 字符串,其中P 标记开始(可能代表“句点”——不幸的是,在日期时间处理中没有标准化术语),T 分隔年份-months-days 从小时-分钟-秒。所以一个半小时将是PT1H30M。您的5 days 20hours 6minutes 30 seconds 示例为P5DT20H6M30S

    java.time 类默认使用 ISO 8601 格式。因此,您只需调用toString 即可生成文本。无需指定格式模式。

    String output = d.toString() ;
    

    P5DT20H6M30S

    要解析,请调用parse

    Duration d = Duration.parse( "P5DT20H6M30S" ) ;
    

    请注意,Duration 将天数计为 24 小时时间段,而不考虑日历。如果您想要基于日历的日期,请使用Period 类。如果您想同时使用这两个概念,请使用 ThreeTen-Extra 中的 PeriodDuration 类,但要三思而后行,因为混合这两个概念通常是不明智和不切实际的。

    我强烈建议您不要使用您的问题中所示的时钟符号表示时间跨度。这样做是模棱两可的,容易出错,因为人们会误解文本,正如我个人在业务场景中看到的那样。标准格式要明智得多。

    Duration::to…Part

    但如果您坚持时钟格式,请通过调用 Duration 上的 to…Part 方法创建一个字符串。

    String output = d.toDaysPart() + ":" + d.toHoursPart() + ":" + d.toMinutesPart() + ":" + d.toSecondsPart() + "." + d.toNanosPart() ; 
    

    toHourstoHoursPart

    如果希望将所有天数报告为小时,请通过调用 toHours 而不是 toHoursPart 获取整个时间跨度内的总小时数。然后得到分和秒的部分。

    Duration d = Duration.between( start , stop ) ;
    String output = d.toHours() + ":" + d.toMinutesPart() + ":" + d.toSecondsPart() ;
    

    120:06:30


    关于java.time

    java.time 框架内置于 Java 8 及更高版本中。这些类取代了麻烦的旧 legacy 日期时间类,例如 java.util.DateCalendarSimpleDateFormat

    Joda-Time 项目现在位于maintenance mode,建议迁移到java.time 类。

    要了解更多信息,请参阅Oracle Tutorial。并在 Stack Overflow 上搜索许多示例和解释。规格为JSR 310

    您可以直接与您的数据库交换 java.time 对象。使用符合JDBC 4.2 或更高版本的JDBC driver。不需要字符串,不需要java.sql.* 类。

    从哪里获得 java.time 类?

    ThreeTen-Extra 项目通过附加类扩展了 java.time。该项目是未来可能添加到 java.time 的试验场。您可以在这里找到一些有用的类,例如IntervalYearWeekYearQuartermore

    【讨论】:

      【解决方案2】:

      这可以使用 postgresql 来实现。

      要将两个时间戳之间的差异计算为秒数,请使用:

      EXTRACT(EPOCH FROM (startTime - endTime))
      

      然后您使用函数 TO_TIMESTAMP 将此值调整回时间戳,并使用函数 TO_CHAR 将其格式化为时间。

      小时部分很棘手,因为您想显示大于 24 的值(正如您所料,这是 postgres 中允许的最大值):您需要使用一些算术来计算它。

      SELECT CONCAT(
          EXTRACT(EPOCH FROM (startTime - endTime))/60/60,
          ':',
          TO_CHAR(TO_TIMESTAMP(
               EXTRACT(EPOCH FROM (startTime - endTime))
            ), 'MI:SS')
       )
      FROM my_table
      

      【讨论】:

      • 这没有提供问题的答案。要批评或要求作者澄清,请在他们的帖子下方留下评论。 - From Review
      • @NikolaYovchev 我猜我的帖子在你发表评论时被编辑了
      猜你喜欢
      • 2023-03-17
      • 1970-01-01
      • 1970-01-01
      • 2021-04-07
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多