PostgreSQL
 sql >> Base de données >  >> RDS >> PostgreSQL

Conserver le fuseau horaire dans le type d'horodatage PostgreSQL

Comme vous l'avez déjà compris, le fuseau horaire n'est pas enregistré du tout avec les types de date/heure Postgres, pas même avec timestamptz . Son rôle est juste un modificateur d'entrée ou un décorateur de sortie, respectivement. Seule la valeur (le point dans le temps) est enregistrée. De nombreux détails dans cette réponse connexe :

  • Ignorer complètement les fuseaux horaires dans Rails et PostgreSQL

Par conséquent, si vous souhaitez conserver cette partie de la chaîne d'entrée, vous devez l'extraire de la chaîne et l'enregistrer vous-même. J'utiliserais un tableau comme :

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

tz , étant text , peut contenir un décalage numérique ainsi qu'une abréviation de fuseau horaire , ou un nom de fuseau horaire .

La difficulté est d'extraire la partie fuseau horaire selon toutes les différentes règles suivies par l'analyseur et d'une manière qui ne se cassera pas facilement. Au lieu de préparer votre propre procédure, faites le travail à l'analyseur . Considérez cette démo :

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.

Fonctionne avec ou sans T entre la date et l'heure. La logique clé est ici :

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

Prenez ce qui reste d'une chaîne d'horodatage après avoir coupé la longueur de ce que l'analyseur a identifié comme composant date/heure. Cela repose sur l'entrée étant, comme vous l'avez indiqué :

chaînes ISO8601 validées