Вы можете преобразовать свою временную метку с часовым поясом в 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
db <> fiddle
Это также сохраняет миллисекунды, если они есть у начальной временной метки (это конвертируется из 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
db <> fiddle
Если ваша начальная временная метка имеетчем выше точность, то вам нужно будет усечь (или округлить / пол / потолок / приведение), чтобы избежать нецелого результата;эта версия просто обрезает извлеченную часть в миллисекундах:
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
.
Я бы забыл орасхождение в високосных секундах;если вам нужно / хотите справиться с этим, см. этот ответ .