Oracle
 sql >> Baza danych >  >> RDS >> Oracle

Konwertuj lokalną datę i godzinę (ze strefą czasową) na uniksowy znacznik czasu w Oracle

Możesz przekonwertować swój znacznik czasu ze strefą czasową na UTC, a następnie odjąć od tego epokę:

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 daje interwałowy typ danych:

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

Następnie możesz wyodrębnić elementy z tego i pomnożyć każdy element przez odpowiedni współczynnik, aby przekonwertować go na milisekundy (tj. dla dni 60*60*24*1000); a następnie dodaj je razem:

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

Zachowuje to również milisekundy, jeśli początkowy znacznik czasu je zawiera (to konwertuje z czasu „Unixa” przy ich zachowaniu):

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

następnie do konwersji z powrotem:

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

Jeśli twój początkowy znacznik czasu ma większą precyzję, będziesz musiał obciąć (lub zaokrąglić/podłoga/sufit/odlać), aby uniknąć wyniku niecałkowitego; ta wersja po prostu obcina wyodrębnioną część 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 tego obcięcia (lub odpowiednika) otrzymasz 1539961967123.456789 .

Zapomniałem o rozbieżności w sekundach przestępnych; jeśli potrzebujesz/chcesz sobie z tym poradzić, zobacz tę odpowiedź .



  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. Odpowiednik \G MySQL w Oracle SQL*Plus

  2. problem ze znalezieniem listy plików w katalogu

  3. Odwróć ciąg słowo po słowie za pomocą SQL

  4. Importowanie danych z pliku csv

  5. Przekazywanie operatorów SQL do zapytania przez parametr iReport