Puede convertir su marca de tiempo con zona horaria a UTC y luego restar la época de eso:
select timestamp '2018-10-19 09:12:47.0 AMERICA/DENVER'
- timestamp '1970-01-01 00:00:00.0 UTC' as diff
from dual;
lo que le da un tipo de datos de intervalo:
DIFF
----------------------
+17823 15:12:47.000000
Luego puede extraer los elementos de eso y multiplicar cada elemento por un factor apropiado para convertirlo a milisegundos (es decir, para días, 60 * 60 * 24 * 1000); y luego sumarlos:
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
Esto también conserva milisegundos, si la marca de tiempo inicial los tiene (esto se convierte de un tiempo 'Unix' mientras los conserva):
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
luego para volver a convertir:
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
Si su marca de tiempo inicial tiene una precisión mayor que esa, entonces deberá truncar (o redondear/piso/techo/emisión) para evitar tener un resultado no entero; esta versión solo trunca la parte de milisegundos extraída:
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
Sin ese truncamiento (o equivalente), terminaría con 1539961967123.456789
.
Me había olvidado de la discrepancia de los segundos bisiestos; si necesita/quiere manejar eso, vea esta respuesta .