Postgres将日期时差转换为HH:MM:SS

时间:2018-12-28 21:47:03

标签: java sql postgresql timestamp

例如:

startTime-EndTime 

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

2 个答案:

答案 0 :(得分:3)

tl; dr

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

使用类似于SQL标准TIMESTAMP WITH TIME ZONE的数据类型的列和与JDBC 4.2或更高版本兼容的驱动程序(在Java方面进行操作很简单)(以支持现代的 java.time < / em>类)。

OffsetDateTime

按照OffsetDateTime作为JDBC 4.2 spec个对象来检索您的时刻。

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

Duration

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

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

ISO 8601

生成格式为ISO 8601的标准PnYnMnDTnHnMnS字符串,其中P表示开始(可能代表“句点” –不幸的是,日期时间处理中没有标准化的术语),并且T将年-月-日与小时-分钟-秒分开。因此,一个半小时就是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类。如果要同时使用这两个概念,请使用PeriodDuration中的ThreeTen-Extra类,但请三思而后行,因为将这两个概念混合在一起通常是不明智和不切实际的。

我强烈建议您使用问题中所示的时钟符号表示时间跨度。这样做是模棱两可的,容易出错,人们会误解文本,正如我个人所见,这种情况发生在业务场景中。标准格式更加明智。

Duration::to…Part

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

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-Timemaintenance mode项目建议迁移到java.time类。

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

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

在哪里获取java.time类?

ThreeTen-Extra项目使用其他类扩展了java.time。该项目为将来可能在java.time中添加内容提供了一个试验场。您可能会在这里找到一些有用的类,例如IntervalYearWeekYearQuartermore

答案 1 :(得分:1)

这可以使用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