Soru PostezSQL date () ile saat dilimi


Postgres'ten tarihleri ​​doğru seçerek bir sorun yaşıyorum - bunlar UTC'de depolanıyor, ancak Date () işleviyle doğru şekilde dönüştürülmez.

Zaman damgasını bir tarihe dönüştürmek, 4 pm PST geçmişse bana yanlış tarih verir.

2012-06-21 olmalı 2012-06-20 bu durumda.

starts_at sütun veri türü timestamp without time zone. İşte benim sorgularım:

PST saat dilimine dönüştürülmeden:

Select starts_at from schedules where id = 40;

      starts_at      
---------------------
 2012-06-21 01:00:00

Dönüştürme şunu verir:

Select (starts_at at time zone 'pst') from schedules where id = 40;
        timezone        
------------------------
 2012-06-21 02:00:00-07

Ancak, zaman dilimi içinde doğru tarihe dönüşmez.


32
2018-06-20 18:39


Menşei




Cevaplar:


Ben göremiyorum kesin bir çeşit starts_at sorunuzda. Bu bilgiyi içermelisiniz, çözümün anahtarı budur. Tahmin etmeliyim.

Temel olarak PostgreSQL her zaman tür için UTC zaman değerini kaydeder timestamp with time zone içten. Sadece ekran sizin mevcut ile değişir timezone ayarı. Etkisi AT TIME ZONE Yapı ayrıca temel veri tipiyle de değişir. Daha fazla detay bu ilgili cevap.

Eğer bir date türünden timestamp [without time zone]Geçerli saat diliminin tarihini alırsınız. Çıkıştaki gün, ekranınkiyle aynı olacaktır. timestamp değer.

Eğer bir date türünden timestamp with time zone (timestamptz kısaca), saat dilimi ofseti ilk olarak "uygulanır". Halen geçerli saat diliminin tarihini alırsınız. Görüntüle zaman damgasının Zamanla aynı nokta, Avrupa’nın bir bölümünde, ertesi gün saat 16: 00’da geçiyor. örneğin Kaliforniya'da. Belirli bir saat dilimini almak için AT TIME ZONE ilk.

Bu nedenle, sorunun üst kısmında anlattığınız şey, örneğinizle çelişir.

Verilen starts_at bir timestamp [without time zone] ve sunucunuzdaki saat yerel saate göre ayarlanır. İle test edin:

SELECT now();

Duvarınızda saat olarak aynı saati gösterir mi? Evet ise, timezone Mevcut oturumunuzun ayarı, yerel saat diliminizle uyumlu olur. Hayır ise ayarını ziyaret etmek isteyebilirsiniz. timezone senin içinde postgresql.conf. Ya da müşteriniz ayar için bir şeyler yapar mı? (Oturum başına ayarlanabilir.) Kılavuzdaki ayrıntılar.

Yerel tarihinizi almak için starts_at sadece

SELECT starts_at::date

Tantamount için:

SELECT date(starts_at)

BTW, yerel saatiniz UTC-7'de değil, UTC-8'de değil, çünkü gün ışığından yararlanma süresi (insan ırkının parlak fikirleri arasında değil) geçerli.

Pasifik Standart TIME (PST) normalde UTC'den (Evrensel saat dilimi) 8 saat önce, ancak gün ışığından yararlanma dönemlerinde (şimdiki gibi) 7 saattir. Bu yüzden timestamptz olarak görüntülenir 2012-06-21 02:00:00-07 senin örneğinde. Yapı AT TIME ZONE 'PST' gün ışığından yararlanma süresini dikkate alır. Bu iki ifade farklı sonuçlar verir (biri kış mevsiminde, biri yaz mevsiminde) ve ne zaman döküm yapıldığında farklı tarihlerle sonuçlanabilir:

SELECT '2012-06-21 01:00:00'::timestamp AT TIME ZONE 'PST'
      ,'2012-12-21 01:00:00'::timestamp AT TIME ZONE 'PST'

23
2018-06-22 00:02



Bu bir tür doğru - 'PST' gün ışığından yararlanmalarını hesaba katmıyor, bkz. John Rennpferd'in "ABD / Pasifik" ile "PST" veya "PDT" kullanma konusundaki cevabı. - Kurt Koller


Temel olarak istediğin şey:

$ select starts_at AT TIME ZONE 'UTC' AT TIME ZONE 'US/Pacific' from schedules where id = 40

Bu yazıdan çözüm aldım, düz GOLD !!! Pstgrsql TZ yönetimini daha iyi anlamak isterseniz, bu önemsiz konuyu çok açık bir şekilde açıklar, bir okumanızı verir.

Yerel saatte bölgeler olmadan PostgreSQL zaman damgalarını ifade etme

