ฟังก์ชันวันที่ของ SQLite สร้างปัญหาให้นักพัฒนา JavaScript เนื่องจากขาดตัวบ่งชี้ UTC

ทีมบรรณาธิการ BigGo
ฟังก์ชันวันที่ของ SQLite สร้างปัญหาให้นักพัฒนา JavaScript เนื่องจากขาดตัวบ่งชี้ UTC

ฟังก์ชันวันที่และเวลาของ SQLite กลายเป็นแหล่งความหงุดหงิดสำหรับนักพัฒนาที่ทำงานกับแอปพลิเคชัน JavaScript ปัญหาหลักเกิดจากแนวทางของ SQLite ในการจัดรูปแบบ UTC timestamps ซึ่งแตกต่างจากแนวปฏิบัติมาตรฐานและสร้างปัญหาความเข้ากันได้กับการพัฒนาเว็บสมัยใหม่

การขาดตัวบ่งชี้ UTC สร้างปัญหาการแยกวิเคราะห์ใน JavaScript

ปัญหาหลักอยู่ที่พฤติกรรมการจัดรูปแบบวันที่ของ SQLite เมื่อ SQLite สร้าง UTC timestamps จะไม่รวมอักขระ 'Z' ต่อท้ายที่ระบุเวลา UTC ตามมาตรฐาน ISO การละเลยที่ดูเหมือนเล็กน้อยนี้มีผลกระทบอย่างมีนัยสำคัญต่อนักพัฒนา JavaScript เมื่อการแยกวิเคราะห์วันที่ของ JavaScript พบ timestamp ที่ไม่มีส่วนต่อท้าย 'Z' จะถือว่าวันที่อยู่ในเขตเวลาท้องถิ่นของไคลเอนต์แทนที่จะเป็น UTC พฤติกรรมนี้ทำให้เกิดเซสชันการดีบักที่ยาวนานหลายชั่วโมงสำหรับนักพัฒนาที่ไม่ทราบเกี่ยวกับความแปลกประหลาดนี้

ปัญหาจะรุนแรงเป็นพิเศษกับรูปแบบฐานข้อมูลทั่วไปเช่นคอลัมน์ createdAt ที่ใช้ฟังก์ชัน NOW() ของ SQLite ทุกครั้งที่ timestamps เหล่านี้ต้องการการประมวลผลจะต้องมีการจัดการเพิ่มเติมเพื่อเพิ่มอักขระ 'Z' ที่ขาดหายไป นักพัฒนาต้องใช้วิธีแก้ไขปัญหาเพื่อตรวจสอบว่าวันที่ UTC รวมตัวบ่งชี้ต่อท้ายหรือไม่และเพิ่มด้วยตนเองเมื่อขาดหายไป

รูปแบบฟังก์ชันวันที่ของ SQLite

ฟังก์ชัน รูปแบบผลลัพธ์ ตัวอย่าง
date() YYYY-MM-DD 2025-06-16
time() HH:MM:SS 13:22:19
datetime() YYYY-MM-DD HH:MM:SS 2025-06-16 13:22:19
current_timestamp YYYY-MM-DD HH:MM:SS 2025-06-15 19:50:50

หมายเหตุ: รูปแบบเหล่านี้ไม่มีตัวบ่งชี้ UTC 'Z' โดยค่าเริ่มต้น

ความสับสนเรื่องการปฏิบัติตาม ISO 8601

จุดสับสนอีกประการหนึ่งเกี่ยวข้องกับการอ้างสิทธิ์ของ SQLite เรื่องการปฏิบัติตาม ISO 8601 ฟังก์ชัน current_timestamp ส่งคืนวันที่ในรูปแบบเช่น 2025-06-15 19:50:50 โดยใช้ตัวคั่นช่องว่างแทนอักขระ 'T' ที่คาดหวังโดยทั่วไปในรูปแบบ ISO 8601 สิ่งนี้สร้างความไม่สอดคล้องเมื่อทำงานกับเมธอด .toISOString() ของ JavaScript ซึ่งสร้างสตริง ISO ที่จัดรูปแบบอย่างถูกต้อง

