Como você já descobriu, o fuso horário não é salvo com os tipos de data/hora do Postgres, nem mesmo com
timestamptz
. Seu papel é apenas um modificador de entrada ou um decorador de saída, respectivamente. Apenas o valor (o ponto no tempo) é salvo. Amplos detalhes nesta resposta relacionada:- Ignorando completamente os fusos horários no Rails e no PostgreSQL
Portanto, se você quiser preservar essa parte da string de entrada, precisará extraí-la da string e salvá-la você mesmo. Eu usaria uma tabela como:
CREATE TABLE tstz
...
, ts timestamp -- without time zone
, tz text
)
tz
, sendo text
, pode conter um deslocamento numérico bem como uma abreviatura de fuso horário , ou um fuso horário nome . A dificuldade é extrair a parte do fuso horário de acordo com todas as várias regras que o analisador segue e de uma maneira que não seja quebrada facilmente. Em vez de preparar seu próprio procedimento, faça o analisador fazer o trabalho . Considere esta demonstração:
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.
Funciona com ou sem um
T
entre data e hora. A lógica chave está aqui:right(tstz, -1 * length(tstz::timestamp::text)) AS tz
Pegue o que resta de uma string de carimbo de data/hora depois de cortar o comprimento do que o analisador identificou como componente de data/hora. Isso depende da entrada ser, como você afirmou:
strings ISO8601 validadas