เขตเวลา: TIMESTAMP เทียบกับ TIMESTAMPTZ
ทำความเข้าใจความแตกต่างระหว่าง TIMESTAMP กับ TIMESTAMPTZ แปลงค่าด้วย AT TIME ZONE และจัดเก็บเป็น UTC เพื่อให้แอปใช้งานได้อย่างยืดหยุ่น
เขตเวลา: TIMESTAMP เทียบกับ TIMESTAMPTZ เป็นบทเรียน SQL Academy ฟรีบน CoddyKit นี่คือบทเรียนที่ 3 จากทั้งหมด 4 บทเรียน คุณสามารถอ่านบทเรียนทั้งหมดด้านล่างฟรี — จากนั้นลองปฏิบัติด้วยตัวคุณเองในเบราว์เซอร์พร้อมตัวแก้ไขโค้ดในตัวและติวเตอร์ AI ตลอด 24/7 บทเรียนนี้เป็นส่วนหนึ่งของเส้นทางการเรียน SQL Academy และความก้าวหน้าของคุณจะซิงค์ข้ามเว็บและแอป CoddyKit คอร์ส SQL Academy มีบทเรียนทั้งหมด 4 บทเรียน
ชนิด TIMESTAMP สองแบบ
PostgreSQL มีชนิดประทับเวลาสองแบบ:
TIMESTAMP— ประทับเวลาแบบ "ไม่ระบุเขตเวลา" ไม่มีข้อมูลเขตเวลาTIMESTAMPTZ— ประทับเวลาพร้อมเขตเวลา (จัดเก็บภายในเป็น UTC)
หลักการทั่วไป: ใช้ TIMESTAMPTZ กับเหตุการณ์ และใช้ TIMESTAMP กับเวลานามธรรมล้วน ๆ เช่น "เวลาทำการ 9:00 AM"
TIMESTAMPTZ ทำงานอย่างไร
ภายในจะจัดเก็บเป็น UTC เสมอ เมื่อ INSERT ค่าที่ป้อนจะถูกแปลงจาก TZ ของเซสชันเป็น UTC เมื่อ SELECT ค่าที่ส่งออกจะถูกแปลงกลับเป็น TZ ของเซสชัน
SET TIME ZONE 'Europe/Berlin';
INSERT INTO events (ts) VALUES ('2024-03-15 12:00:00');
-- stored as 2024-03-15 11:00:00 UTC (Berlin is UTC+1 in winter)
SET TIME ZONE 'UTC';
SELECT ts FROM events;
-- 2024-03-15 11:00:00+00TIMESTAMP สูญเสียข้อมูล
TIMESTAMP ธรรมดาไม่ทราบเขตเวลา "2024-03-15 12:00:00" อาจหมายถึงเวลาท้องถิ่นใดก็ได้ เมื่อผู้ใช้ย้ายเขตเวลา ความหมายเดิมจะสูญหาย
AT TIME ZONE
แปลงระหว่างเขตเวลาเพื่อแสดงผล:
SELECT ts AT TIME ZONE 'America/New_York' AS ny_time FROM events;
SELECT ts AT TIME ZONE 'Asia/Tokyo' AS tokyo_time FROM events;การจัดเก็บ UTC และการแสดงเวลาท้องถิ่น
แนวทางที่ดีที่สุดคือจัดเก็บเป็น TIMESTAMPTZ แล้วแปลงเป็นเขตเวลาของผู้ใช้ใน SELECT ไม่ควรทำกลับกัน
SELECT id,
ts AT TIME ZONE COALESCE(u.tz, 'UTC') AS local_ts
FROM events e
JOIN users u ON u.id = e.user_id;SESSION TIME ZONE
คุณสามารถตั้งค่าได้ในแต่ละเซสชัน ผู้ใช้แต่ละคน หรือทั่วทั้งระบบ:
-- Session:
SET TIME ZONE 'Europe/Berlin';
-- Per-user (PG):
ALTER ROLE alice SET timezone TO 'Europe/Berlin';
-- Server default in postgresql.conf:
-- timezone = 'UTC'SUPPLY ZONE WITH LITERAL
ระบุเขตเวลาไว้ในค่าลิเทอรัล:
SELECT TIMESTAMPTZ '2024-03-15 12:00:00 Europe/Berlin';
SELECT '2024-03-15 12:00:00+02'::TIMESTAMPTZ;NOW() ส่งคืน TIMESTAMPTZ
NOW() และ CURRENT_TIMESTAMP จะส่งคืน TIMESTAMPTZ เสมอ การใช้ร่วมกับคอลัมน์ TIMESTAMP เป็นข้อผิดพลาดที่พบบ่อย
เมื่อ TIMESTAMP (ไม่มีเขตเวลา) เหมาะสม
สำหรับเวลานามธรรมหรือเวลาท้องถิ่นที่ไม่ขึ้นกับเขตเวลาอย่างแท้จริง เช่น "ร้านเปิดเวลา 09:00" ให้ใช้ TIMESTAMP (หรือ TIME)
CREATE TABLE store_hours (
store_id BIGINT,
open_at TIME NOT NULL,
close_at TIME NOT NULL
);การเปลี่ยนผ่าน DST
TIMESTAMPTZ จัดการ DST โดยอัตโนมัติ การบวก INTERVAL จะทำงานตามชั่วโมงบนนาฬิกา เว้นแต่จะข้ามขอบเขต DST ซึ่งอาจทำให้เวลาเลื่อนไป 23 หรือ 25 ชั่วโมง
SELECT TIMESTAMPTZ '2024-03-30 23:00:00 Europe/Berlin' + INTERVAL '5 hours';
-- Result accounts for the DST transition on March 31อย่าจัดเก็บค่าออฟเซ็ต ให้จัดเก็บชื่อเขตเวลา
ค่าออฟเซ็ตอย่าง +02:00 ไม่ได้บอกว่า DST เริ่มเมื่อใด แต่ชื่อเขตเวลาอย่าง Europe/Berlin บอกได้ เมื่อจัดเก็บเขตบ้านของผู้ใช้ ให้จัดเก็บชื่อ IANA
สรุปทบทวน
โดยค่าเริ่มต้นให้ใช้ TIMESTAMPTZ สำหรับเหตุการณ์
- จัดเก็บเป็น UTC และแสดงผลตาม TZ ของเซสชัน
- แปลงเพื่อแสดงผลด้วย AT TIME ZONE
- ใช้ TIMESTAMP (ไม่มีเขตเวลา) เฉพาะกับเวลาท้องถิ่นแบบนามธรรม
ตรวจสอบความเข้าใจ
คุณกำลังสร้างบริการ SaaS ระดับโลกที่บันทึกเหตุการณ์ของผู้ใช้ ควรใช้ชนิดประทับเวลาใดกับคอลัมน์ occurred_at
คำถามที่พบบ่อย
บทเรียน “เขตเวลา: TIMESTAMP เทียบกับ TIMESTAMPTZ” ฟรีหรือไม่
ใช่ — ข้อความเต็มของ “เขตเวลา: TIMESTAMP เทียบกับ TIMESTAMPTZ” ฟรีให้อ่านที่นี่บนเว็บ เพื่อปฏิบัติแบบโต้ตอบ (ตัวแก้ไขโค้ดในตัวและติวเตอร์ AI ตลอด 24/7) และปลดล็อคส่วนที่เหลือของคอร์ส SQL Academy ให้อัปเกรดเป็น CoddyKit PRO คอร์ส SQL Academy มีบทเรียนทั้งหมด 4 บทเรียน
คุณจะเรียนรู้อะไรในบทเรียน “เขตเวลา: TIMESTAMP เทียบกับ TIMESTAMPTZ”
ทำความเข้าใจความแตกต่างระหว่าง TIMESTAMP กับ TIMESTAMPTZ แปลงค่าด้วย AT TIME ZONE และจัดเก็บเป็น UTC เพื่อให้แอปใช้งานได้อย่างยืดหยุ่น คุณปฏิบัติ SQL Academy ด้วยโค้ดที่ใช้งานได้จริงที่คุณเรียกใช้โดยตรงในเบราว์เซอร์ และติวเตอร์ AI ตลอด 24/7 ตอบคำถามของคุณขณะที่คุณไปผ่านบทเรียน
คุณต้องมีประสบการณ์ก่อนที่จะเริ่มเรียน SQL Academy หรือไม่
ไม่จำเป็นต้องมีประสบการณ์มาก่อน SQL Academy บน CoddyKit ออกแบบมาสำหรับผู้เริ่มต้นไปจนถึงผู้เรียนขั้นสูง คุณสามารถเริ่มต้นที่นี่หรือเริ่มจากตัวแรกและเรียนด้วยความเร็วของคุณเอง นี่คือบทเรียนที่ 3 จากทั้งหมด 4 บทเรียน
บทเรียน “เขตเวลา: TIMESTAMP เทียบกับ TIMESTAMPTZ” ใช้เวลานานแค่ไหน
บทเรียน CoddyKit ส่วนใหญ่ใช้เวลาประมาณ 5–10 นาที แต่ละบทเรียนจึงสั้นและเป็นแบบโต้ตอบ คุณสามารถก้าวหน้าอย่างต่อเนื่องและกลับมาเรียนต่อจากตรงที่เพิ่งหยุดบนเว็บและแอปได้เลย
ฉันเขียนและรันโค้ดในบทเรียน SQL Academy นี้ได้ไหม
ได้ บทเรียน SQL Academy ทุกบทมีตัวแก้ไขโค้ดในตัว คุณจึงเขียนและรันโค้ดจริงได้เลยในเบราว์เซอร์ และได้รับข้อเสนอแนะจาก AI ในทันที — ไม่ต้องติดตั้งในเครื่องของคุณ
บทเรียนทั้งหมดในหลักสูตรนี้
- การคำนวณวันที่และ INTERVAL
- EXTRACT, DATE_TRUNC, AGE
- เขตเวลา: TIMESTAMP เทียบกับ TIMESTAMPTZ
- รายงานวันที่ที่พบบ่อย (MTD, WoW, YoY)