İşte neler oluyor. İlk olarak, 'PST zaman diliminin UTC zaman diliminin 8 saat gerisinde olduğunu bilmeniz gerekir. Örneğin, 1 Ocak 2014, 4:30 PST (Çarşamba, 01 Ocak 2014 16:00:30 -0800), 2 Ocak 2014, 00:30 AM UTC (Perşembe, 02 Ocak 2014 00:00:30 +0000). PST'de saat 16: 00'dan sonra herhangi bir saat ertesi güne geçer, UTC olarak yorumlanır.

Ayrıca Erwin Brandstetter'in yukarıda da belirttiği gibi, postresql'de iki tip zaman damgası veri türü vardır, bunlardan biri saat dilimi ve diğeri olmadan. Zaman damgalarınız bir saat dilimi içeriyorsa, basittir:

$ select starts_at AT TIME ZONE 'US/Pacific' from schedules where id = 40

çalışacak. Ancak, zaman damgasız zaman diliminde değilse, yukarıdaki komutu yürütmek işe yaramazsa ve İLK, saat dilimi olmayan bir zaman damgasını saat dilimi ile, yani bir UTC saat dilimi ile dönüştürmeli ve SADECE, istediğiniz 'PST' veya 'ABD / Pasifik '(bazı gün ışığından yararlanma saati sorunları ile aynıdır. Ben de iyi olmalısınız düşünüyorum).

Zaman dilimi olmayan bir zaman damgası oluşturduğum bir örnekle göstermeme izin verin. Yerel saat dilimimizin gerçekten 'PST' olduğu rahatlık için varsayalım (eğer o zaman olmasaydı, bu açıklamanın amacı için gereksiz olan daha karmaşık hale geliyordu).

Benim de söylediğim gibi:

$ select timestamp '2014-01-2 00:30:00' AS a, timestamp '2014-01-2 00:30:00' AT TIME ZONE 'UTC' AS b,  timestamp '2014-01-2 00:30:00' AT TIME ZONE 'UTC' AT TIME ZONE 'PST' AS c, timestamp '2014-01-2 00:30:00' AT TIME ZONE 'PST' AS d

Bu verim:

"a"=>"2014-01-02 00:30:00"   (This is the timezoneless timestamp)
"b"=>"2014-01-02 00:30:00+00" (This is the UTC TZ timestamp, note that up to a timezone, it is equivalent to the timezoneless one)
"c"=>"2014-01-01 16:30:00" (This is the correct 'PST' TZ conversion of the UTC timezone, if you read the documentation postgresql will not print the actual TZ for this conversion)
"d"=>"2014-01-02 08:30:00+00"

Son zaman damgası, postgresql'deki UTC'den "PST" ye zaman ayarlı zaman damgasının dönüştürülmesine ilişkin tüm karışıklığın sebebidir. Yazdığımızda:

timestamp '2014-01-2 00:30:00' AT TIME ZONE 'PST' AS d

Zaman dilimi olmayan bir zaman damgası alıyoruz ve 'PST TZ' e dönüştürmeye çalışıyoruz (dolaylı olarak postgresql'in bir UTC TZ'den zaman damgasını dönüştürmeyi istediğimizi anlayacağımızı, ancak postresql'in kendi planları olduğunu anlıyoruz). Pratikte, postgresql'in ne yaptığı, zaman ayarsız zaman damgasını ('2014-01-2 00:30:00) alır ve bir' PST 'TZ zaman damgası olduğu gibi davranır (ör: 2014-01-2 00:30 : 00 -0800) ve bunu UTC saat dilimine çevirir !!! Yani aslında geri yerine 8 saat ileri itiyor! Böylece aldık (2014-01-02 08: 30: 00 + 00).

Her neyse, bu son (sezgisel olmayan) davranış tüm karışıklığın sebebidir. Daha kapsamlı bir açıklama istiyorsanız, makaleyi okuyun, aslında bu son kısımda biraz farklı sonuçlar elde ettim, ama genel fikir aynı.


23
2017-11-18 00:21



Bu detaylı açıklama için teşekkür ederiz. Bunu okumadan önce tamamen kaybettim! - Jordan Brown


Bunun eski bir tane olduğunu biliyorum, ancak herhangi bir PST / PDT sorununu önlemek için kullanıldığında AT TIME ZONE "ABD / Pasifik" kullanmayı düşünebilirsiniz. Yani

Select_at :: TIMESTAMPTZ ZAMAN ZONE "US / Pasifik" SEÇİMDEN SUNUCULAR WHERE ID = '40';


7
2017-08-04 16:43



Gerçek zamanlarını temsil etmek için geçmişe ihtiyacınız varsa, bu kesinlikle doğrudur. - Kurt Koller