ในที่สุด JavaScript Dates กำลังจะได้รับการแก้ไข
(docs.timetime.in)- หนึ่งในการเปลี่ยนแปลงล่าสุดของ ECMAScript ที่น่าจับตามองที่สุดคือข้อเสนอ Temporal
- API นี้สามารถใช้งานได้แล้วผ่าน polyfill ที่ทีม FullCalendar จัดให้
- หนึ่งในข้อดีหลักของ API นี้คือ ในที่สุดก็มีอ็อบเจ็กต์แบบเนทีฟสำหรับแสดง "Zoned Date Time"
Zoned Date Time คืออะไร?
- เมื่อต้องจัดการกับวันที่ในแบบที่มนุษย์ใช้กัน เรามักพูดถึงวันที่และเวลาโดยละเขตเวลาออกไป
- แต่ใน JavaScript อ็อบเจ็กต์
Dateจัดการเพียงตัวเลข ทำให้ความหมายดั้งเดิมของวันที่สูญหายไป - ตัวอย่างเช่น หากต้องการบันทึกเวลาที่ชำระเงินผ่านบัตร หลายคนอาจเขียนโค้ดแบบนี้
const paymentDate = new Date('2024-07-20T10:30:00'); - เบราว์เซอร์จะคำนวณมิลลิวินาทีโดยอิงจากเขตเวลาของผู้ใช้ (CET) แต่ข้อมูลที่บันทึกไว้สามารถถูกตีความต่างกันไปตามเขตเวลา
- นอกจากข้อเท็จจริงสำคัญมากที่ว่า วันที่ใน JavaScript ไม่ได้ยึดตาม UTC แต่เป็น POSIX ซึ่งไม่สนใจ leap second อย่างสิ้นเชิง ยังมีปัญหาที่ว่าเมื่อเหลือเพียงตัวเลข ความหมายเดิมของวันที่ก็หายไปด้วย
- หลายคนคิดว่าถ้าทำงานด้วย UTC หรือส่งวันที่ในรูปแบบ ISO ก็จะปลอดภัย แต่จริง ๆ แล้วข้อมูลก็ยังสูญหายได้ จึงไม่ใช่คำตอบที่ถูกต้อง
UTC ไม่เพียงพอ
- ต่อให้ทำงานด้วยรูปแบบ ISO เวลาจะแสดงวันที่ก็ยังขาดข้อมูลเขตเวลาอยู่ดี
- ฟังก์ชันที่แปลง timestamp เป็นวันที่ที่มนุษย์อ่านได้ไม่เป็น injective (ฟังก์ชันหนึ่งต่อหนึ่ง)
- ตัวอย่างเช่น หากคุณเดินทางจากมาดริดไปซิดนีย์แล้วกลับมา คุณอาจสับสนกับปัญหาเขตเวลาในรายการธุรกรรมของธนาคาร
แนะนำ Temporal API
- Temporal API เพิ่มอ็อบเจ็กต์
Temporal.ZonedDateTimeสำหรับแสดงวันที่และเวลาพร้อมเขตเวลา - มีการเสนอส่วนขยายของ RFC 3339 เพื่อกำหนดมาตรฐานสำหรับ serialize และ deserialize วันที่ในรูปแบบสตริง
1996-12-19T16:39:57-08:00[America/Los_Angeles]- สตริงนี้หมายถึงวันที่ 19 ธันวาคม 1996 เวลา 16:39:57
- offset จาก UTC คือ -08:00 (Pacific Standard Time, PST ซึ่งลอสแอนเจลิสใช้อยู่)
- และระบุ standard time zone ที่เกี่ยวข้องเพิ่มเติม ("Pacific Standard Time") เพื่อให้แอปพลิเคชันที่รับรู้เขตเวลาสามารถนำไปพิจารณาได้
- รองรับระบบปฏิทินหลากหลายแบบ (เช่น พุทธ, จีน, Dangi, เกรกอเรียน, อิสลาม, เปอร์เซีย, ญี่ปุ่น ฯลฯ)
การดำเนินการพื้นฐาน
การสร้างวันที่
- Temporal API มีเครื่องมือทรงพลังสำหรับจัดการเขตเวลา
- ตัวอย่างเช่น เมื่อสร้างอ็อบเจ็กต์
Temporal.ZonedDateTimeก็จะสะท้อนเขตเวลาได้อย่างถูกต้องconst zonedDateTime = Temporal.ZonedDateTime.from({ year: 2024, month: 8, day: 16, hour: 12, minute: 30, second: 0, timeZone: 'Europe/Madrid'}); - ด้วยเหตุนี้ จึงรักษาเวลาได้อย่างถูกต้องแม้มีการเปลี่ยนเขตเวลาหรือการปรับเวลาท้องถิ่นอย่าง DST
การเปรียบเทียบวันที่
- อ็อบเจ็กต์
ZonedDateTimeมีเมธอดcompareสำหรับเปรียบเทียบZonedDateTimeสองค่าconst one = Temporal.ZonedDateTime.from('2020-11-01T01:45-07:00[America/Los_Angeles]'); const two = Temporal.ZonedDateTime.from('2020-11-01T01:15-08:00[America/Los_Angeles]'); Temporal.ZonedDateTime.compare(one, two); // => -1
ความสามารถในตัวที่มีประโยชน์
- พร็อพเพอร์ตี
hoursInDayจะคืนค่าจำนวนชั่วโมงจริงของวันนั้นTemporal.ZonedDateTime.from('2020-03-08T12:00-07:00[America/Los_Angeles]').hoursInDay; // => 23 (วันเริ่ม DST)
การแปลงเขตเวลา
- สามารถเปลี่ยนเขตเวลาของ
ZonedDateTimeได้ด้วยเมธอดwithTimeZonezdt = Temporal.ZonedDateTime.from('1995-12-07T03:24:30+09:00[Asia/Tokyo]'); zdt.withTimeZone('Africa/Accra').toString(); // => '1995-12-06T18:24:30+00:00[Africa/Accra]'
การคำนวณเลขคณิตพื้นฐาน
- ใช้เมธอด
.addเพื่อบวกหรือลบวันที่ตามกฎ DST ได้zdt = Temporal.ZonedDateTime.from('2020-03-08T00:00-08:00[America/Los_Angeles]'); laterDay = zdt.add({ days: 1 }); // => 2020-03-09T00:00:00-07:00[America/Los_Angeles]
การคำนวณความแตกต่างระหว่างวันที่
- เมธอด
.untilใช้คำนวณความต่างระหว่างสองช่วงเวลา และคืนค่าเป็นอ็อบเจ็กต์Temporal.Duration- ตัวอย่างเช่น สามารถใช้ในรูปแบบ
zdt.until(other)
- ตัวอย่างเช่น สามารถใช้ในรูปแบบ
บทสรุป
- Temporal API กำลังเปลี่ยนวิธีที่ JavaScript จัดการเรื่องเวลาอย่างมีนัยสำคัญ
- บทความนี้อธิบายความแตกต่างระหว่างวันที่ที่มนุษย์อ่านเข้าใจได้กับวันที่แบบ UTC รวมถึงวิธีใช้
Temporal.ZonedDateTimeเพื่อแสดงสิ่งเหล่านี้อย่างถูกต้อง - ในบทความถัดไปจะไปสำรวจอ็อบเจ็กต์ที่น่าสนใจอื่น ๆ เช่น Instant, PlainDate และ Duration
ความเห็นของ GN⁺
- ปัญหาการจัดการวันและเวลาที่สร้างความลำบากให้กับนักพัฒนา JavaScript มานาน น่าจะได้รับการแก้ไขด้วย Temporal API
- ความสามารถในการจัดการปัญหาเขตเวลาและ DST โดยอัตโนมัติ ทำให้มีประโยชน์มากในการพัฒนาแอปพลิเคชันระดับโลก
- ประเด็นเรื่องความเข้ากันได้กับอ็อบเจ็กต์
Dateเดิมและการย้ายระบบยังเป็นสิ่งที่ต้องพิจารณา TemporalAPI ถูกออกแบบมาให้ชัดเจนและเข้าใจง่าย อีกทั้งยังโดดเด่นด้านการรองรับ internationalization เช่น การสนับสนุนระบบปฏิทินหลากหลายแบบ- คาดว่าการเปลี่ยนแปลงนี้จะช่วยเพิ่มประสิทธิภาพการทำงานของนักพัฒนา JavaScript ได้อย่างมาก
5 ความคิดเห็น
ในที่สุด!
อ้างอิง: Deno มี Temporal API ฝังมาให้แล้ว
สุดยอดเลย ตอนออกแบบบริการระดับโลก เรื่องวันที่ทำให้ปวดหัวตลอด
อยากลองใช้สิ่งนี้ดูสักครั้งครับ
จริงสิ ในที่สุดก็ไม่ต้องใช้ moment หรือ dayjs แล้วเหรอ
ความเห็นจาก Hacker News
การจัดการวันที่และเวลาใน Javascript เป็นเรื่องที่ยากมาก
Dateและ Moment ของ JS ใช้งานยากคาดว่า API ใหม่จะช่วยแก้ปัญหา timezone ของ JS
ฟังก์ชันที่แปลง timestamp เป็นวันที่ในรูปแบบที่มนุษย์อ่านได้ไม่เป็น injective
tไม่มีวันที่ที่มนุษย์อ่านได้xที่เป็นเอกลักษณ์เสมอไปมุกเกี่ยวกับเส้นโค้งความยากของการจัดการเวลา
ถ้าใช้ตัวอย่างวันที่ในอนาคตมากกว่านี้ บทความน่าจะน่าเชื่อถือขึ้น
ผู้ใช้ที่กังวลเพราะยังไม่เข้าใจการจัดการเวลา
การมีมาตรฐาน datetime ที่ดีคือชนะไปแล้วครึ่งหนึ่ง
สตริงวันที่แบบ ISO ควรเก็บข้อมูลที่ถูกต้องครบถ้วน
Dateทำให้ปัญหาง่าย ๆ ซับซ้อนเกินไปถามว่าใน Postgres ควรจัดการปัญหานี้อย่างไร
ยังมีหลักฐานไม่เพียงพอว่า Temporal จะถูกนำมาใช้จริง