เรื่องของ Timezone 🕙🕚🕔 — ตอนจบ

mixth
Zarewoft
Published in
2 min readSep 26, 2018

ในตอนที่แล้ว:

เราได้ทราบกันแล้วนะครับว่า timezone มีหลักการทำงานอย่างไร และเราจะนำเสนอเวลาแบบ ISO อย่างไร — ในตอนนี้เราจะมาทำความเข้าใจสถานการณ์ที่เกี่ยวข้องกับเวลาต่างๆ กันครับ

กรอกเวลาลงแอพฯ ต้องยุ่งกับ timezone แค่ไหน?

กรณีนี้เราต้องพิจารณาว่าเมื่อผู้ใช้กรอกเวลา ผู้ใช้คาดหวังว่ามันเป็นเวลาของ timezone ใด?

  • หมายถึง timezone ของผู้ใช้
  • หมายถึง timezone ที่ผู้ใช้ทุกคนเข้าใจร่วมกัน

Timezone ของผู้ใช้

กรณีนี้แสดงว่าเราต้องนำ input ของผู้ใช้ประกอบกับ timezone ของผู้ใช้ สร้าง datetime ขึ้นมา ยกตัวอย่างเช่น Bob (UTC+7) กรอกเวลาว่า 2018-08-18T22:00:00 แสดงว่าเราต้องเก็บ 2018–08–18T22:00:00+07:00 ซึ่งแบบนี้โดยทั่วไป library จะทำให้เราอยู่แล้วครับ

Timezone ที่ผู้ใช้ทุกคนเข้าใจร่วมกัน

กรณีนี้เราต้องนำ input มาประกอบกับ fixed timezone ที่เรากำหนดไว้ครับ ยกตัวอย่างเช่น แม้ Alice (UTC+1) กรอกเวลาว่า

2018-08-18T22:00:00

แต่ระบบเรากำหนดว่า timezone ที่เราเข้าใจร่วมกันคือ UTC+7 เราจะโยน datetime ดังกล่าวเข้า library เลยไม่ได้ เพราะ library จะแสดงเวลาออกมาเป็น

2018-08-18T22:00:00+01:00

ซึ่งจริงๆแล้ว Alice ไม่ได้ต้องการแบบนั้นครับ เธอต้องการให้มันเป็นเวลา UTC+7 ต่างหาก ทำให้วิธีการนี้เราเปลี่ยนจุดนึงในเวลาที่ Alice ต้องการจะบอกเราครับ

วิธีการที่ถูกต้องคือ เราต้องสกัดเลขดังกล่าวและ timezone ที่ตกลงไว้ไปสร้าง datetime ใหม่ครับ ถ้าไม่ชัดว่าคนละจุดนึงในเวลาอย่างไร ให้ลองแปลงเวลาเป็น UTC ดูเพื่อความเข้าใจง่ายครับ

โดยสรุปคือเราต้องดูว่าผู้ใช้มีการใช้งานโปรแกรมเราโดยคาดหวังว่าเวลาที่กรอก หรือเวลาที่เห็นจะเป็น timezone ใดครับ

แล้วแสดงผลเวลาละ ต้องทำยังไง?

จริงๆคำตอบส่วนนี้สอดคล้องกับด้านบนครับ

หากเราต้องการแสดงเวลาที่เป็นเวลาท้องถิ่นของผู้ใช้ lib ทั่วไปจะทำส่วนนี้ให้ เพียงแค่เราโยนเวลาพร้อม timezone เข้าไปเท่านั้น

แต่หากเราต้องการแสดงเวลาที่ไม่ใช่ timezone ของ user ก็อาจจะต้องมีการปรับเล็กน้อยครับ แต่ทั้งนี้ทั้งนั้นอาจจะต้องสื่อสารกับ user นิดนึง ว่าเขาเข้าใจนะว่าเวลานี้คือเวลาอะไร ถ้าไม่เข้าใจอาจจะต้องแสดง timezone ให้เขาเห็นด้วยครับ

จะเก็บ Datetime ใน DB ยังไงละ?

จากที่ผมลองทำงานร่วมกับมันมาสักพัก หากเราต้องการแค่เก็บจุดนึงในเวลาเราจะเก็บ timezone ไหนก็ได้ครับ ไม่ว่าจะเป็น

  • fixed ของระบบเอง
  • UTC เสมอ
  • เก็บของ user แต่ละคน

ขึ้นกับความสะดวกของการทำ application และการ query ขึ้นมาอ่านด้วยตาเอง เพราะสุดท้ายแล้วตอนเราแสดงผลให้ผู้ใช้ ก็ต้องผ่านการคิดก่อนอยู่ดีว่าเราจะแสดงด้วย timezone แบบใด

แต่ถ้าเราต้องการเก็บ timezone ของผู้ใช้เพื่อใช้บอกว่าผู้ใช้กรอกมา timezone ไหน หรือเพื่อให้ผู้ใช้คนเดิมเห็นว่ากรอกอะไรไป แม้เขาจะอยู่ timezone ไหนอีกรอบก็ตาม (เอ๋ะ จะมีไหมนะ?) หากเป็นเช่นนี้เราควรเก็บ datetime ที่เป็น timezone ของผู้ใช้อยู่ด้วยครับ

ระวังว่า

  • client แต่บางตัวอาจจะมีการแปลงค่าเป็นเวลาท้องถิ่นของเราก่อนแสดงผลให้เราดู เช่น client database เป็นต้น
  • เวลาเราสกัดเวลาเพื่อเปลี่ยน timezone อย่าลืมว่ามันควรจะไปทั้งวัน และเวลานะ เพราะถ้าไปแค่เวลา เราอาจจะทำข้อมูลเพี้ยนได้ครับ

สรุป

  • เราต้องศึกษาว่าผู้ใช้มีการใช้งานโปรแกรมเราโดยคาดหวังว่าเวลาที่กรอก หรือเวลาที่เห็นจะเป็น timezone ใด
  • หากต้องการให้เวลาที่เห็นเป็นเวลาท้องถิ่นของผู้ใช้ สามารถส่ง datetime พร้อม timezone เข้าไปที่ lib ส่วนใหญ่ได้เลย
  • หากต้องการให้เห็นเวลาที่ตกลงไว้ อย่าลืมพิจารณาว่าผู้ใช้เข้าใจว่าเวลาดังกล่าวอยู่ใน timezone ใดนะครับ

แนะนำ ติชมได้เต็มที่เลยนะครับ หากมีคำถามเพิ่มเติมหรืออยากให้เขียนเรื่องไหนก็บอกกันได้เลยครับ :)

Extra

  • ในหลายๆ libs จะกำหนด timezone ด้วยชื่อเมือง เช่น Asia/Bangkok, Europe/London ซึ่งเป็น timezone ใน tz database โดย IANA ครับ เพราะว่าการกำหนด timezone เป็น offset ของ UTC อาจจะทำให้พลาดได้ เนื่องจากในบางภูมิภาคมีการเปลี่ยน timezone ด้วย

--

--

mixth
Zarewoft

🇹🇭 BKK based 👨‍💻 software engineer 🐈 love cats 🌟 push for more democratic and more transparent gov 🍿 watch way too much movies and tv series