sql >> Base de Datos >  >> RDS >> PostgreSQL

Preservar la zona horaria en el tipo de marca de tiempo de PostgreSQL

Como ya se habrá dado cuenta, la zona horaria no se guarda en absoluto con los tipos de fecha / hora de Postgres, ni siquiera con timestamptz . Su función es solo un modificador de entrada o un decorador de salida, respectivamente. Solo se guarda el valor (el punto en el tiempo). Amplios detalles en esta respuesta relacionada:

  • Ignorar las zonas horarias por completo en Rails y PostgreSQL

Por lo tanto, si desea conservar esa parte de la cadena de entrada, debe extraerla de la cadena y guardarla usted mismo. Yo usaría una tabla como:

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

tz , siendo text , puede contener un desplazamiento numérico así como una abreviatura de zona horaria , o una zona horaria nombre .

La dificultad es extraer la parte de la zona horaria de acuerdo con las diversas reglas que sigue el analizador y de una manera que no se rompa fácilmente. En lugar de preparar su propio procedimiento, haga que el analizador haga el trabajo . Considere esta demostración:

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;

Violín SQL.

Funciona con o sin T entre fecha y hora. La lógica clave está aquí:

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

Tome lo que queda de una cadena de marca de tiempo después de recortar la longitud de lo que el analizador identificó como componente de fecha/hora. Esto depende de que la entrada sea, como dijiste:

cadenas ISO8601 validadas