“ AT TIME ZONE” พร้อมชื่อโซนบั๊ก PostgreSQL หรือไม่


12

ฉันตอบคำถามstackoverflowนี้และพบผลลัพธ์ที่แปลก:

 select * from  pg_timezone_names where name = 'Europe/Berlin' ;
     name      | abbrev | utc_offset | is_dst 
---------------+--------+------------+--------
 Europe/Berlin | CET    | 01:00:00   | f

และแบบสอบถามต่อไป

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

ฉันใช้ PostgreSQL 9.1.2 และ Ubuntu 12.04
เพิ่งตรวจสอบว่าในผลลัพธ์ 8.2.11 เหมือนกัน

ตามเอกสารมันไม่สำคัญว่าฉันจะใช้ชื่อหรือตัวย่อ

นี่เป็นข้อบกพร่องหรือไม่?
ฉันกำลังทำอะไรผิดหรือเปล่า?
มีคนอธิบายผลลัพธ์นี้ได้ไหม

แก้ไข สำหรับความคิดเห็นที่ CET ไม่ใช่ยุโรป / เบอร์ลิน

ฉันแค่เลือกค่าจาก pg_timezone_names

select * from  pg_timezone_names  where abbrev ='CEST';
 name | abbrev | utc_offset | is_dst 
------+--------+------------+--------

และ

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
 .....

ในช่วงฤดูหนาวยุโรป / เบอร์ลินคือ +01 ในช่วงฤดูร้อนจะเป็น +02

EDIT2 ใน 2012-10-28 เขตเวลามีการเปลี่ยนแปลงจากเวลาฤดูร้อนถึงฤดูหนาวเวลา 2:00 น
บันทึกสองรายการนี้มีค่าเหมือนกันในยุโรป / เบอร์ลิน:

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

สิ่งนี้แนะนำว่าถ้าฉันใช้ตัวย่อตัวหนึ่ง (CET หรือ CEST) สำหรับช่วงข้อมูลขนาดใหญ่ (ฤดูร้อนและฤดูหนาว) ผลลัพธ์จะผิดสำหรับบันทึกบางส่วน จะดีถ้าฉันใช้ 'ยุโรป / เบอร์ลิน'

ฉันเปลี่ยนเวลาของระบบเป็น '2012-01-17' และ pg_timezone_names ก็เปลี่ยนไปเช่นกัน

select * from  pg_timezone_names  where name ='Europe/Berlin';
     name      | abbrev | utc_offset | is_dst 
---------------+--------+------------+--------
 Europe/Berlin | CEST   | 02:00:00   | t

1
ค่อนข้างแน่ใจว่า2012-10-28 01:30:00เป็น CEST ไม่ใช่ CET
dezso

1
เท่าที่ผมรู้CETคือไม่ได้ Europe/Berlin - อย่างน้อยไม่ได้ในช่วงเวลา DST
a_horse_with_no_name

คำตอบ:


9

ที่จริงแล้วเอกสารอธิบายอย่างชัดเจนว่าชื่อเขตเวลาและตัวย่อจะทำงานแตกต่างกัน

กล่าวโดยย่อนี่คือความแตกต่างระหว่างตัวย่อและชื่อเต็ม: ตัวย่อมักจะแสดงถึงออฟเซ็ตคงที่จาก UTC ในขณะที่ชื่อเต็มส่วนใหญ่แสดงถึงกฎเวลาออมแสงในท้องถิ่นและมีการปรับค่า UTC สองค่าที่เป็นไปได้ การอ้างอิง

FWIW การอ้างอิงเดียวกันนั้นยังบอกด้วย

เราไม่แนะนำให้ใช้เวลาพิมพ์กับเขตเวลา (แม้ว่า PostgreSQL จะรองรับกับแอปพลิเคชันรุ่นเก่าและเป็นไปตามมาตรฐาน SQL)


6

