In postgres, timestamp with time zone
può essere abbreviato come timestamptz
e timestamp without time zone
come timestamp
. Userò i nomi di tipo più brevi per semplicità.
Ottenere il timestamp Unix da un postgres timestamptz
come now()
è semplice, come dici tu, solo:
select extract(epoch from now());
Questo è davvero tutto ciò che devi sapere per ottenere il tempo assoluto da qualsiasi cosa di tipo timestamptz
, incluso now()
.
Le cose si complicano solo quando hai un timestamp
campo.
Quando si inseriscono timestamptz
dati come now()
in quel campo, verranno prima convertiti in un determinato fuso orario (esplicitamente con at time zone
o convertendo nel fuso orario della sessione) e le informazioni sul fuso orario vengono scartate . Non si riferisce più a un tempo assoluto. Questo è il motivo per cui di solito non si desidera memorizzare i timestamp come timestamp
e normalmente si usano timestamptz
- forse un film viene rilasciato alle 18:00 in una data particolare in ogni fuso orario , questo è il tipo di caso d'uso.
Se lavori sempre in un solo fuso orario potresti usare (mis) usando timestamp
. La conversione a timestamptz
è abbastanza intelligente da far fronte all'ora legale e si presume che i timestamp, ai fini della conversione, si trovino nel fuso orario corrente. Ecco un esempio per GMT / BST:
select '2011-03-27 00:59:00.0+00'::timestamptz::timestamp::timestamptz
, '2011-03-27 01:00:00.0+00'::timestamptz::timestamp::timestamptz;
/*
|timestamptz |timestamptz |
|:---------------------|:---------------------|
|2011-03-27 00:59:00+00|2011-03-27 02:00:00+01|
*/
DBFiddle
Tuttavia, nota il seguente comportamento confuso:
set timezone to 0;
values(1, '1970-01-01 00:00:00+00'::timestamp::timestamptz)
, (2, '1970-01-01 00:00:00+02'::timestamp::timestamptz);
/*
|column1|column2 |
|------:|:---------------------|
| 1|1970-01-01 00:00:00+00|
| 2|1970-01-01 00:00:00+00|
*/
DBFiddle
Questo perché :
PostgreSQL non esamina mai il contenuto di una stringa letterale prima di determinarne il tipo e pertanto tratterà entrambi […] come timestamp senza fuso orario. Per assicurarti che un valore letterale sia trattato come data / ora con fuso orario, dagli il tipo esplicito corretto ... In un valore letterale che è stato determinato come data / ora senza fuso orario, PostgreSQL ignora silenziosamente qualsiasi indicazione di fuso orario