sql >> Databasteknik >  >> RDS >> Oracle

Konvertera lokal datumtid (med tidszon) till en Unix-tidsstämpel i Oracle

Du kan konvertera din tidsstämpel med tidszon till UTC och sedan subtrahera epoken från det:

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

som ger dig en intervalldatatyp:

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

Du kan sedan extrahera elementen från det och multiplicera varje element med en lämplig faktor för att omvandla det till millisekunder (dvs. för dagar, 60*60*24*1000); och lägg sedan ihop dem:

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<>fiol

Detta bevarar också millisekunder, om starttidsstämpeln har dem (detta konverteras från en "Unix"-tid samtidigt som de bevaras):

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

sedan för att konvertera tillbaka:

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<>fiol

Om din starttidsstämpel har större precision än så måste du trunkera (eller runda/golv/tak/gjutning) för att undvika att få ett resultat som inte är heltal; denna version trunkerar bara den extraherade millisekundersdelen:

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

Utan den trunkeringen (eller motsvarande) skulle du sluta med 1539961967123.456789 .

Jag hade glömt bort skottsekundersavvikelsen; om du behöver/vill hantera det, se det här svaret .



  1. Hur exporterar jag en MySQL db-struktur till en Excel-fil?

  2. Subtraktion mellan två sql-frågor

  3. Varför fungerar inte yttre ordning efter korrekt?

  4. PostgreSQL-mod:Vad är "resjunk"?