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| */
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| */
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ábanSzintaxis: 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.