และนั่นก็ยังไม่ใช่ส่วนสำคัญของมัน! เมื่อไม่นานมานี้ฉันพบปัญหาที่คล้ายกันมาก

ข้อเสนอหลักของตัวย่อเขตเวลาได้ถูกนำเสนอไว้ที่นี่แล้ว: พวกเขาไม่ได้คำนึงถึง DST (การปรับเวลาตามฤดูกาล) สำคัญโปร: เรียบง่ายมีผลในการที่เหนือกว่าประสิทธิภาพการทำงาน การพิจารณากฎ DST ทำให้ชื่อเขตเวลาช้าลงเมื่อเปรียบเทียบ ตัวย่อของเขตเวลาเป็นแบบง่าย ๆ การชดเชยเวลาที่เป็นสัญลักษณ์ชื่อเขตเวลาอาจมีการเปลี่ยนแปลงกฎอย่างต่อเนื่อง ฉันใช้มาตรฐานในคำตอบที่เกี่ยวข้องกับ SOความแตกต่างนั้นน่าทึ่ง แต่เมื่อนำไปใช้กับชุดปกติจำเป็นต้องใช้ชื่อเขตเวลาเพื่อให้ครอบคลุมสถานะ DST ที่แตกต่างกันต่อแถว (และความแตกต่างในอดีต)

เรากำลังพูดถึงCET ส่วนที่ยุ่งยากจริงๆก็คือ "CET" ไม่เพียง (ชัดแจ้ง) ตัวย่อเขตเวลาแต่ยังเป็นชื่อเขตเวลาอย่างน้อยตามการติดตั้งของฉัน (PostgreSQL 9.1.6 บน Debian Squeeze with locale "de_AT.UTF-8 ") และอื่น ๆ ทั้งหมดที่ฉันเคยเห็น ฉันพูดถึงรายละเอียดเหล่านี้เนื่องจาก Postgres ใช้ข้อมูลตำแหน่งที่ตั้งของระบบปฏิบัติการพื้นฐานหากมี

ดูตัวเอง:

SELECT * FROM pg_timezone_names WHERE name = 'CET';

SELECT * FROM pg_timezone_abbrevs WHERE abbrev = 'CET';

ซอ Fiddle

Postgres เลือกตัวย่อของชื่อเต็ม ดังนั้นแม้ว่าฉันพบ CET ในชื่อโซนเวลา , การแสดงออก'2012-01-18 01:00 CET'::timestamptzถูกตีความตามกฎที่แตกต่างกันอย่างละเอียดสำหรับตัวย่อเขตเวลา

ถ้านั่นไม่ใช่ปืนพกโหลดฉันไม่รู้ว่ามันคืออะไร

เพื่อหลีกเลี่ยงความคลุมเครือให้ใช้ชื่อเขตเวลา 'ยุโรป / เบอร์ลิน' (หรือ 'ยุโรป / เวียนนา' ในกรณีของฉัน - ซึ่งมีประสิทธิภาพเหมือนกันยกเว้นความแตกต่างทางประวัติศาสตร์) ค้นหารายละเอียดเพิ่มเติมเกี่ยวกับหัวข้อที่อยู่ภายใต้คำถามที่เกี่ยวข้องอย่างใกล้ชิดผมกล่าวข้างต้น

ในการปิดฉันต้องการเสียงของฉันรู้สึกลึกดูถูกแนวคิดมโนธรรมของ DST มันควรจะถูกลบออกจากการดำรงอยู่และไม่เคยพูดถึงอีกครั้ง


3

ตรวจสอบสิ่งนี้:

select  
    '2012-10-28 02:30:00+02'::timestamp with time zone at time zone 'Europe/Berlin' as berlin,
    '2012-10-28 02:30:00+02'::timestamp with time zone at time zone 'CET' as cet,
    '2012-10-28 02:30:00+02'::timestamp with time zone at time zone 'CEST' as cest

+02 คือ CEST ในเบอร์ลินไม่ใช่ CET

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.