【问题标题】:how to get time in millisecond from date field of oracle for the date 01-01-9999如何从 oracle 的日期字段中获取日期为 01-01-9999 的时间(以毫秒为单位)
【发布时间】:2016-07-19 08:00:47
【问题描述】:

我想从 oracle 的日期字段中获取日期“01-01-9999”的毫秒数。

我已经创建了下面的块来实现同样的效果。

set serveroutput on;
declare
    base_point constant timestamp := to_timestamp_tz('01-JAN-1970 00:00:00.000+00:00', 'DD-Mon-RR HH24:MI:SS.FFTZH:TZM') AT TIME ZONE 'UTC';
    now timestamp := to_timestamp_tz('01-01-2099 00:00:00.000+00:00', 'DD-MM-RR HH24:MI:SS.FFTZH:TZM') AT TIME ZONE 'UTC';
    -- now constant timestamp := systimestamp AT TIME ZONE 'UTC' ;
    n number;
begin

  select to_timestamp_tz(to_char(todate,'DD-MM-YY HH24:MI:SS')||'.000+00:00','DD-MM-YY HH24:MI:SS.FFTZH:TZM')
  into now
   from t_table where ACCOUNTID = 'ACC001124211';

 DBMS_OUTPUT.put_line(' now :'||now);

 n := (
                  ((extract(day    from (now-base_point)))*86400)
                + ((extract(hour   from (now-base_point)))*3600)
                + ((extract(minute from (now-base_point)))*60)
                + ((extract(second from (now-base_point))))
           ) * 1000;

           DBMS_OUTPUT.put_line(' n :'||n);
end;
/

但是使用上面的块我得到的值是4070908800000,它等于日期1/1/2099,但我表中的实际日期是01-01-9999

您能否帮助我们使用日期字段获得精确的毫秒数

【问题讨论】:

标签: database oracle oracle11g oracle10g


【解决方案1】:

不需要PL/SQL,你可以用普通的SQL来做。

将日期转换为毫秒,因为01-JAN-1970

SQL> SELECT to_number(DATE '9999-01-01'
  2         - to_date('01-JAN-1970','DD-MON-YYYY')) * (24 * 60 * 60 * 1000) milliseconds
  3  FROM dual;

      MILLISECONDS
------------------
   253370764800000

SQL>

【讨论】:

    【解决方案2】:

    你得到错误值的原因是这个陈述。

    select to_timestamp_tz(to_char(todate,'DD-MM-YY HH24:MI:SS')||'.000+00:00','DD-MM-YY HH24:MI:SS.FFTZH:TZM')
    

    由于您的年份格式元素是 YY,to_char 转换将只有 2 位年份。

    select to_char(date'9999-01-01','DD-MM-YY HH24:MI:SS')||'.000+00:00'    char_date
    from dual
    
    char_date
    ------------
    01-01-99 00:00:00.000+00:00
    

    当您使用 YY 作为格式元素将其转换为时间戳时,返回的年份始终与当前年份具有相同的前 2 位数字,这就是您将 2099 作为年份的原因。

    select to_char(to_timestamp_tz(to_char(date'9999-01-01','DD-MM-YY HH24:MI:SS')||'.000+00:00','DD-MM-YY HH24:MI:SS.FFTZH:TZM'),'yyyy') char_date
    from dual;
    
    char_date
    ------------
    2099
    

    故事的寓意:

    Oracle 建议您使用 4 位数的年份元素 (YYYY) 而不是较短的年份元素,原因如下:

    • 4 位数年份元素消除了歧义。
    • 较短的年份元素可能会影响查询优化,因为年份在查询编译时是未知的,只能在运行时确定。

    【讨论】:

      【解决方案3】:

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

      您只需将其调整为毫秒而不是纳秒。 您需要使用“CAST(DATE_HERE AS TIMESTAMP)”将日期转换为时间戳。

      SELECT (EXTRACT(DAY FROM (
          CAST(SYSDATE AS TIMESTAMP) --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
          CAST(SYSDATE AS TIMESTAMP) --Replace line with desired timestamp
      )) *  1000 AS MILLIS FROM DUAL;
      
      MILLIS
      1598447857000
      

      【讨论】:

        【解决方案4】:

        我的解决方案是双向的::

        迄今为止的毫秒数 select to_date('1970-01-01 00','yyyy-mm-dd hh24') + (1424217600000)/1000/60/60/24 from dual;

        日期到毫秒(类似于 java 中的 date.getTime()) SELECT to_number(to_date('18-02-2015 00','dd-mm-yyyy hh24') - to_date('01-JAN-1970','DD-MON-YYYY')) * (24 * 60 * 60 * 1000) milliseconds FROM dual;

        【讨论】:

          猜你喜欢
          • 2011-01-21
          • 1970-01-01
          • 2022-11-27
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2021-09-13
          相关资源
          最近更新 更多