Việc lên lịch sự kiện trên nhiều múi giờ là một việc rất khó khăn với đối tượng Date cũ, đặc biệt là trong quá trình chuyển đổi Giờ mùa hè (DST) khi giờ có thể bị bỏ qua hoặc lặp lại.
API Temporal cung cấp Temporal.ZonedDateTime để biểu thị ngày và giờ theo một múi giờ cụ thể, tự động xử lý các chuyển đổi DST và có thể dự đoán được.
Cách triển khai
Cách điều phối các sự kiện toàn cầu và xử lý xung đột tiềm ẩn về giờ mùa hè:
- BẮT BUỘC: Tạo ZonedDateTime: Sử dụng
Temporal.ZonedDateTime.from()để tạo đối tượng ngày giờ có múi giờ. - BẮT BUỘC: Xử lý trường hợp không rõ ràng: Sử dụng tuỳ chọn
disambiguationđể kiểm soát hành vi khi thời gian không rõ ràng hoặc không tồn tại (ví dụ: trong quá trình thay đổi đồng hồ). - BẮT BUỘC: Chuyển đổi múi giờ: Sử dụng
.withTimeZone()để xem giờ tương đương ở một vị trí khác.
Ví dụ: Lập lịch biểu và phát hiện xung đột
// 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' })}`);
Triển khai chiến lược và các phương pháp hay nhất
- NÊN sử dụng
Temporal.ZonedDateTimecho các sự kiện liên quan đến một vị trí địa lý cụ thể (chẳng hạn như cuộc họp ở một thành phố cụ thể). - NÊN sử dụng
disambiguation: 'reject'nếu bạn cần phát hiện và cảnh báo người dùng về xung đột lịch biểu trong quá trình chuyển đổi DST. - NÊN sử dụng
disambiguation: 'compatible'(mặc định) khi bạn muốn hệ thống tự động chọn thời gian hợp lý khi xảy ra xung đột. - KHÔNG sử dụng
Temporal.PlainDateTimecho các sự kiện toàn cầu vì lớp này không chứa thông tin về múi giờ và không thể tính đến các thay đổi về DST. - NÊN sử dụng
.withTimeZone()để tính thời gian tương đương ở các vị trí khác mà không làm thay đổi đối tượng ban đầu (đối tượng Temporal là bất biến). - NÊN sử dụng định dạng
.toLocaleString()gốc (chẳng hạn như{ hour: 'numeric', minute: '2-digit' }) cho màn hình hiển thị thời gian dành cho người dùng thay vì tính toán và đệm thời gian theo cách thủ công.
Chiến lược dự phòng
Phương án dự phòng và hỗ trợ trình duyệt cho Temporal
Đối với các trình duyệt chưa hỗ trợ API Temporal gốc, hãy sử dụng tính năng phát hiện tính năng và tải động temporal-polyfill (~15 KB min+gz).
Xin lưu ý rằng việc nhập temporal-polyfill không tự động chỉ định đối tượng Temporal cho phạm vi toàn cục. Hãy chỉ định rõ ràng nếu mã của bạn dựa vào 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();
})();