我知道将Unix时间戳(以毫秒为单位)转换为SQL时间戳我可以使用
SELECT TO_DATE('1970-01-01','YYYY-MM-DD HH24:MI:SS') +
(:timestamp / (1000*60*60*24)) FROM DUAL;
但是我需要一个时间戳,所以我尝试了
SELECT TO_TIMESTAMP('1970-01-01 00:00:00','YYYY-MM-DD HH24:MI:SSFF3') +
(:timestamp) from DUAL
这给了我错误:
错误:ORA-01841 :(完整)年份必须介于-4713和+9999之间,而不是0
似乎在时间戳中添加1总是将其转换为一天。
如何才能获得真正的时间戳?
答案 0 :(得分:5)
如果您向timestamp
添加interval
,则会收到timestamp
(请参阅date/interval arithmetics)。
作为Benoit noticed,当超过大约2.1e9时,你不能指定一个秒的间隔:
SQL> SELECT numtodsinterval(2.2e9, 'SECOND'),
2 numtodsinterval(2.3e9, 'SECOND')
3 FROM dual;
NUMTODSINTERVAL(2.2E9,'SECOND' NUMTODSINTERVAL(2.3E9,'SECOND'
------------------------------- -------------------------------
+000024855 03:14:07.147483647 +000024855 03:14:07.147483647
这就是为什么你应该使用不会失去精确度的分钟。例如,假设:TS
是unix时间戳(即数字):
SQL> variable ts number;
SQL> -- determining unix timestamp with nanosecond precision
SQL> BEGIN
2 :ts := (to_date('2099-01-01 01:02:03', 'yyyy-mm-dd hh24:mi:ss')
3 - date '1970-01-01') * 1000*60*60*24
4 + 123.456789;
5 END;
6 /
ts
---------
4070912523123,456789
SQL> select timestamp '1970-01-01 00:00:00'
2 + numtodsinterval((:ts)/1000/60, 'MINUTE')
3 from dual;
TIMESTAMP'1970-01-0100:00:00'+NUMTODSINTERVAL((:TS)/1000/60,'MINUTE')
---------------------------------------------------------------------------
2099-01-01 01:02:03.123456789
答案 1 :(得分:2)
有两种类型:
间隔是减去时间戳时得到的,将时间戳加在一起是没有意义的。
如果你需要一个毫秒间隔,我会建议使用第二个间隔并将其除以1000:
我可以建议:
SELECT timestamp'1970-01-01 00:00:00' + (interval '1888' second(9) / 1000)
FROM dual
这里的问题是你不能在相同的时间戳文字中使用超过9位的数字。
如果您需要广告时间为2,061,464,797,255毫秒,我可以建议:
SELECT TIMESTAMP'1970-01-01 00:00:00'
+ INTERVAL '2' SECOND(9) * 1000000000
+ INTERVAL '061464797' SECOND(9)
+ INTERVAL '255' SECOND(3) / 1000
FROM dual
你得到2035-04-29 13:06:37.255000000
它似乎受2038错误的影响:TIMESTAMP'1970-01-01 00:00:00'+ 30亿秒不起作用,而它的工作量为20亿。
答案 2 :(得分:0)
使用
SELECT TIMESTAMP '1970-01-01 00:00:00.1234' + INTERVAL '1 00:00:00' DAY TO SECOND
AS ts
FROM dual;
答案 3 :(得分:0)
我已经发布了here一些方法,可将纳秒转换为时间戳,并将时间戳转换为纳秒。这些方法不受时区的影响,并且具有纳秒级的精度。
您只需要将其调整为使用毫秒而不是纳秒。
SELECT TIMESTAMP '1970-01-01 00:00:00 UTC' + numtodsinterval(
1598434427263 --Replace line with desired milliseconds
/ 1000, 'SECOND') AS TIMESTAMP FROM dual;
TIMESTAMP
26/08/20 09:33:47,263000000 UTC