การกำหนดเวลากิจกรรมในเขตเวลาต่างๆ เป็นเรื่องยากมากเมื่อใช้ออบเจ็กต์ Date เดิม โดยเฉพาะในช่วงการเปลี่ยนผ่านเวลาออมแสง (DST) ที่อาจมีการข้ามหรือทำซ้ำชั่วโมง
Temporal API มี Temporal.ZonedDateTime เพื่อแสดงวันที่และเวลาในเขตเวลาที่เฉพาะเจาะจง โดยจัดการการเปลี่ยนเวลา DST โดยอัตโนมัติและคาดการณ์ได้
วิธีการนำไปใช้งาน
วิธีประสานงานกิจกรรมทั่วโลกและจัดการความขัดแย้งที่อาจเกิดขึ้นเกี่ยวกับ DST
- บังคับ: สร้าง ZonedDateTime: ใช้
Temporal.ZonedDateTime.from()เพื่อสร้างออบเจ็กต์วันที่และเวลาที่รับรู้เขตเวลา - บังคับ: จัดการความกำกวม: ใช้ตัวเลือก
disambiguationเพื่อควบคุมลักษณะการทำงานเมื่อเวลากำกวมหรือไม่มีอยู่ (เช่น ระหว่างการเปลี่ยนนาฬิกา) - บังคับ: แปลงเขตเวลา: ใช้
.withTimeZone()เพื่อดูเวลาที่เทียบเท่าในสถานที่อื่น
ตัวอย่าง: การกำหนดเวลาและการตรวจหาความขัดแย้ง
// 1. Define the event time and target time zone
const date = "2025-03-09";
const time = "02:30"; // This time is skipped in New York during Spring Forward
const timeZone = "America/New_York";
const inputStr = `${date}T${time}[${timeZone}]`;
// 2. Detect conflicts using 'reject'
let hasConflict = false;
try {
// 'reject' throws RangeError if the time is ambiguous or does not exist
Temporal.ZonedDateTime.from(inputStr, { disambiguation: 'reject' });
} catch (e) {
if (e instanceof RangeError) {
hasConflict = true;
console.log("This time falls in a DST transition gap or overlap.");
}
}
// 3. Resolve the time safely using 'compatible' (default)
// 'compatible' will resolve to a valid time even if skipped or repeated
const hostTime = Temporal.ZonedDateTime.from(inputStr, { disambiguation: 'compatible' });
console.log(`Resolved time: ${hostTime.toString()}`);
// 4. Convert to another time zone (e.g., Tokyo)
const tokyoTime = hostTime.withTimeZone("Asia/Tokyo");
// Use toLocaleString() for user-facing display instead of manual hour/minute padding
console.log(`Tokyo time: ${tokyoTime.toLocaleString('en-US', { hour: 'numeric', minute: '2-digit' })}`);
การนำไปใช้เชิงกลยุทธ์และแนวทางปฏิบัติแนะนำ
- ควรใช้
Temporal.ZonedDateTimeสำหรับกิจกรรมที่เชื่อมโยงกับสถานที่ตั้งทางภูมิศาสตร์ที่เฉพาะเจาะจง (เช่น การประชุมในเมืองที่เฉพาะเจาะจง) - ควรใช้
disambiguation: 'reject'หากต้องการตรวจจับและเตือนผู้ใช้เกี่ยวกับเวลาที่ทับซ้อนกันระหว่างการเปลี่ยนผ่าน DST - ควรใช้
disambiguation: 'compatible'(ค่าเริ่มต้น) เมื่อต้องการให้ระบบเลือกเวลาที่เหมาะสมโดยอัตโนมัติเมื่อเกิดความขัดแย้ง - อย่าใช้
Temporal.PlainDateTimeสำหรับกิจกรรมทั่วโลก เนื่องจากไม่มีข้อมูลเขตเวลาและไม่สามารถพิจารณาการเปลี่ยนแปลง DST ได้ - ควรใช้
.withTimeZone()เพื่อคำนวณเวลาที่เทียบเท่าในสถานที่อื่นๆ โดยไม่เปลี่ยนแปลงออบเจ็กต์เดิม (ออบเจ็กต์ Temporal เปลี่ยนแปลงไม่ได้) - ควรใช้การจัดรูปแบบ
.toLocaleString()แบบเนทีฟ (เช่น{ hour: 'numeric', minute: '2-digit' }) สำหรับการแสดงเวลาต่อผู้ใช้แทนการคำนวณเวลาและการเติมด้วยตนเอง
กลยุทธ์สำรอง
เบราว์เซอร์ที่รองรับและทางเลือกสำรองสำหรับ Temporal
สำหรับเบราว์เซอร์ที่ยังไม่รองรับ Temporal API แบบเนทีฟ ให้ใช้การตรวจหาฟีเจอร์และโหลด temporal-polyfill แบบไดนามิก (~15 KB min+gz)
โปรดทราบว่าการนำเข้า temporal-polyfill จะไม่กำหนดออบเจ็กต์ Temporal ให้กับขอบเขตส่วนกลางโดยอัตโนมัติ กำหนดอย่างชัดเจนหากโค้ดของคุณใช้ globalThis.Temporal
// Check if Temporal is supported natively
(async () => {
if (typeof Temporal === 'undefined') {
// Load the polyfill conditionally
const module = await import('https://esm.sh/temporal-polyfill');
globalThis.Temporal = module.Temporal;
// Extend Date.prototype if needed
Date.prototype.toTemporalInstant = module.toTemporalInstant;
}
initializeApp();
})();