oracle转换unix epoch时间到目前为止

时间:2016-05-18 16:21:03

标签: oracle datetime unix date-format epoch

上下文是我们的产品中存在一个现有的应用程序,它生成EPOCH号并将其发送到现有的oracle程序&反之亦然。它使用类似这样的程序在该程序中工作

SELECT UTC_TO_DATE (1463533832) FROM DUAL
SELECT date_to_utc(creation_date) FROM mytable

当我尝试这些查询时,它对我和Oracle 10g服务器(以及oracle sql developer 4.x,如果这很重要)也有效。

在现有程序中,要求是将值保存为日期本身(时间组件无关紧要),但是在新要求中我必须将unix EPOCH值转换为datetime(在小时/分钟/秒级别,或更好)在oracle查询中以特定格式,如dd-MMM-yyyy hh:mm:ss)。奇怪的是,我无法找到有关Google的UTC_TO_DATE和DATE_TO_UTC函数的任何文档。我已经查看了有关stackoverflow的所有不同问题,但大多数都是特定于编程语言,如php,java等。

底线,如何在Oracle查询中使用这些函数(或任何其他函数)将EPOCH转换为该时间级别?另外,我所指的那些功能可能是自定义的或特定的,因为我没有看到任何文档或对此的引用。

6 个答案:

答案 0 :(得分:12)

要从纪元转换为毫秒(假设纪元是1970年1月1日):

select to_date('19700101', 'YYYYMMDD') + ( 1 / 24 / 60 / 60 / 1000) * 1322629200000
from dual;

11/30/2011 5:00:00 AM

将该日期转换回毫秒:

select (to_date('11/30/2011 05:00:00', 'MM/DD/YYYY HH24:MI:SS') - to_date('19700101', 'YYYYMMDD')) * 24 * 60 * 60 * 1000
from dual;

1322629200000

如果是秒而不是毫秒,则省略等式的1000部分:

select to_date('19700101', 'YYYYMMDD') + ( 1 / 24 / 60 / 60 ) * 1322629200
from dual;

select (to_date('11/30/2011 05:00:00', 'MM/DD/YYYY HH24:MI:SS') - to_date('19700101', 'YYYYMMDD')) * 24 * 60 * 60
from dual;

希望有所帮助。

答案 1 :(得分:4)

另一种选择是使用间隔类型:

SELECT TO_TIMESTAMP('1970-01-01 00:00:00.0'
                   ,'YYYY-MM-DD HH24:MI:SS.FF'
       ) + NUMTODSINTERVAL(1493963084212/1000, 'SECOND')
FROM dual;

它有这个优点,毫秒不会被削减。

答案 2 :(得分:1)

我认为有人会对看到这个的Oracle函数版本感兴趣:

CREATE OR REPLACE FUNCTION unix_to_date(unix_sec NUMBER)
RETURN date
IS
ret_date DATE;
BEGIN
    ret_date:=TO_DATE('19700101','YYYYMMDD')+( 1/ 24/ 60/ 60)*unix_sec;
    RETURN ret_date;
END;
/

我有一堆我需要日期的记录,因此我更新了我的表:

update bobfirst set entered=unix_to_date(1500000000+a);

其中a是1到10,000,000之间的数字。

答案 3 :(得分:1)

如果您的时代时间存储为整数..... 并且您希望转换为Oracle日期格式。

步骤1-> 将您的纪元日期(1462086000)添加到标准1970年1月1日。 86400是24小时内的秒数。

*Select TO_DATE('01-jan-1970',   'dd-mon-yyyy') + 1462086000/86400 from dual*  
   **output is 5/1/2016 7:00:00 AM**

第2步->将其转换为CHAR。在应用其他功能之前,需要进行格式化。

  *Select TO_CHAR(TO_DATE('01-jan-1970',   'dd-mon-yyyy') + 1462086000/86400 ,'yyyy-mm-dd hh24:mi:ss') from dual*

   output is  2016-05-01 07:00:00

第3步->现在进入时间戳转换

