Преобразование типа данных timestamp в unix timestamp Oracle

У меня есть тип данных timestamp в базе данных с форматом 24-JuL-11 10.45.00.000000000 AM и хочу, чтобы он был преобразован в метку времени unix, как я могу его получить?

7 ответов


этот вопрос в значительной степени обратный преобразование Unixtime в Datetime SQL (Oracle)

как говорит Джастин Кейв:

нет встроенных функций. Но это относительно легко написать один. Так как временная метка Unix-количество секунд с 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 года число долей секунд не имеет значения. Однако вы все равно можете вызвать его с типом данных timestamp...

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 час.


Я понимаю, что ответ уже принят, но я думаю, что следует пояснить, что функция в этом ответе не учитывает смещение часового пояса прошедшей даты. Правильная метка времени 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_time и unix_time_to_date, доступно по адресу http://jrfom.com/2012/02/10/oracle-and-unix-timestamps-revisited/. Я не могу поверить, что Oracle прошла весь путь до 11g без их реализации.


дата:

   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;

Я использую следующий метод, который немного отличается от других ответов в том, что он использует 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;

вот, что я придумал:

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;

чистки рядов


SELECT (SYSDATE - TO_DATE('01-01-1970 00:00:00', 'DD-MM-YYYY HH24:MI:SS')) * 24 * 60 * 60 * 1000 FROM DUAL

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