การประสานงานกิจกรรมระดับโลกด้วย Temporal

ฟีเจอร์บนเว็บ: Temporal

การกำหนดเวลากิจกรรมในเขตเวลาต่างๆ เป็นเรื่องยากมากเมื่อใช้ออบเจ็กต์ Date เดิม โดยเฉพาะในช่วงการเปลี่ยนผ่านเวลาออมแสง (DST) ที่อาจมีการข้ามหรือทำซ้ำชั่วโมง

Temporal API มี Temporal.ZonedDateTime เพื่อแสดงวันที่และเวลาในเขตเวลาที่เฉพาะเจาะจง โดยจัดการการเปลี่ยนเวลา DST โดยอัตโนมัติและคาดการณ์ได้

วิธีการนำไปใช้งาน

วิธีประสานงานกิจกรรมทั่วโลกและจัดการความขัดแย้งที่อาจเกิดขึ้นเกี่ยวกับ DST

  1. บังคับ: สร้าง ZonedDateTime: ใช้ Temporal.ZonedDateTime.from() เพื่อสร้างออบเจ็กต์วันที่และเวลาที่รับรู้เขตเวลา
  2. บังคับ: จัดการความกำกวม: ใช้ตัวเลือก disambiguation เพื่อควบคุมลักษณะการทำงานเมื่อเวลากำกวมหรือไม่มีอยู่ (เช่น ระหว่างการเปลี่ยนนาฬิกา)
  3. บังคับ: แปลงเขตเวลา: ใช้ .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();
})();