我正在使用以下语法
TIMESTAMPDIFF(2, CHAR(CREATED - TIMESTAMP('1970-01-01 00:00:00'))
其中CREATED
的类型为TIMESTAMP
,数据库为DB2。内涵是将时间戳从epoch转换为millis。如果有更好的功能会更有帮助。
样本数据:
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;
答案 0 :(得分:7)
这是因为TIMESTAMPDIFF
按预期返回时间戳之间差异的估计,而不是实际值。
来自reference,第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
微秒不精确期间/持续时间信息。虽然在很多情况下此类数据 有用,但这不是其中之一。
简短回答:确切的答案无法在数据库中正确计算,实际上不应。
答案很长:
计算可能,但相当复杂,绝对不适合数据库内计算。我不打算在这里重现它们(如果你感兴趣,请查看JodaTime,特别是各种Chronology
子类)。你最大的问题是几个月的长度不一样。此外,如果您的时间戳不是UTC,那么您将遇到重大问题 - 更具体地说,夏令时会对计算造成严重破坏。为什么?因为任何国家的抵消都可以随时改变。
也许你可以解释为什么你需要毫秒数?希望您使用的是Java(或能够使用Java),并且可以使用java.time
。但如果你在iSeries上,它可能是RPG ......
答案 1 :(得分:1)
根据the v9.7 info center,TIMESTAMPDIFF根据一年365天(不是真实的~25%的时间),一个月内30天(不是30天)返回估计的时差真的有75%的时间,虽然平均有点好一点),一天24小时(一些时区的一年中的几天都不是真的),一小时60分钟(万岁,一个正确!),以及一分钟60秒(真正> 99.9%的时间 - 我们确实获得闰秒)。
所以,不,这不是在DB2中获取纪元时间的方法。到目前为止,我已经把时间作为时间戳,并在客户端转换它。
答案 2 :(得分: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);
祝你好运,