Unix zaman damgası, 1 Ocak 1970 gece yarısından bu yana geçen saniye sayısıdır.
PostgreSQL'den doğru unix zaman damgasını nasıl alabilirim?
currenttimestamp.com]2 ve timestamp.1e5b.de ile karşılaştırdığımda PostgreSQL'den beklenen zamanı alamıyorum:
Bu, doğru zaman damgasını döndürür:
SELECT extract(epoch from now());
Bu olmasa da:
SELECT extract(epoch from now() at time zone 'utc');
UTC +02 zaman diliminde yaşıyorum. PostgreSQL'den geçerli unix zaman damgasını almanın doğru yolu nedir?
Bu, doğru saati ve saat dilimini döndürür:
SELECT now();
now
-------------------------------
2011-05-18 10:34:10.820464+02
Başka bir karşılaştırma:
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
Postgres'te timestamp with time zone
timestamptz
olarak ve timestamp without time zone
timestamp
olarak kısaltılabilir. Ben basitlik için daha kısa tip isimlerini kullanacağım.
Unix zaman damgasını now()
gibi bir postgres timestamptz
dan almak, dediğiniz gibi basittir:
select extract(epoch from now());
Bu, now()
da dahil olmak üzere timestamptz
türündeki herhangi bir şeyden mutlak zamanı alma hakkında bilmeniz gereken tek şeydir.
İşler yalnızca bir timestamp
alanınız olduğunda karmaşıklaşır.
Bu alana now()
gibi timestamptz
verileri koyduğunuzda, önce belirli bir zaman dilimine dönüştürülür (ya açıkça at time zone
ile ya da oturum zaman dilimine dönüştürülerek) ve zaman dilimi bilgisi atılır. Artık mutlak bir zamana atıfta bulunmaz. Bu nedenle zaman damgalarını genellikle timestamp
olarak saklamak istemezsiniz ve normalde timestamptz
kullanırsınız - belki bir film belirli bir tarihte her zaman diliminde akşam 6'da gösterime giriyordur, bu tür bir kullanım durumu.
Eğer sadece tek bir zaman diliminde çalışıyorsanız timestamp
ı (yanlış) kullanabilirsiniz. Timestamptz'a geri dönüştürme, DST ile başa çıkmak için yeterince akıllıdır ve zaman damgalarının dönüştürme amacıyla geçerli saat diliminde olduğu varsayılır. İşte GMT/BST için bir örnek:
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|
*/
Ancak, aşağıdaki kafa karıştırıcı davranışa dikkat edin:
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|
*/
Bunun nedeni](https://www.postgresql.org/docs/9.6/static/datatype-datetime.html#AEN6247):
PostgreSQL, türünü belirlemeden önce bir değişmez dizenin içeriğini asla incelemez ve bu nedenle her iki [...] zaman dilimi olmayan zaman damgası olarak ele alınır. Bir değişmezin zaman dilimi ile zaman damgası olarak ele alınmasını sağlamak için, ona doğru açık türü verin... Zaman dilimi olmadan zaman damgası olarak belirlenen bir değişmezde, PostgreSQL herhangi bir zaman dilimi göstergesini sessizce yoksayacaktır
SELECT extract(epoch from now() at time zone 'utc');
doğru zaman damgasını döndürmez çünkü postgres zaman dilimi dönüşümü sonuçtan zaman dilimi bilgisini atar:
9.9.3. ZAMAN BÖLGESİNDE
Sözdizimi: zaman dilimi olmadan zaman damgası ZAMAN BÖLGESİNDE Döndürür: zaman dilimi ile zaman damgası Zaman dilimi olmadan verilen zaman damgasını belirtilen zaman diliminde bulunuyormuş gibi değerlendirin
Sözdizimi: ZAMAN BÖLGESİNDE zaman dilimi ile zaman damgası Döndürür: zaman dilimi olmadan zaman damgası Zaman dilimi ile verilen zaman damgasını, zaman dilimi ataması olmadan yeni zaman dilimine dönüştürür
Daha sonra, extract zaman damgasına saat dilimi olmadan bakar ve yerel saat olarak kabul eder (aslında zaten utc olmasına rağmen).
Doğru yol şöyle olurdu:
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)
Son satırda ilk at zaman dilimi
dönüşümü gerçekleştirir, ikincisi ise sonuca yeni zaman dilimi atar.