0Pricing
SQL Academy · บทเรียน

เขตเวลา: 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+00

TIMESTAMP สูญเสียข้อมูล

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 ในทันที — ไม่ต้องติดตั้งในเครื่องของคุณ

บทเรียนทั้งหมดในหลักสูตรนี้

  1. การคำนวณวันที่และ INTERVAL
  2. EXTRACT, DATE_TRUNC, AGE
  3. เขตเวลา: TIMESTAMP เทียบกับ TIMESTAMPTZ
  4. รายงานวันที่ที่พบบ่อย (MTD, WoW, YoY)
← กลับไปที่ SQL Academy