13 คะแนน โดย GN⁺ 2026-03-12 | 7 ความคิดเห็น | แชร์ทาง WhatsApp
  • มาตรฐานใหม่ Temporal API ที่มาแทนข้อจำกัดของ อ็อบเจ็กต์ Date ใน JavaScript แบบถึงราก ได้มาถึง ECMAScript Stage 4 หลังพัฒนามานาน 9 ปี
  • Temporal มอบ ชนิดข้อมูลแบบ immutable, การรองรับเขตเวลาและปฏิทินอย่างชัดเจน, และ ความละเอียดระดับนาโนวินาที ช่วยขจัดความกำกวมและข้อผิดพลาดของ Date เดิม
  • องค์กรหลากหลายแห่งอย่าง Bloomberg, Igalia, Microsoft, Google, Mozilla ร่วมมือกันออกแบบสเปกและพัฒนา โดยใช้ ไลบรารีส่วนกลาง temporal_rs ที่สร้างด้วย Rust เพื่อให้หลายเอนจินทำงานร่วมกันได้
  • Temporal รองรับการคำนวณเวลาและการจัดการปฏิทินสากลได้อย่างแม่นยำผ่านชนิดข้อมูลที่แยกละเอียด เช่น ZonedDateTime, Instant, PlainDate/Time, Duration
  • มาตรฐานนี้ซึ่งแก้ปัญหาที่สะสมมากว่า 30 ปี ถูกยกให้เป็น ตัวอย่างความสำเร็จของการทำงานร่วมกันและนวัตกรรมแบบเปิดในระบบนิเวศ JavaScript

ปัญหาการจัดการเวลาใน JavaScript และการมาของ Temporal

  • เดิมที อ็อบเจ็กต์ Date เป็นการพอร์ต Date จาก Java ปี 1995 มาแทบตรง ๆ และตลอดหลายสิบปีที่ผ่านมาได้กลายเป็นต้นตอของบั๊กจากปัญหาอย่าง การเปลี่ยนค่าได้, การคำนวณเดือนที่ไม่สอดคล้องกัน, การพาร์สที่กำกวม
    • ตัวอย่าง: เมื่อใช้ setMonth อาจเกิดข้อผิดพลาดในการคำนวณช่วงสิ้นเดือน หรือเมื่อพาร์สสตริงคล้าย ISO ผลลัพธ์อาจต่างกันในแต่ละเบราว์เซอร์
  • หลังปี 2010 เมื่อเว็บแอปพลิเคชันมีความซับซ้อนขึ้น ข้อจำกัดของ Date ก็ยิ่งชัดเจนขึ้น
  • นักพัฒนาจึงใช้ไลบรารีภายนอกอย่าง Moment.js เพื่ออุดช่องว่าง แต่ก็แลกมากับ ขนาดบันเดิลที่ใหญ่ขึ้นและภาระในการดูแลรักษา
  • ในปี 2017 Maggie Johnson-Pint ได้ยื่น ข้อเสนอ Temporal ต่อ TC39 และเป็นจุดเริ่มต้นของการหารือเพื่อทำให้เป็นมาตรฐาน

ความร่วมมือระหว่าง TC39 และภาคอุตสาหกรรม

  • Temporal เริ่มต้นที่ Stage 1 ในปี 2018 และใช้เวลา 9 ปีจนมาถึง Stage 4 (การเป็นมาตรฐาน)
  • Bloomberg เข้ามามีส่วนร่วมอย่างจริงจังเพื่อแก้ปัญหาเรื่องเขตเวลาและความละเอียดในสภาพแวดล้อม JavaScript ขนาดใหญ่
    • ความต้องการหลัก: เขตเวลาที่ผู้ใช้กำหนดเองได้, ความแม่นยำของเขตเวลาเชิงประวัติศาสตร์ตาม IANA, และความละเอียดระดับนาโนวินาที
  • มีการร่วมมือกับ Igalia, Microsoft, Google, Mozilla และอื่น ๆ ในการออกแบบสเปกและพัฒนา
  • วิศวกรหลายคน เช่น Philipp Dunkel, Ujjwal Sharma, Philip Chimento, Shane Carr, Justin Grant เข้าร่วมในฐานะแชมเปียนของข้อเสนอ