แม้ว่าบางคนจะโต้แย้งว่าการใช้ช่องว่างแทน 'T' ได้รับอนุญาตภายใต้การตีความบางประการของมาตรฐาน ISO 8601 แต่เอกสารไม่ได้อธิบายความแตกต่างนี้อย่างชัดเจน มาตรฐานอนุญาตให้ละเว้นตัวคั่น 'T' โดยข้อตกลงร่วมกันในแอปพลิเคชันเฉพาะ แต่การแทนที่ด้วยช่องว่างไม่ได้รับอนุญาตอย่างชัดเจนในข้อกำหนดหลัก

วิธีแก้ปัญหาชั่วคราว

การเพิ่ม UTC Indicator แบบแมนนวล:

  • strftime('%Y-%m-%dT%H:%M:%SZ') - รูปแบบ UTC พื้นฐานพร้อม Z
  • strftime('%Y-%m-%dT%H:%M:%fZ') - รูปแบบ UTC พร้อมเศษส่วนของวินาที

วิธีการจัดเก็บข้อมูลทางเลือก:

  • จัดเก็บเป็น INTEGER (Unix epoch มิลลิวินาที/นาโนวินาที)
  • ใช้ Julian day numbers สำหรับวันที่ในอดีต
  • ใช้งาน custom JSON serialization สำหรับ time zones ที่ซับซ้อน

แนวทางการจัดเก็บทางเลือก

นักพัฒนาหลายคนได้เลิกใช้ฟังก์ชัน datetime แบบสตริงของ SQLite ทั้งหมด การจัดเก็บ timestamps เป็นจำนวนเต็มที่แสดงมิลลิวินาทีหรือนาโนวินาทีตั้งแต่ Unix epoch กลายเป็นทางเลือกที่ได้รับความนิยม แนวทางนี้มีข้อดีหลายประการ: ประมวลผลเร็วกว่า ใช้พื้นที่จัดเก็บน้อยกว่า และหลีกเลี่ยงความไม่สอดคล้องในการจัดรูปแบบโดยสิ้นเชิง

อย่างไรก็ตาม แนวทางแบบจำนวนเต็มนี้มาพร้อมกับการแลกเปลี่ยนของตัวเอง วันที่แบบสตริงสามารถอ่านได้ทันทีเมื่อตรวจสอบเนื้อหาฐานข้อมูลโดยตรง ในขณะที่ timestamps แบบจำนวนเต็มต้องการการแปลงเพื่อให้มนุษย์เข้าใจ นักพัฒนาบางคนแก้ปัญหานี้โดยการสร้างมุมมองฐานข้อมูลที่แสดงวันที่ที่มนุษย์อ่านได้เมื่อจำเป็นสำหรับการตรวจสอบ

ข้อพิจารณาการย้ายฐานข้อมูล

ปัญหาการจัดรูปแบบ datetime ได้มีอิทธิพลต่อการเลือกระบบฐานข้อมูลของนักพัฒนาบางคน ฟังก์ชันวันที่ของ PostgreSQL รวมส่วนต่อท้าย 'Z' โดยอัตโนมัติสำหรับ UTC timestamps ทำให้เข้ากันได้กับแอปพลิเคชัน JavaScript มากกว่าทันที ข้อได้เปรียบด้านความเข้ากันได้นี้กลายเป็นปัจจัยในการตัดสินใจเลือกฐานข้อมูล โดยเฉพาะสำหรับแอปพลิเคชันเว็บที่พึ่งพาการประมวลผลวันที่ฝั่งไคลเอนต์อย่างมาก

สำหรับนักพัฒนาที่ต้องทำงานกับทั้ง SQLite และฐานข้อมูลอื่น ๆ ความไม่สอดคล้องในการจัดรูปแบบเหล่านี้สร้างความซับซ้อนเพิ่มเติมในการรักษาพฤติกรรมที่สอดคล้องกันในระบบฐานข้อมูลที่แตกต่างกัน

ชุมชนนักพัฒนา SQLite ยังคงหารือเกี่ยวกับปัญหาเหล่านี้ โดยผู้ใช้บางคนเสนอส่วนขยายและการปรับเปลี่ยนเพื่อปรับปรุงการจัดการ datetime อย่างไรก็ตาม พฤติกรรมการจัดรูปแบบหลักยังคงไม่เปลี่ยนแปลง ทำให้นักพัฒนาต้องใช้โซลูชันของตนเองสำหรับการรวม JavaScript ที่ราบรื่น

อ้างอิง: sqlite - Date And Time Functions