データベースに 24-JuL-11 10.45.00.000000000 AM という形式のタイムスタンプ データ型があり、それを UNIX タイムスタンプに変換したいのですが、どうすれば取得できますか?
10 に答える
この質問は、Unixtime を Datetime SQL (Oracle) に変換するのとほとんど逆です。
ジャスティン・ケイブが言うように:
組み込み関数はありません。しかし、それを書くのは比較的簡単です。Unix タイムスタンプは 1970 年 1 月 1 日からの秒数なので
ある日付を別の日付から減算すると、それらの間の日数が得られるため、次のようなことができます。
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 時間の差があります。
回答が既に受け入れられていることは承知していますが、その回答の関数は、渡された日付のタイムゾーンオフセットを考慮していないことを明確にする必要があると思います。適切な 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
あり、 http://jrfom.com/2012/02/10/oracle-and-unix-timestamps-revisited/unix_time_to_date
で入手できます。これらを実装せずに Oracle が 11g にまで到達したとは信じられません。
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;
FWIW
SELECT
to_char(sysdate, 'YYYY/MM/DD HH24:MI:SS') dt,
round((sysdate - to_date('19700101 000000', 'YYYYMMDD HH24MISS'))*86400) as udt
FROM dual;