ชนิดข้อมูลและความสามารถหลักของ Temporal

  • Temporal.ZonedDateTime: การแทนค่าช่วงเวลาที่เป็น immutable พร้อมเขตเวลา ปฏิทิน และการชดเชย DST อย่างชัดเจน
    • ตัวอย่าง: หาก 01:30 ไม่มีอยู่จริงในช่วงเปลี่ยน DST ของลอนดอน ระบบจะปรับเป็น 02:30 โดยอัตโนมัติ
  • Temporal.Instant: การแทนค่าจุดเวลาแบบสัมบูรณ์ที่ไม่ผูกกับเขตเวลาหรือปฏิทิน และรองรับ ความละเอียดระดับนาโนวินาที
    • สามารถแปลงจุดเวลาเดียวกันไปยังหลายเขตเวลาได้
  • PlainDate / PlainTime / PlainDateTime / PlainYearMonth / PlainMonthDay: ชนิดข้อมูลแบบ “นาฬิกาบนผนัง” ที่ไม่มีเขตเวลา
    • เหมาะกับการแสดงหรือคำนวณวันที่และเวลาแบบทั่วไป
  • Temporal.Duration: ใช้แทนช่วงเวลา และแปลงหน่วยได้หลากหลาย (total({ unit: "second" }))
  • การรองรับปฏิทิน: คำนวณกับปฏิทินที่ไม่ใช่เกรกอเรียน เช่น ปฏิทินฮีบรู ได้อย่างถูกต้อง

กระบวนการพัฒนาและการทำให้เป็นมาตรฐาน

  • Temporal เป็น การเพิ่มสเปกครั้งใหญ่ที่สุดครั้งหนึ่งในประวัติศาสตร์ ECMAScript และมี เคสทดสอบราว 4,500 รายการ
  • มีการพัฒนา อิมพลีเมนเทชันส่วนกลาง temporal_rs ที่สร้างด้วย Rust ซึ่ง เอนจินหลายตัวอย่าง V8 และ Boa ใช้ร่วมกัน
    • ข้อดี: ลดอุปสรรคในการเริ่มต้นพัฒนา, ดูแลรักษาระยะยาวได้ง่ายขึ้น, และยกระดับคุณภาพของโค้ด
  • ตลอดปี 2024~2025 temporal_rs ผ่านการทดสอบได้ครบ 100% และถูกมองเป็นกรณีศึกษาความสำเร็จของความร่วมมือข้ามเอนจิน

สถานะการรองรับและโจทย์ต่อจากนี้

  • ปัจจุบัน Temporal รองรับแล้วใน Firefox 139, Chrome/Edge 144, TypeScript 6.0 Beta
    • ส่วน Safari ยังอยู่ในขั้นเทคโนโลยีพรีวิว และ Node.js 26 มีกำหนดรองรับในอนาคต
  • โจทย์สำคัญถัดไปคือ การผสานเข้ากับ Web API
    • ตัวอย่าง: รองรับชนิด Temporal ในองค์ประกอบฟอร์มอย่าง <input type="date">
    • มีการพิจารณาความเป็นไปได้ในการใช้แทน DOMHighResTimeStamp (พร้อมยกตัวอย่างการใช้ Temporal.Now.instant())

ผลลัพธ์ของความร่วมมือและนวัตกรรมแบบเปิด

  • Temporal เป็นมาตรฐานที่เสร็จสมบูรณ์จาก ความร่วมมือข้ามหลายองค์กรตลอด 9 ปี โดยมีผู้เล่นอย่าง
    • Microsoft, Google, Mozilla, Bloomberg, Igalia, Boa เข้าร่วม
  • temporal_rs เป็นตัวอย่างความสำเร็จของ โมเดลโครงสร้างพื้นฐานแบบใช้ร่วมกัน โดย
    • พิสูจน์ให้เห็นถึงการลดต้นทุนจากการพัฒนาซ้ำซ้อน เพิ่มความสอดคล้อง และเร่งนวัตกรรม
  • Temporal ไม่ได้เป็นเพียงการปรับปรุง API แต่ยังเป็น หลักฐานของความร่วมมือที่ทำให้ชุมชน JavaScript แก้หนี้เทคนิคระยะยาวได้สำเร็จ
  • หลังผ่านไป 30 ปี ในที่สุด JavaScript ก็มี API สำหรับวันที่และเวลาที่ทันสมัย

7 ความคิดเห็น

 
jeeeyul 2026-03-12

ความซับซ้อนของการคำนวณเวลาเกิดจากหลายอย่างที่มากกว่าปัญหาเรื่องรูปแบบ ไม่ว่าจะเป็นปรัชญาของมนุษยชาติ ความแม่นยำทางดาราศาสตร์ และวัฒนธรรม การคำนวณเองนั้นใช้แค่ long ก็ง่ายอยู่แล้ว เส้นเวลาทางประวัติศาสตร์มีช่วงพิเศษที่ 1 + 1 ไม่ได้เท่ากับ 2 ถูกกำหนดไว้ในหลายแห่ง และส่วนใหญ่ก็มาจากปฏิทินแบบอี้จิงที่เปลี่ยนไปตามตำแหน่ง เช่น มุมของดวงอาทิตย์กับพื้นผิวโลก ในกรณีแบบนี้ ไม่ว่าอย่างไรก็ตาม ปฏิทินสุริยคติ-จันทรคติของเกาหลีเองก็ไม่เคยถูกนำมาถกเถียงด้วยซ้ำ