Select to_timestamp(TO_CHAR(TO_DATE('01-jan-1970',   'dd-mon-yyyy') + 1462086000/86400 ,'yyyy-mm-dd hh24:mi:ss'), 'yyyy-mm-dd hh24:mi:ss') from dual

  output is 5/1/2016 7:00:00.000000000 AM

第4步->现在需要使用UTC的TimeZone

Select from_tz(to_timestamp(TO_CHAR(TO_DATE('01-jan-1970',   'dd-mon-yyyy') + 1462086000/86400 ,'yyyy-mm-dd hh24:mi:ss'), 'yyyy-mm-dd hh24:mi:ss'),'UTC')  from dual

     output is 5/1/2016 7:00:00.000000000 AM +00:00

步骤5->如果您的时区需要PST

 Select from_tz(to_timestamp(TO_CHAR(TO_DATE('01-jan-1970',   'dd-mon-yyyy') + 1462086000/86400 ,'yyyy-mm-dd hh24:mi:ss'), 'yyyy-mm-dd hh24:mi:ss'),'UTC')  at time zone 'America/Los_Angeles' TZ from dual

           output is 5/1/2016 12:00:00.000000000 AM -07:00

第6步->格式化PST时区时间戳。

 Select to_Char(from_tz(to_timestamp(TO_CHAR(TO_DATE('01-jan-1970',   'dd-mon-yyyy') + 1462086000/86400 ,'yyyy-mm-dd hh24:mi:ss'), 'yyyy-mm-dd hh24:mi:ss'),'UTC')  at time zone 'America/Los_Angeles' ,'DD-MON-YYYY HH24:MI:SS') TZ from dual 

          output is  01-MAY-2016 00:00:00

步骤7->最后,如果您的列是日期数据类型

   Add to_DATE to the whole above Select. 

答案 4 :(得分:0)

这里是UTC / GMT和EST;

GMT  select (to_date('1970-01-01 00','yyyy-mm-dd hh24') +
     (1519232926891)/1000/60/60/24) from dual;

EST  select new_time(to_date('1970-01-01 00','yyyy-mm-dd hh24') + 
     (1519232926891)/1000/60/60/24, 'GMT', 'EST') from dual;

答案 5 :(得分:-1)

将时间戳转换为纳秒的更短方法。

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
)) *  1000000000 AS NANOS FROM DUAL;

NANOS
1598434427263027000

一种将纳秒转换为时间戳的方法。

SELECT TIMESTAMP '1970-01-01 00:00:00 UTC' + numtodsinterval(
    1598434427263027000 --Replace line with desired nanoseconds
/ 1000000000, 'SECOND') AS TIMESTAMP FROM dual;

TIMESTAMP
26/08/20 09:33:47,263027000 UTC

如预期的那样,上述方法的结果不受时区的影响。

一种将间隔转换为纳秒的较短方法。

SELECT (EXTRACT(DAY FROM (
    INTERVAL '+18500 09:33:47.263027' DAY(5) TO SECOND --Replace line with desired interval --Maximum value: INTERVAL '+694444 10:39:59.999999999' DAY(6) TO SECOND(9) or up to 3871 year
) * 24 * 60) * 60 + EXTRACT(SECOND FROM (
    INTERVAL '+18500 09:33:47.263027' DAY(5) TO SECOND --Replace line with desired interval
))) * 1000000000 AS NANOS FROM DUAL;

NANOS
1598434427263027000

一种将纳秒转换为间隔的方法。

SELECT numtodsinterval(
    1598434427263027000 --Replace line with desired nanoseconds
/ 1000000000, 'SECOND') AS INTERVAL FROM dual;

INTERVAL
+18500 09:33:47.263027

正如预期的那样,毫厘,微米和纳米被转换和还原,尽管SYSTIMESTAMP没有纳米级的信息。

例如,如果要使用毫秒而不是纳秒,则将1000000000替换为1000。

我尝试了一些发布的方法,但是几乎所有方法都受时区或恢复后数据丢失的影响,所以我决定发布适合我的方法。