将毫秒转换为时间戳

rad*_*lan 5 sql oracle timestamp milliseconds unix-timestamp

我知道可以将毫秒级的Unix时间戳转换为我可以使用的SQL时间戳

SELECT TO_DATE('1970-01-01','YYYY-MM-DD HH24:MI:SS') + 
       (:timestamp / (1000*60*60*24)) FROM DUAL;
Run Code Online (Sandbox Code Playgroud)

但是我需要一个时间戳,所以我尝试了

SELECT TO_TIMESTAMP('1970-01-01 00:00:00','YYYY-MM-DD HH24:MI:SSFF3') + 
       (:timestamp) from DUAL
Run Code Online (Sandbox Code Playgroud)

这给了我错误:

错误:ORA-01841 :(完整)年份必须在-4713和+9999之间,并且不能为0

似乎将1加到时间戳总是将其转换为一天。

我该如何做才能获得实时时间戳?

Vin*_*rat 5

如果将timestamp添加interval到,则会得到一个timestamp(请参见日期/间隔算术)。

正如Benoit所注意到的,当它们的间隔大约为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
Run Code Online (Sandbox Code Playgroud)

这就是为什么您应该使用不会损失精度的分钟数的原因。例如,假设: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
Run Code Online (Sandbox Code Playgroud)