タイムゾーン付きのタイムスタンプをUTCに変換し、そこからエポックを差し引くことができます。
select timestamp '2018-10-19 09:12:47.0 AMERICA/DENVER'
- timestamp '1970-01-01 00:00:00.0 UTC' as diff
from dual;
これにより、間隔データ型が得られます:
DIFF
----------------------
+17823 15:12:47.000000
次に、そこから要素を抽出し、各要素に適切な係数を掛けてミリ秒に変換します(つまり、日数の場合、60 * 60 * 24 * 1000)。次に、それらを一緒に追加します:
select extract(day from diff) * 86400000
+ extract(hour from diff) * 3600000
+ extract(minute from diff) * 60000
+ extract(second from diff) * 1000 as unixtime
from (
select timestamp '2018-10-19 09:12:47.0 AMERICA/DENVER'
- timestamp '1970-01-01 00:00:00.0 UTC' as diff
from dual
);
UNIXTIME
--------------------
1539961967000
開始タイムスタンプにミリ秒がある場合、これもミリ秒を保持します(これは、それらを保持しながら「Unix」時間から変換します):
select (timestamp '1970-01-01 00:00:00.0 UTC' + (1539961967567 * interval '0.001' second))
at time zone 'America/Denver' as denver_time
from dual;
DENVER_TIME
--------------------------------------------
2018-10-19 09:12:47.567000000 AMERICA/DENVER
その後、元に戻すには:
select extract(day from diff) * 86400000
+ extract(hour from diff) * 3600000
+ extract(minute from diff) * 60000
+ extract(second from diff) * 1000 as unixtime
from (
select timestamp '2018-10-19 09:12:47.567 AMERICA/DENVER'
- timestamp '1970-01-01 00:00:00.0 UTC' as diff
from dual
);
UNIXTIME
--------------------
1539961967567
開始タイムスタンプの精度がそれよりも高い場合は、整数以外の結果にならないように、切り捨て(または丸め/床/天井/キャスト)する必要があります。このバージョンは、抽出されたミリ秒の部分を切り捨てるだけです:
select diff,
extract(day from diff) * 86400000
+ extract(hour from diff) * 3600000
+ extract(minute from diff) * 60000
+ trunc(extract(second from diff) * 1000) as unixtime
from (
select timestamp '2018-10-19 09:12:47.123456789 AMERICA/DENVER'
- timestamp '1970-01-01 00:00:00.0 UTC' as diff
from dual
);
DIFF UNIXTIME
------------------------- --------------------
+17823 15:12:47.123456789 1539961967123
その切り捨て(または同等のもの)がないと、1539961967123.456789
になります。 。
うるう秒の不一致を忘れていました。それを処理する必要がある/処理したい場合は、この回答を参照してください 。