【问题标题】:How to get millis of timestamp since 1970 UTC in Oracle SQL? [duplicate]如何在 Oracle SQL 中获取自 1970 UTC 以来的毫秒时间戳? [复制]
【发布时间】:2015-10-17 14:06:31
【问题描述】:

我有一张表,其中一列的类型为TIMESTAMP(6)

如何获取自 1970 UTC 以来列数据的毫秒数?

【问题讨论】:

标签: sql oracle


【解决方案1】:

试试这个

select (cast(your_column as date) - date '1970-01-01')*24*60*60 from your_table;

【讨论】:

  • 这是自 1970 年以来的秒数,而不是毫秒。对于您想要的毫秒数:SELECT (CAST(SYSTIMESTAMP AS DATE) - DATE '1970-01-01')*24*60*60*1000 + MOD( EXTRACT( SECOND FROM SYSTIMESTAMP ), 1 ) * 1000 FROM DUAL
  • 将之前的评论重新格式化为:SELECT ((TRUNC(CURRENT_DATE, 'MI') - DATE '1970-01-01') * 86400 + EXTRACT(SECOND FROM CURRENT_TIMESTAMP)) * 1000 FROM DUAL
【解决方案2】:
select 
  MY_TS as orig
  , extract(day from (MY_TS-to_timestamp_tz('01-01-70 0', 'DD-MM-RR TZH')))*1000*60*60*24
  + extract(hour from (MY_TS-to_timestamp_tz('01-01-70 0', 'DD-MM-RR TZH')))*1000*60*60
  + extract(minute from (MY_TS-to_timestamp_tz('01-01-70 0', 'DD-MM-RR TZH')))*1000*60
  + extract(second from (MY_TS-to_timestamp_tz('01-01-70 0', 'DD-MM-RR TZH')))*1000
    as millis
from MY_TABLE;

【讨论】:

  • 请注意,如果您的时间戳与客户端的时区不同,您可能需要指定它是什么。为此,将MY_TS 替换为FROM_TZ(MY_TS, 'PST')
【解决方案3】:

考虑闰秒:

SQL Fiddle

Oracle 11g R2 架构设置

CREATE FUNCTION milliseconds_Since_1970(
  datetime TIMESTAMP
) RETURN NUMBER DETERMINISTIC
AS
  diff   INTERVAL DAY(9) TO SECOND(9) := datetime - TIMESTAMP '1970-01-01 00:00:00';
  millis NUMBER(38,0) := EXTRACT( DAY    FROM diff ) * 24 * 60 * 60 * 1000
                       + EXTRACT( HOUR   FROM diff )      * 60 * 60 * 1000
                       + EXTRACT( MINUTE FROM diff )           * 60 * 1000
                       + EXTRACT( SECOND FROM diff )                * 1000;
  leap_seconds SYS.ODCIDATELIST := SYS.ODCIDATELIST(
    DATE '1972-07-01',
    DATE '1973-01-01',
    DATE '1974-01-01',
    DATE '1975-01-01',
    DATE '1976-01-01',
    DATE '1977-01-01',
    DATE '1978-01-01',
    DATE '1979-01-01',
    DATE '1980-01-01',
    DATE '1981-07-01',
    DATE '1982-07-01',
    DATE '1983-07-01',
    DATE '1985-07-01',
    DATE '1988-01-01',
    DATE '1990-01-01',
    DATE '1991-01-01',
    DATE '1992-07-01',
    DATE '1993-07-01',
    DATE '1994-07-01',
    DATE '1996-01-01',
    DATE '1997-07-01',
    DATE '1999-01-01',
    DATE '2006-01-01',
    DATE '2009-01-01',
    DATE '2012-07-01',
    DATE '2015-07-01'
  );
BEGIN
  FOR i IN 1 .. leap_seconds.COUNT LOOP
    IF datetime < leap_seconds(i) THEN
      RETURN millis;
    END IF;
    millis := millis + 1000;
  END LOOP;
  RETURN millis;
END;
//

查询 1

SELECT milliseconds_Since_1970( TIMESTAMP '1970-01-01 00:00:00' ) AS "MS 1970-01-01 00:00:00",
       milliseconds_Since_1970( TIMESTAMP '1970-01-01 00:01:00' ) AS "MS 1970-01-01 00:01:00",
       milliseconds_Since_1970( TIMESTAMP '1972-06-30 23:59:59' ) AS "MS 1972-06-30 23:59:59",
       milliseconds_Since_1970( TIMESTAMP '1972-07-01 00:00:00' ) AS "MS 1972-07-01 00:00:00"
FROM   DUAL

Results

| MS 1970-01-01 00:00:00 | MS 1970-01-01 00:01:00 | MS 1972-06-30 23:59:59 | MS 1972-07-01 00:00:00 |
|------------------------|------------------------|------------------------|------------------------|
|                      0 |                  60000 |            78796799000 |            78796801000 |

【讨论】:

  • 感谢您的回复。我不得不说,在与 Oracle 合作了很短时间之后——这是我见过的最不友好的数据库之一。真正令人困惑的是,这不包含在系统实用程序功能中。
【解决方案4】:

我已经发布了here 一些将时间戳转换为纳秒以及将纳秒转换为时间戳的方法。这些方法不受时区影响,精度为纳秒级。

您只需将其调整为毫秒而不是纳秒。

SELECT (EXTRACT(DAY FROM (
    SYSTIMESTAMP --Replace line with desired timestamp --Maximum value: TIMESTAMP '3871-04-29 10:39:59.999999999 UTC'
- TIMESTAMP '1970-01-01 00:00:00 UTC') * 24 * 60) * 60 + EXTRACT(SECOND FROM
    SYSTIMESTAMP --Replace line with desired timestamp
)) *  1000 AS MILLIS FROM DUAL;

MILLIS
1598434427263.027

【讨论】:

    猜你喜欢
    • 2013-11-02
    • 2010-12-29
    • 1970-01-01
    • 1970-01-01
    • 2012-07-06
    • 2018-04-06
    • 1970-01-01
    • 1970-01-01
    • 2012-03-23
    相关资源
    最近更新 更多