4

我正在使用以下语法

TIMESTAMPDIFF(2, CHAR(CREATED - TIMESTAMP('1970-01-01 00:00:00'))

whereCREATED是类型TIMESTAMP,数据库是 DB2。目的是将时间戳从纪元转换为毫秒。如果有更好的功能会更有帮助。

示例数据:
返回2011-10-04 13:54:50值是1316613290但实际值应该是1317732890(从http://www.epochconverter.com获得)

要运行的查询

SELECT TIMESTAMPDIFF(2, CHAR(TIMESTAMP('2011-10-04 13:54:50') - TIMESTAMP('1970-01-01 00:00:00'))) FROM  SYSIBM.SYSDUMMY1;
4

3 回答 3

8

这是TIMESTAMPDIFF返回时间戳之间差异的估计值的结果,而不是预期的实际值。

参考资料,第 435 页(假设为 iSeries):

将元素值转换为请求的间隔类型时使用以下假设:

  • 一年有365天。
  • 一年有52周。
  • 一年有12个月。
  • 一个季度有 3 个月。
  • 一个月有30天。
  • 一周有7天。
  • 一天有24小时。
  • 一小时有60分钟。
  • 一分钟有60秒。
  • 一秒有1000000微秒。

实际使用的计算是:

秒 + (分钟 + (小时 + ((天 + (月 * 30) + (年 * 365)) * 24)) * 60) * 60

由于显而易见的原因,这是不准确的。没有帮助。

这似乎是时间戳算术结果返回方式的直接结果。
那是;

SELECT                                                              
TIMESTAMP('1971-03-02 00:00:00') - TIMESTAMP('1970-01-01 00:00:00') 
FROM sysibm/sysdummy1        

返回:

10,201,000,000.000000         

Which can be divided into:
  • 1
  • 02
  • 01
  • 00小时
  • 00分钟
  • 00
  • 000000微秒

这是不精确的期间/持续时间信息。虽然在很多情况下这种类型的数据很有用,但这不是其中之一。

简答:在数据库中无法正确计算出准确答案,实际上也不应该


长答案:

计算是可能的,但相当复杂,绝对不适合数据库内计算。我不打算在这里重现它们(如果你有兴趣,请查看JodaTimeChronology ,特别是各种子类)。你最大的问题是月份的长度并不完全相同。此外,如果您的时间戳不是 UTC,您将遇到重大问题 - 更具体地说,夏令时将对计算造成严重破坏。为什么?因为对于任何国家,偏移量可以随时更改。

也许您可以解释为什么需要毫秒数?希望您正在使用 Java(或能够这样做),并且可以使用java.time. 但如果你在 iSeries 上,它可能是 RPG ......

于 2011-10-06T17:40:01.630 回答
1

根据v9.7 信息中心,TIMESTAMPDIFF 根据一年中的 365 天(大约 25% 的时间不正确)、一个月中的 30 天(不正确的 75% 的时间,尽管平均值)返回估计的时差比那好一点),一天 24 小时(在某些时区一年中的几天不是真的),一小时 60 分钟(万岁,对!),一分钟 60 秒(真的 >99.9 %的时间 - 我们确实得到闰秒)。

所以,不,这不是在 DB2 中获取纪元时间的方法。到目前为止,我已经将时间作为时间戳,并在客户端进行转换。

于 2011-10-06T17:15:28.227 回答
1

正如其他人指出的那样,部分错误是由于 TIMESTAMPDIFF 函数的不准确性而发生的。

另一个错误来源是因为 Epoch 基于 GMT - 所以你必须考虑你当地的时区。

因此,您可以使用以下表达式执行此操作:

(DAYS(timestamp('2011-10-04-13.54.50.000000') - current timezone) - DAYS('1970-01-01-00.00.00.000000')) * 86400 + MIDNIGHT_SECONDS(timestamp('2011-10-04-13.54.50.000000') - current timezone)

您可以编写一个简单的 UDF 来简化它:

create or replace function epoch (in db2ts timestamp)
   returns bigint
   language sql
   deterministic
   no external action
   return (days(db2ts - current timezone) - days('1970-01-01-00.00.00.000000')) * 86400 + midnight_seconds(db2ts - current timezone);

祝你好运,

于 2011-10-07T08:09:58.920 回答