Hogyan kaphatom meg a PostgreSQL-től a jelenlegi unix időbélyeget?

Unix időbélyegzője az UTC UTC, 1970. január 1., éjfél óta eltelt másodpercek száma.

Hogyan szerezhetem meg a helyes unix időbélyeget a PostgreSQL-től?

Ha összehasonlítjuk a currenttimestamp.com és a timestamp.1e5b.de Nem kapom meg a várt időt a PostgreSQL-től:

Ez a helyes időbélyeget adja vissza:

SELECT extract(epoch from now()); 

Bár ez nem történik meg:

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

UTC +02 időzónában élek. Mi a helyes módja az aktuális unix időbélyeg megszerzésének a PostgreSQL-ből?

Ez a helyes idő- és időzónát adja vissza:

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

Egy másik összehasonlítás:

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 

Válasz

Postgres-ben rövidítése timestamptz, timestamp without time zone pedig timestamp. Az egyszerűség kedvéért a rövidebb típusneveket fogom használni.

A Unix időbélyeg megszerzése egy postgres-ből timestamptz, mint például now() egyszerű, ahogy mondja, csak:

select extract(epoch from now()); 

Ez minden, amit tudnia kell arról, hogy az abszolút időt bármilyen , beleértve a now().

A dolgok csak akkor bonyolódnak, ha van timestamp mező .

Ha timestamptz adatokat, például now() ad be ebbe a mezőbe, akkor először egy adott időzónává konvertálódik (vagy kifejezetten a at time zone paranccsal, vagy a munkamenet időzónájává történő átalakítással), és az időzóna információ elvetésre kerül . Ez már nem abszolút időre vonatkozik. Ezért általában nem akarod az időbélyegeket timestamp néven tárolni, és általában a timestamptz -t használod – lehet, hogy egy filmet este hat órakor adnak le egy adott filmről dátum minden időzónában , ez a fajta használati eset.

Ha valaha csak egyetlen időzónában dolgozik, akkor megúszhatja (tévesen) a timestamp. Az timestamptz visszaállítása elég okos ahhoz, hogy megbirkózzon a DST-vel, és feltételezzük, hogy az időbélyegek átalakítás céljából az aktuális időzónában vannak. Ez egy példa a GMT / BST-re:

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

De vegye figyelembe a következő zavaros viselkedést:

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

Ez az azért van, mert :

A PostgreSQL soha nem vizsgálja meg a szó szerinti karakterlánc tartalmát, mielőtt meghatározná a típusát, ezért mindkét […] időbélyegként fogja kezelni. győződjön meg arról, hogy a literálist időbélyegként kezelik-e időzónával, adja meg a helyes explicit típust … Egy olyan literálban, amelyet időbélyeg nélküli időbélyegként határoztak meg, a PostgreSQL csendben figyelmen kívül hagyja az időzóna-jelzést

Megjegyzések

  • Bármilyen ötlet, hogyan lehet a kapott tizedest egész számra tizedespont nélkül átalakítani (a szám és a tizedes összevonására gondolok, mint egy nagy egész szám). Köszönöm.
  • Mint ezt , de én ' biztos vagyok benne, hogy nem igazán akarod '. Esetleg tízes szorzóval szeretne megszorozni, és levonni a maradék tizedesjegyeket?
  • @ W.M. Talán így? SELECT FLOOR(EXTRACT(epoch FROM NOW())*1000);

Válasz

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

nem adja vissza a megfelelő időbélyegzőt, mert a postgres időzóna átalakítás eldobja az időzóna adatait az eredményből:

9.9.3. AZ IDŐZónában

Szintaxis: időbélyeg nélkül időzóna AT TIME ZONE zóna
Visszaadja: időbélyeg időzónával
Az adott időbélyeg nélkül kezelje az adott időbélyeget a megadott időzónában

Szintaxis: időbélyeg időzónával AT IDŐZÓNA zóna
Visszatér: időbélyeg időzóna nélkül
Adott időbélyeg konvertálása az időzónával az új időzónára, időzóna megjelölés nélkül

utána a kivonat az időbélyegzőt időzóna nélkül megnézi, és helyi időnek tekinti (bár valójában ez már utcai).

A helyes mód a következő lenne:

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) 

Az utolsó sorban az első at time zone hajtja végre az átalakítást, a seco Az egyik új időzónát rendel az eredményhez.

Vélemény, hozzászólás?

Az email címet nem tesszük közzé. A kötelező mezőket * karakterrel jelöltük