และสิ่งนั้น ถูกกำหนด โดยสถาบันวิจัยดาราศาสตร์เกาหลี

 
tsboard 2026-03-12

ในที่สุด! สนุกจัง!!

 
shakespeares 2026-03-12

ในที่สุด!!

 
roxie 2026-03-12

ZonedDateTime...? อย่าบอกนะว่าเธอจะ...!

 
sea715 2026-03-12

ในที่สุด

 
click 2026-03-12

จาก time.h ของ C -> java.util.Date ของ Java -> Date ของ js

จาก joda-time ของ Java -> JSR 310 -> java.time
-> moment.js -> Temporal ของ js

ดูเหมือนว่าจะเป็นลำดับการพัฒนาแบบนี้นะ

 
GN⁺ 2026-03-12
ความคิดเห็นบน Hacker News
  • ชอบมากที่ Temporal บังคับให้จัดการกับความซับซ้อนของเวลาอย่างจริงจัง
    การแยกความต่างระหว่าง instant กับ datetime แบบอิงปฏิทินช่วยป้องกันความผิดพลาดที่มักเกิดกับ Date ได้เกือบหมด
    ถึงจะดูยืดเยื้อไปบ้าง แต่ก็ยังดีกว่าถูกเรียกไปแก้บั๊ก DSTตอนตี 3 มาก
    • ถ้าพูดในเชิงเทคนิค งานแก้บั๊ก DST ตอนตี 3 ก็คงแทบจะไม่เกิดนอกจากวันอาทิตย์
  • ผมเองก็ทรมานกับปัญหาการ parse วันที่แบบ ISO8601 ใน Python มาเกือบ10 ปี
    ประเด็นที่เริ่มขึ้นในปี 2012 สุดท้ายก็ได้ทางแก้เข้าไปอยู่ใน standard library
    ดูการถกเถียงที่เกี่ยวข้องได้ในกระทู้ Google Groups นี้
    • ขอบคุณจริงๆ ตอนนี้การ parse วันที่ด้วยวิธีอื่นนอกจาก fromisoformat มันรู้สึกไม่ตรงไปตรงมาเกินไปแล้ว
      เมื่อก่อนผมใช้ ciso8601 แต่พอเข้า standard แล้ว ทุกอย่างก็ง่ายและเสถียรกว่ามาก
  • ที่ Firefox สามารถ implement Temporal ได้ตั้งแต่ยังอยู่ในขั้น spec ก็ต้องยกความดีให้ André Bargull (Anba)
    โดยเฉพาะเมื่อรู้ว่าเขาทำทั้งหมดนี้คนเดียวในฐานะอาสาสมัคร
  • Temporal เป็นก้าวใหญ่ แต่ผมก็ยังไม่ชอบ API นี้อยู่ดี
    ผมแชร์โค้ดระหว่าง client กับ server เลยพยายามแยกข้อมูลออกจาก logic อย่างเข้มงวด
    ผมอยากเก็บข้อมูลทั้งหมดให้เป็น pure JSON เพื่อให้ serialize/deserialize ได้ง่าย แต่ object ของ Temporal เป็น class instance ที่มี property แบบฟังก์ชัน เลยใช้งานลำบาก
    ผมคิดว่าวิธีแบบ date-fns ที่เอา pure function ไปใช้กับ object ที่เป็นข้อมูลล้วนจะดีกว่า
    • นี่เป็นการออกแบบโดยตั้งใจ ประเภทของ Temporal สามารถ serialize ได้ แต่จะไม่ถูก restore อัตโนมัติด้วย JSON.parse
      นักพัฒนาต้องประกอบ object ที่ถูกต้องกลับขึ้นมาเองจากสตริง ISO
      ถ้าทำให้เป็นอัตโนมัติจะมีความเสี่ยงในการจัดการ type ที่ผิด
      ตัวอย่าง Temporal.Instant reviver ในเอกสาร น่าจะช่วยได้
    • ผมก็เจอปัญหาเดียวกันบ่อยมาก การที่ prototype หายไปเพราะ JSON.parse/stringify เป็นเรื่องปกติ
      แต่ผมคิดว่าทีม Temporal ตัดสินใจถูกแล้ว สำหรับ logic เรื่องวันและเวลา type safety สำคัญกว่าวิธีแบบข้อมูล+ฟังก์ชันธรรมดา
      การผูก operation ไว้กับ object ช่วยป้องกันไม่ให้ PlainDate ถูกเผลอจัดการเหมือน ZonedDateTime
      ในที่อย่าง tRPC แค่เพิ่ม layer บางๆ ที่แปลงด้วย Temporal.from() และ toString() ตรงขอบเขตก็พอแล้ว
      จะน่ารำคาญอยู่บ้าง แต่ก็ดีกว่ายอมเสีย type safety ไป
    • จริงๆ แล้ว instance ของ Date ใน JavaScript ก็มีปัญหาเดียวกัน
      Date.toJSON มีอยู่ แต่ตอน parse JSON ก็ยังต้องแปลงสตริงกลับเป็น Date เอง
      Temporal ก็เหมือนกัน และ date-fns เองสุดท้ายก็จัดการกับinstance ของ Date แบบเนทีฟ
    • object ของ Temporal ทุกชนิด serialize/deserialize ได้ง่ายด้วย .toString() และ Temporal.from()
    • ผมคิดว่าการเปลี่ยนให้ JSON.parse สร้าง object ของ Temporal อัตโนมัตินั้นเกินไป
      เช่นเดียวกับ Date
      serialize: instant.toJSON()
      deserialize: Temporal.Instant.from(jsonDate)
      
      ควรจัดการแบบ explicit ลักษณะนี้มากกว่า
  • ดีใจมากที่ Temporal ได้รับการอนุมัติแล้ว
    ขอแสดงความยินดีกับchampionทุกคนที่ทุ่มเทมาอย่างยาวนาน
    ช่วงหลายปีที่ผ่านมา ผมสนุกมากกับการทำงานบน temporal_rs
  • ถ้ามีการพูดถึงเส้นทางการพัฒนา API เวลาของ Java (Joda-Time → JSR 310 → Java 8) ไปด้วยก็น่าจะน่าสนใจ
    เพราะข้อเสนอแบบค่อนข้างพลิกแนวทางเดิมของ JavaScript ออกมาในปี 2018 เลยสงสัยว่าแนวทางของ Java อาจมีอิทธิพลอยู่บ้างไหม
    • น่าจะมองได้ว่า Joda มีอิทธิพลต่อ Moment.js แล้วสิ่งนั้นก็สะท้อนกลับเข้าไปในการถกเถียงของ TC39
      TC39 อ้างอิงแบบอย่างจากภาษาอื่น แต่ก็ตกผลึกเป็นฉันทามติในทิศทางที่เหมาะกับ JavaScript
      ผมคิดว่า API ชุดนี้คือ implementation ที่สมบูรณ์ที่สุดที่ผู้เชี่ยวชาญ JS ออกแบบร่วมกันตลอด 9 ปี
    • ใช่แล้ว JavaScript ก็เคยรับเอาDate เวอร์ชันแย่ๆมาจาก Java เหมือนกัน
      ดูเพิ่มเติมได้ในกระทู้ HN นี้
  • ประโยคที่ว่า “สมัย Mocha Ken Smith พอร์ตโค้ด Date ของ Java มาเป็น C” ฟังแล้วตลกดี
    เพราะ util.Date ของ Java เองก็แทบจะเป็นพอร์ตของ API time.h ใน Cอยู่แล้ว
  • เห็นแล้วขำที่ Safari รองรับ Temporal แค่บางส่วน
    ตอนนี้ Safari ดูเหมือนจะกลายเป็นทายาททางจิตวิญญาณของ IEไปแล้ว
    • Safari เพิ่มฟีเจอร์ใหม่ช้า แต่ก็ยังค่อยๆ implement อย่างต่อเนื่อง
      ปัญหาของ IE ไม่ใช่ความช้า แต่คือการหยุดนิ่งทั้งที่ครองตลาด
      ตอนนี้ Chrome ต่างหากที่อยู่ในตำแหน่งจักรวรรดิ และยิ่งทำให้ Safari กับ Firefox จำเป็นมากขึ้น
      ปัญหาจริงคือการที่เว็บที่ใช้ได้เฉพาะบน Chrome เพิ่มขึ้นเรื่อยๆ
    • ต่อให้ถึงปี 2026 ก็คงยังไม่มีตัวเลือกวันที่แบบเนทีฟบน Safari มือถือ
  • อยากให้ Temporal มีประเภท intervalด้วย
    const D = new Temporal()
    const t = new Interval({minutes:5})
    const v = D.add(t)
    
    • นั่นคือ Duration
      const D = Temporal.PlainDate.from("2020-06-16");
      const t = Temporal.Duration.from({ day: 1 });
      const v = D.add(t) // 2020-06-17
      
      ดูเอกสาร MDN
    • ใช่ นั่นเรียกว่า Duration
  • ขอบคุณทีมที่ทำการเดินทางข้ามเวลาแบบความเร็ว 1xนาน 9 ปีเพื่อสิ่งนี้