JSON Toolkit

รูปแบบวันที่และเวลาของ JSON ควรเป็นแบบไหน

สรุปสำคัญ: ตัวเลข epoch และสตริง ISO ต่างมีข้อแลกเปลี่ยน แต่การผสมกันคือสิ่งที่ทำให้พังจริง ๆ ใช้ ISO 8601 พร้อม offset เก็บเป็น UTC และแสดงตามเขตเวลาของผู้ใช้

ผู้เริ่มต้นอ่านประมาณ 3 นาทีเผยแพร่ 2026-10-30อัปเดต 2026-10-30
การเลือกรูปแบบ timestamp สำหรับ JSON API

สรุปสั้น ๆ: ใช้ ISO 8601 พร้อม offset ที่ชัดเจนบน wire เก็บเป็น UTC โดยมี Z ต่อท้าย และแปลงเฉพาะตอนแสดงผล; ถ้าเลือกใช้ตัวเลข epoch ให้กำหนดวินาทีหรือมิลลิวินาทีให้ชัดทั้งระบบและใส่หน่วยในชื่อฟิลด์

ทำไม 2026-10-30 14:30:00 ยังไม่พอ

สตริงนั้นไม่มีเขตเวลากำกับ 14:30 ในเซี่ยงไฮ้กับ 14:30 ในลอนดอนห่างกันแปดชั่วโมง และไม่มีทางรู้ว่าหมายถึงอันไหน new Date('2026-10-30 14:30:00') parse ตามเขตเวลาท้องถิ่นของ รันไทม์ เซิร์ฟเวอร์กับเบราว์เซอร์จึงได้เวลาที่ต่างกันสองค่าจาก payload เดียว — บั๊กประเภทที่ทำซ้ำไม่ได้

2026-10-30 เปล่า ๆ ไม่ใช่จุดเวลาเลย เหมาะกับวันเกิดและรอบบิล แต่ผิดสำหรับเวลาที่สร้าง

สองรูปแบบที่ใช้ได้

สตริง ISO 8601

{
  "createdAt": "2026-10-30T14:30:00+08:00",
  "updatedAt": "2026-10-30T06:30:00Z"
}

อ่านได้ เรียงลำดับได้เมื่อรูปแบบสม่ำเสมอ มีความละเอียดถึงมิลลิวินาทีหากต้องการ และอธิบายตัวเอง

ตัวเลข epoch

{ "createdAt": 1793519400 }

กะทัดรัดและไม่กำกวม แต่อ่านไม่ออก และ วินาทีกับมิลลิวินาทีคือภัยถาวร ถ้าเลือกใช้ epoch ให้กำหนดหน่วยให้เป็นมาตรฐานและใส่ในชื่อฟิลด์: createdAtMs ปลอดภัยกว่า createdAt มาก

ข้อกำหนดที่ควรตั้งไว้แต่เนิ่น ๆ

รายการ ข้อกำหนด
รูปแบบบน wire ISO 8601 พร้อม Z หรือ +08:00
เขตเวลาที่เก็บ UTC เพื่อไม่ให้ DST เข้ามาเกี่ยวข้อง
ความละเอียด มิลลิวินาทีก็พอ
การตั้งชื่อฟิลด์ createdAt, updatedAt, expiresAt
วันที่ล้วน ฟิลด์ date แยกต่างหาก เช่น birthday: "1990-01-01"
ระยะเวลา จำนวนเต็มบวกหน่วย เช่น timeoutMs: 3000

การแสดงผล

new Intl.DateTimeFormat('en-GB', {
  dateStyle: 'medium',
  timeStyle: 'short',
  timeZone: 'Europe/London',
}).format(new Date('2026-10-30T06:30:00Z'));

ระบุ timeZone อย่างชัดเจนเมื่อการแสดงผลต้องไม่ตามอุปกรณ์ การพึ่งค่าเริ่มต้นของเบราว์เซอร์ถูกสำหรับเวลาที่ผู้ใช้เห็น แต่ผิดสำหรับรายงาน

บั๊กที่เกิดซ้ำสามอย่าง

วันที่เปล่า ๆ ถูก parse เป็นเที่ยงคืน UTC ตามสเปก ECMAScript สตริงที่มีเฉพาะวันที่เป็น UTC ขณะที่สตริงวันที่และเวลาเป็นเวลาท้องถิ่น ความไม่สอดคล้องนี้เป็นแหล่งของบั๊กคลาดเคลื่อนหนึ่งวันที่พบได้บ่อย

เขตเวลาของฐานข้อมูลไม่ตรงกับ serializer datetime ของ MySQL ไม่มีเขตเวลา; เขียนเป็นเวลาท้องถิ่น อ่านเป็น UTC แล้วทุกอย่างเลื่อนตาม offset

เวลาออมแสง การเก็บเวลาท้องถิ่นในอนาคตสร้างจุดเวลาที่ไม่มีอยู่หรือเกิดซ้ำสองครั้ง UTC ไม่มีช่องว่างเช่นนั้น

คำถามที่พบบ่อย

ควรเลือกระหว่าง ISO 8601 กับตัวเลข epoch อย่างไร?

ใช้ ISO 8601 เมื่อมีคนอ่าน payload, เมื่อต้องการลำดับแบบ lexical หรือเมื่อค่าต้องพาเขตเวลาของตัวเองไปด้วย; ต้นทุนคือไบต์เพิ่มราวสิบกว่าไบต์และไลบรารี parse ใช้ตัวเลข epoch เมื่อความกะทัดรัดและการจัดการข้ามภาษาง่าย ๆ สำคัญกว่า แต่กำหนดวินาทีหรือมิลลิวินาทีให้ชัดทั้งระบบและบอกว่าฟิลด์เก็บหน่วยใด

วันที่เปล่า ๆ กับ timestamp ควรใช้ฟิลด์เดียวกันไหม?

ไม่ควร 2026-10-30 เปล่า ๆ คือวันในปฏิทินที่ไม่มีเวลาและไม่มีเขตเวลา ขณะที่ฟิลด์ timestamp คาดหวังจุดเวลาที่แน่นอน ให้เก็บวันเกิดและรอบบิลในฟิลด์ date แยก และใช้ฟิลด์ ISO 8601 ที่ลงท้ายด้วย At สำหรับเวลาสร้างหรืออัปเดต

อ่านเพิ่มเติม