Hvordan får jeg dagens unix-tidsstempel fra PostgreSQL?

Unix-tidsstempel er antall sekunder siden midnatt UTC 1. januar 1970.

Hvordan får jeg riktig unix-tidsstempel fra PostgreSQL?

Når jeg sammenligner med currenttimestamp.com og tidsstempel.1e5b.de Jeg får ikke forventet tid fra PostgreSQL:

Dette returnerer riktig tidsstempel:

SELECT extract(epoch from now()); 

Selv om dette ikke gjør det:

SELECT extract(epoch from now() at time zone "utc"); 

Jeg bor i tidssonen UTC +02. Hva er den riktige måten å få den nåværende unix-tidsstemplet fra PostgreSQL?

Dette returnerer riktig tid og tidssone:

SELECT now(); now ------------------------------- 2011-05-18 10:34:10.820464+02 

En annen sammenligning:

select now(), extract(epoch from now()), extract(epoch from now() at time zone "utc"); now | date_part | date_part -------------------------------+------------------+------------------ 2011-05-18 10:38:16.439332+02 | 1305707896.43933 | 1305700696.43933 (1 row) Unix timestamp from the web sites: 1305707967 

Svar

I postgres, timestamp with time zone kan forkortes som timestamptz, og timestamp without time zone som timestamp. Jeg vil bruke de kortere typenavnene for enkelhets skyld.

Å få Unix-tidsstempelet fra en postgres timestamptz som now() er enkelt, som du sier, bare:

select extract(epoch from now()); 

Det er egentlig alt du trenger å vite om å få absolutt tid fra noe av typen timestamptz, inkludert now().

Ting blir bare kompliserte når du har et timestamp -felt .

Når du setter timestamptz data som now() i det feltet, blir det først konvertert til en bestemt tidssone (enten eksplisitt med at time zone eller ved å konvertere til øktens tidssone) og informasjon om tidssonen forkastes . Det refererer ikke lenger til en absolutt tid. Dette er grunnen til at du vil vanligvis ikke lagre tidsstempler som timestamp og vil normalt bruke timestamptz – kanskje en film blir utgitt kl 18.00 på en bestemt dato i hver tidssone , det er den slags brukssak.

Hvis du bare jobber i en enkelt tidssone, kan du komme unna med (mis) ved å bruke timestamp. Konvertering tilbake til timestamptz er smart nok til å takle sommertid, og tidsstemplene antas for konverteringsformål å være i gjeldende tidssone. Her er et eksempel for 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

Men vær oppmerksom på følgende forvirrende oppførsel:

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

Denne er fordi :

PostgreSQL undersøker aldri innholdet i en bokstavelig streng før den bestemmer typen, og vil derfor behandle begge […] som tidsstempel uten tidssone. sørg for at en bokstav blir behandlet som tidsstempel med tidssone, gi den riktig eksplisitt type … I en bokstav som er bestemt for å være tidstempel uten tidssone, vil PostgreSQL stille ignorere enhver tidssoneindikasjon

Kommentarer

  • Enhver ide om hvordan du konverterer den resulterende desimalen til et helt tall uten desimaltegn (jeg mener å slå sammen tallet og desimalet som ett stort heltall). Takk.
  • Som dette men jeg ' er sikker på at du ikke ' ikke vil gjøre det. Kanskje du vil multiplisere med en kraft på ti og fjerne eventuelle gjenværende desimaler?
  • @ W.M. Kanskje slik? SELECT FLOOR(EXTRACT(epoch FROM NOW())*1000);

Svar

SELECT extract(epoch from now() at time zone "utc"); 

returnerer ikke riktig tidsstempel fordi konvertering av tidssone fra postgres kaster bort tidssoneinformasjon fra resultatet:

9.9.3. PÅ TIDSSONE

Syntaks: tidsstempel uten tidssone PÅ TIDSZONE-sone
Returnerer: tidsstempel med tidssone
Behandle gitt tidsstempel uten tidssone som lokalisert i den angitte tidssonen

Syntaks: tidsstempel med tidssone AT TIME ZONE zone
Returnerer: tidstempel uten tidssone
Konverter gitt tidsstempel med tidssone til den nye tidssonen, uten tidssonebetegnelse

etterpå, ser utdrag på tidsstempel uten tidssone og anser det for å være en lokal tid (selv om det allerede er utc faktisk).

Den riktige måten ville være:

select now(), extract(epoch from now()), -- correct extract(epoch from now() at time zone "utc"), -- incorrect extract(epoch from now() at time zone "utc" at time zone "utc"); -- correct now | date_part | date_part | date_part -------------------------------+------------------+------------------+------------------ 2014-10-14 10:19:23.726908+02 | 1413274763.72691 | 1413267563.72691 | 1413274763.72691 (1 row) 

I siste linje utfører den første at time zone konverteringen, seco og man tildeler resultatet en ny tidssone.

Legg igjen en kommentar

Din e-postadresse vil ikke bli publisert. Obligatoriske felt er merket med *