Saya menjawab pertanyaan stackoverflow ini dan menemukan hasil yang aneh:
select * from pg_timezone_names where name = 'Europe/Berlin' ;
name | abbrev | utc_offset | is_dst
---------------+--------+------------+--------
Europe/Berlin | CET | 01:00:00 | f
dan permintaan selanjutnya
select id,
timestampwithtimezone,
timestampwithtimezone at time zone 'Europe/Berlin' as berlin,
timestampwithtimezone at time zone 'CET' as cet
from data ;
id | timestampwithtimezone | berlin | cet
-----+------------------------+---------------------+---------------------
205 | 2012-10-28 01:30:00+02 | 2012-10-28 01:30:00 | 2012-10-28 00:30:00
204 | 2012-10-28 02:00:00+02 | 2012-10-28 02:00:00 | 2012-10-28 01:00:00
203 | 2012-10-28 02:30:00+02 | 2012-10-28 02:30:00 | 2012-10-28 01:30:00
202 | 2012-10-28 02:59:59+02 | 2012-10-28 02:59:59 | 2012-10-28 01:59:59
106 | 2012-10-28 02:00:00+01 | 2012-10-28 02:00:00 | 2012-10-28 02:00:00
Saya menggunakan PostgreSQL 9.1.2 dan ubuntu 12.04.
Hanya memeriksa bahwa pada hasil 8.2.11 adalah sama.
Menurut dokumentasi , tidak masalah jika saya menggunakan nama atau singkatan.
Apakah ini bug?
Apakah saya melakukan sesuatu yang salah?
Adakah yang bisa menjelaskan hasil ini?
EDIT Untuk komentar bahwa CET bukan Eropa / Berlin.
Saya hanya memilih nilai dari pg_timezone_names.
select * from pg_timezone_names where abbrev ='CEST';
name | abbrev | utc_offset | is_dst
------+--------+------------+--------
dan
select * from pg_timezone_names where abbrev ='CET';
name | abbrev | utc_offset | is_dst
---------------------+--------+------------+--------
Africa/Tunis | CET | 01:00:00 | f
Africa/Algiers | CET | 01:00:00 | f
Africa/Ceuta | CET | 01:00:00 | f
CET | CET | 01:00:00 | f
Atlantic/Jan_Mayen | CET | 01:00:00 | f
Arctic/Longyearbyen | CET | 01:00:00 | f
Poland | CET | 01:00:00 | f
.....
Selama musim dingin Eropa / Berlin adalah +01. Selama musim panas itu +02.
EDIT2
Pada 2012-10-28 zona waktu telah berubah dari waktu musim panas ke waktu musim dingin pada pukul 2:00.
Dua catatan ini memiliki nilai yang sama di Eropa / Berlin:
204 | 2012-10-28 02:00:00+02 | 2012-10-28 02:00:00 | 2012-10-28 01:00:00
106 | 2012-10-28 02:00:00+01 | 2012-10-28 02:00:00 | 2012-10-28 02:00:00
Ini menunjukkan bahwa jika saya menggunakan salah satu singkatan (CET atau CEST) untuk rentang data besar (waktu musim panas dan musim dingin) hasilnya akan salah untuk beberapa rekaman. Akan baik jika saya menggunakan 'Eropa / Berlin'.
Saya mengubah waktu sistem menjadi '2012-01-17' dan pg_timezone_names telah berubah juga.
select * from pg_timezone_names where name ='Europe/Berlin';
name | abbrev | utc_offset | is_dst
---------------+--------+------------+--------
Europe/Berlin | CEST | 02:00:00 | t
sumber
2012-10-28 01:30:00
adalah CEST, bukan CET.CET
adalah tidakEurope/Berlin
- setidaknya tidak selama DST kali.Jawaban:
Sebenarnya, dokumentasi mengatakan dengan jelas bahwa nama zona waktu dan singkatan akan berperilaku berbeda.
FWIW, referensi yang sama juga mengatakan
sumber
Dan itu masih bukan intinya! Saya mengalami masalah yang sangat mirip beberapa waktu lalu.
Kontra utama dari singkatan zona waktu telah disajikan di sini: mereka tidak memperhitungkan DST (waktu musim panas). Pro utama: kesederhanaan menghasilkan kinerja yang unggul . Mempertimbangkan aturan DST membuat nama zona waktu lebih lambat dibandingkan. Singkatan zona waktu sederhana, offset waktu simbolis, nama zona waktu tunduk pada seperangkat aturan yang terus berubah. Saya menjalankan tolok ukur dalam jawaban terkait pada SO ini , perbedaannya luar biasa. Tetapi ketika diterapkan pada himpunan, biasanya diperlukan untuk menggunakan nama zona waktu untuk mencakup kemungkinan status DST berbeda per baris (dan juga perbedaan historis).
Kita berbicara tentang CET . Bagian yang sulit adalah bahwa "CET" tidak hanya (jelas) sebuah singkatan zona waktu , itu adalah juga sebuah nama zona waktu , setidaknya menurut instalasi saya (PostgreSQL 9.1.6 pada Squeeze Debian dengan lokal "de_AT.UTF-8 ") dan semua yang saya lihat sejauh ini. Saya menyebutkan perincian ini, karena Postgres menggunakan informasi lokal dari OS yang mendasarinya jika tersedia.
Lihat diri mu sendiri:
SQL Fiddle.
Postgres memilih singkatan dari nama lengkap. Jadi, meskipun saya menemukan CET dalam nama zona waktu , ungkapan
'2012-01-18 01:00 CET'::timestamptz
tersebut ditafsirkan menurut aturan yang agak berbeda untuk singkatan zona waktu .Jika itu bukan footgun yang dimuat, saya tidak tahu apa itu.
Untuk menghindari ambiguitas, gunakan nama zona waktu 'Eropa / Berlin' (atau 'Eropa / Wina' dalam kasus saya - yang secara efektif sama, kecuali untuk perbedaan historis). Temukan detail lebih lanjut tentang topik di bawah pertanyaan terkait erat yang saya sebutkan di atas .
Sebagai penutup, saya ingin menyuarakan rasa jijik saya yang dalam terhadap konsep tolol DST. Itu harus dihilangkan dari keberadaan dan tidak pernah dibicarakan lagi.
sumber
Periksa ini:
+02
adalah CEST di Berlin, bukan CET.sumber