PostgreSQL
 sql >> Database >  >> RDS >> PostgreSQL

Mantieni il fuso orario nel tipo timestamptz di PostgreSQL

Come hai già capito tu stesso, il fuso orario non viene salvato affatto con i tipi di data/ora di Postgres, nemmeno con timestamptz . Il suo ruolo è rispettivamente solo un modificatore di input o un decoratore di output. Viene salvato solo il valore (il punto nel tempo). Ampi dettagli in questa risposta correlata:

  • Ignora del tutto i fusi orari in Rails e PostgreSQL

Pertanto, se vuoi preservare quella parte della stringa di input, devi estrarla dalla stringa e salvarla tu stesso. Userei una tabella come:

CREATE TABLE tstz
 ...
 , ts timestamp    -- without time zone
 , tz text
)

tz , essendo text , può contenere un offset numerico nonché un'abbreviazione del fuso orario o un nome del fuso orario .

La difficoltà è estrarre la parte del fuso orario secondo tutte le varie regole seguite dal parser e in un modo che non si rompa facilmente. Invece di elaborare la tua procedura, fai fare il lavoro al parser . Considera questa demo:

WITH ts_literals (tstz) AS (
   VALUES ('2013-11-28 23:09:11.761166+03'::text)
         ,('2013-11-28 23:09:11.761166 CET')
         ,('2013-11-28 23:09:11.761166 America/New_York')
   )
SELECT tstz
      ,tstz::timestamp AS ts
      ,right(tstz, -1 * length(tstz::timestamp::text)) AS tz
FROM   ts_literals;

SQL Fiddle.

Funziona con o senza T tra data e ora. La logica chiave è qui:

right(tstz, -1 * length(tstz::timestamp::text)) AS tz

Prendi ciò che resta di una stringa timestamp dopo aver tagliato la lunghezza di ciò che il parser ha identificato come componente data/ora. Questo si basa sull'input, come hai affermato:

stringhe ISO8601 convalidate