sql >> Databáze >  >> RDS >> Oracle

Převeďte místní datum a čas (s časovým pásmem) na unixové časové razítko v Oracle

Své časové razítko s časovým pásmem můžete převést na UTC a poté od něj odečíst epochu:

select timestamp '2018-10-19 09:12:47.0 AMERICA/DENVER'
  - timestamp '1970-01-01 00:00:00.0 UTC' as diff
from dual;

což vám dává intervalový datový typ:

DIFF                  
----------------------
+17823 15:12:47.000000

Z toho pak můžete extrahovat prvky a vynásobit každý prvek příslušným faktorem, abyste jej převedli na milisekundy (tj. na dny, 60*60*24*1000); a poté je sečtěte:

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

Tím se zachovají i milisekundy, pokud je má počáteční časové razítko (převádí se z 'Unixového' času a zachovává je):

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

pak převést zpět:

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

Pokud má vaše počáteční časové razítko větší přesnost, pak budete muset zkrátit (nebo kulaté/podlahové/stropní/obsazené), abyste se vyhnuli neceločíselnému výsledku; tato verze pouze zkrátí extrahovanou část milisekund:

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

Bez tohoto zkrácení (nebo ekvivalentu) byste skončili s 1539961967123.456789 .

Zapomněl jsem na rozdíl v přestupných sekundách; pokud to potřebujete/chcete zvládnout, viz tuto odpověď .



  1. Jaký je nejrychlejší způsob vložení dat do tabulky Oracle?

  2. Filtrovat podle COUNT(*)?

  3. T-SQL Jak dynamicky vytvářet tabulky v uložených procedurách?

  4. chyba připojení k databázi spojená s kódováním