2012-08-24 162 views

回答

15

这个问题是相当多的Convert Unixtime to Datetime SQL (Oracle)

逆贾斯汀洞说:

有没有内置的功能。但是编写 就比较容易。由于UNIX时间戳是自1月1日的秒数, 1970年

正如你可以不喜欢他们之间的天数去除彼此结果两个日期:

create or replace function date_to_unix_ts(PDate in date) return number is 

    l_unix_ts number; 

begin 

    l_unix_ts := (PDate - date '1970-01-01') * 60 * 60 * 24; 
    return l_unix_ts; 

end; 

由于其在自1970年以来秒数的秒数并不重要。您仍然可以使用时间戳数据类型,虽然叫它...

SQL> select date_to_unix_ts(systimestamp) from dual; 

DATE_TO_UNIX_TS(SYSTIMESTAMP) 
----------------------------- 
        1345801660 

在回答您的意见,我很抱歉,但我没有看到这种行为:

SQL> with the_dates as (
    2 select to_date('08-mar-12 01:00:00 am', 'dd-mon-yy hh:mi:ss am') as dt 
    3  from dual 
    4  union all 
    5 select to_date('08-mar-12', 'dd-mon-yy') 
    6  from dual) 
    7 select date_to_unix_ts(dt) 
    8 from the_dates 
    9   ; 

DATE_TO_UNIX_TS(DT) 
------------------- 
     1331168400 
     1331164800 

SQL> 

有3,600秒的差距,即1小时。

+0

我传递给PDATE价值来自 $ SQL =选择TO_DATE(TO_CHAR(fld_from_date,'DD-Mon-YY HH:MI:SS AM'),'DD-Mon-YY HH:MI:SS AM')AS date_for_unix_timestamp) 假设TO_CHAR(fld_from_date,'DD- YY HH:MI:SS AM')在上面的查询结果'08 - Mar-12 01:00:00 AM',这个char的to_date covesrion出来只是'08 -Mar-12',什么是HH:MI:SS(01:00:00 AM)没有出现的原因? – deepti

+0

嗨@deepti,没有必要发布另一个答案。您可以随时点击您问题上的修改链接并在此处进行更改。评论也留下了通知。我已经更新了我的答案;缺乏可见性可能只是与您的客户有关? – Ben

+0

学习时间和闰秒我不得不说你的程序化解决方案是正确的,但引用的Unix时间定义并不是:Unix时间不是自1.1.1970以来的秒数,而是“1.1天以来的天数”。 1970年代60 * 60 * 24加上今天午夜以来的秒数! – Falco

10

我意识到一个答案已被接受,但我认为应该明确,该答案中的函数不考虑传入日期的时区偏移量。一个适当的Unix时间戳应在GMT(+0)计算。除非另有说明,Oracle的to_date函数假定传入的日期位于本地时区。夏令时是真实的事实,这个问题更加严重。我来到过这个问题有以下功能:

create or replace 
    function unix_time_from_date 
     (
     in_date in date, 
     in_src_tz in varchar2 default 'America/New_York' 
    ) 
    return integer 
    as 
    ut  integer  := 0; 
    tz  varchar2(8) := ''; 
    tz_date timestamp with time zone; 
    tz_stmt varchar2(255); 
    begin 
    /** 
    * This function is used to convert an Oracle DATE (local timezone) to a Unix timestamp (UTC). 
    * 
    * @author James Sumners 
    * @date 01 February 2012 
    * 
    * @param in_date An Oracle DATE to convert. It is assumed that this date will be in the local timezone. 
    * @param in_src_tz Indicates the time zone of the in_date parameter. 
    * 
    * @return integer 
    */ 

    -- Get the current timezone abbreviation (stupid DST) 
    tz_stmt := 'select systimestamp at time zone ''' || in_src_tz || ''' from dual'; 
    execute immediate tz_stmt into tz_date; 
    select 
     extract(timezone_abbr from tz_date) 
    into tz 
    from dual; 

    -- Get the Unix timestamp 
    select 
     (new_time(in_date, tz, 'GMT') - to_date('01-JAN-1970', 'DD-MM-YYYY')) * (86400) 
    into ut 
    from dual; 

    return ut; 
end unix_time_from_date; 

我有一些伴侣功能,unix_timeunix_time_to_date,可在http://jrfom.com/2012/02/10/oracle-and-unix-timestamps-revisited/。我无法相信甲骨文在没有实现这一点的情况下一直到11g。

1

日期:

FUNCTION date_to_unix (p_date date,in_src_tz in varchar2 default 'Europe/Kiev') return number is 
begin 
    return round((cast((FROM_TZ(CAST(p_date as timestamp), in_src_tz) at time zone 'GMT') as date)-TO_DATE('01.01.1970','dd.mm.yyyy'))*(24*60*60)); 
end; 

的时间戳:

FUNCTION timestamp_to_unix (p_time timestamp,in_src_tz in varchar2 default 'Europe/Kiev') return number is 
    begin 
     return round((cast((FROM_TZ(p_time, in_src_tz) at time zone 'GMT') as date)-TO_DATE('01.01.1970','dd.mm.yyyy'))*(24*60*60)); 
    end; 
0

这就是我想出了:

select substr(extract(day from (n.origstamp - timestamp '1970-01-01 00:00:00')) * 24 * 60 * 60 + 
      extract(hour from (n.origstamp - timestamp '1970-01-01 00:00:00')) * 60 * 60 + 
      extract(minute from (n.origstamp - timestamp '1970-01-01 00:00:00')) * 60 + 
      trunc(extract(second from (n.origstamp - timestamp '1970-01-01 00:00:00')),0),0,15) TimeStamp 
      from tablename; 

FWIW

0
SELECT 
to_char(sysdate, 'YYYY/MM/DD HH24:MI:SS') dt, 
round((sysdate - to_date('19700101 000000', 'YYYYMMDD HH24MISS'))*86400) as udt 
FROM dual; 
+4

总是建议为您的代码添加一些解释,特别是为什么它与其他答案不同,如果已经有很多 – Bowdzone

0

我使用下面的方法,它不同于一点点从其他的答案,因为它使用sessiontimezone()功能正常获取日期

select 
    ( 
     cast((FROM_TZ(CAST(in_date as timestamp), sessiontimezone) at time zone 'GMT') as date) -- in_date cast do GMT 
     - 
     TO_DATE('01.01.1970','dd.mm.yyyy') -- minus unix start date 
    ) 
    * 86400000 -- times miliseconds in day 
    from dual; 
0
SELECT (SYSDATE - TO_DATE('01-01-1970 00:00:00', 'DD-MM-YYYY HH24:MI:SS')) * 24 * 60 * 60 * 1000 FROM DUAL