Hầu như bất kỳ loại ứng dụng nào được viết bằng JavaScript đều hoạt động với thời gian hoặc ngày tháng ở một mức độ nào đó. Ban đầu, điều này được giới hạn ở API ngày tích hợp. API này bao gồm chức năng cơ bản nhưng khá hạn chế về những gì nó có thể làm. Các thư viện của bên thứ ba như Moment.js và các API tích hợp sau này như API quốc tế và API tạm thời mới, tăng thêm tính linh hoạt cao hơn nhiều khi làm việc với thời gian và ngày tháng. Sự trỗi dậy và sụp đổ của Moment.js Moment.js là một thư viện JavaScript với các tiện ích mạnh mẽ để làm việc với ngày và giờ. Nó bao gồm các tính năng còn thiếu từ API ngày cơ bản, chẳng hạn như thao tác múi giờ và làm cho nhiều thao tác phổ biến trở nên đơn giản hơn. Khoảnh khắc cũng bao gồm các chức năng định dạng ngày và giờ. Nó đã trở thành một thư viện được sử dụng rộng rãi trong nhiều ứng dụng khác nhau. Tuy nhiên, Moment cũng có một số vấn đề. Đó là một thư viện lớn và có thể bổ sung đáng kể kích thước gói của ứng dụng. Vì thư viện không hỗ trợ rung cây (một tính năng của các gói hiện đại có thể loại bỏ những phần không sử dụng của thư viện), toàn bộ thư viện Moment sẽ được đưa vào ngay cả khi bạn chỉ sử dụng một hoặc hai chức năng của nó. Một vấn đề khác với Moment là các đối tượng mà nó tạo ra có thể thay đổi được. Việc gọi một số hàm nhất định trên đối tượng Moment có tác dụng phụ và làm thay đổi giá trị của đối tượng đó. Điều này có thể dẫn đến hành vi hoặc lỗi không mong muốn. Vào năm 2020, những người bảo trì Moment đã quyết định đưa thư viện vào chế độ bảo trì. Không có sự phát triển tính năng mới nào được thực hiện và những người bảo trì khuyến nghị không nên sử dụng nó cho các dự án mới. Có các thư viện ngày tháng JavaScript khác, chẳng hạn như date-fns, nhưng có một trình phát mới trong thị trấn, một API được tích hợp trực tiếp vào JavaScript: Temporal. Đó là một tiêu chuẩn mới giúp lấp đầy các lỗ hổng của API ngày gốc cũng như giải quyết một số hạn chế có trong Moment và các thư viện khác. Thời gian là gì? Temporal là API ngày và giờ mới được thêm vào tiêu chuẩn ECMAScript, định nghĩa JavaScript hiện đại. Tính đến tháng 3 năm 20266, nó đã đạt đến Giai đoạn 4 của quy trình TC39 (ủy ban giám sát các đề xuất và bổ sung cho ngôn ngữ JavaScript) và sẽ được đưa vào phiên bản tiếp theo của đặc tả ECMAScript. Nó đã được triển khai trên một số trình duyệt: Chrome 144+ và Firefox 139+, dự kiến ​​Safari sẽ sớm ra mắt. Một polyfill cũng có sẵn cho các trình duyệt và Node.js không được hỗ trợ. API tạm thời tạo các đối tượng nói chung đại diện cho các khoảnh khắc. Đây có thể là tem ngày và toàn thời gian trong một múi giờ nhất định hoặc chúng có thể là phiên bản chung của thời gian “đồng hồ treo tường” mà không có bất kỳ thông tin về múi giờ hoặc ngày nào. Một số tính năng chính của Temporal bao gồm:

Thời gian có hoặc không có ngày. Đối tượng tạm thời có thể biểu thị thời gian cụ thể trong một ngày cụ thể hoặc thời gian không có bất kỳ thông tin ngày nào. Một ngày cụ thể, không có thời gian, cũng có thể được trình bày. Hỗ trợ múi giờ. Các đối tượng tạm thời hoàn toàn nhận biết múi giờ và có thể được chuyển đổi qua các múi giờ khác nhau. Khoảnh khắc cũng hỗ trợ các múi giờ, nhưng nó yêu cầu thư viện múi giờ bổ sung. Tính bất biến. Khi một đối tượng Temporal được tạo, nó không thể thay đổi được. Chuyển đổi số học hoặc múi giờ thời gian không sửa đổi đối tượng cơ bản. Thay vào đó, chúng tạo ra một đối tượng Temporal mới. Lập chỉ mục dựa trên 1. Một nguồn lỗi phổ biến với Date API (cũng như với Moment) là các tháng không được lập chỉ mục. Điều này có nghĩa là tháng 1 là tháng 0 chứ không phải tháng 1 như chúng ta đều hiểu trong đời thực. Tạm thời khắc phục điều này bằng cách sử dụng lập chỉ mục dựa trên 1 — Tháng 1 là tháng 1. Nó được tích hợp sẵn trong trình duyệt. Vì Temporal là một API trong chính trình duyệt nên nó không bổ sung gì vào kích thước gói ứng dụng của bạn.

Điều quan trọng cần lưu ý là Date API sẽ không biến mất. Mặc dù Temporal thay thế API này nhưng nó không bị xóa hoặc không được dùng nữa. Nhiều ứng dụng sẽ bị hỏng nếu trình duyệt đột nhiên loại bỏ Date API. Tuy nhiên, cũng nên nhớ rằng Moment hiện được coi là một dự án cũ ở chế độ bảo trì. Trong phần còn lại của bài viết, chúng ta sẽ xem xét một số “công thức” để di chuyển mã dựa trên Khoảnh khắc sang API tạm thời mới. Hãy bắt đầu tái cấu trúc! Tạo đối tượng ngày và giờ Trước khi có thể thao tác ngày và giờ, chúng ta phải tạo các đối tượng đại diện cho chúng. Để tạo đối tượng Moment biểu thị ngày và giờ hiện tại, hãy sử dụng hàm moment. const bây giờ = khoảnh khắc(); console.log(bây giờ); // Khoảnh khắc<2026-02-18T21:26:29-05:00>

Đối tượng này bây giờ có thể được định dạng hoặc thao tác khi cần thiết.

// chuyển đổi sang UTC //cảnh báo: Điều này làm thay đổi đối tượng Moment và đặt nó ở chế độ UTC! console.log(now.utc()); // Khoảnh khắc<2026-02-19T02:26:29Z>

// in một chuỗi được định dạng - lưu ý rằng hiện tại nó đang sử dụng thời gian UTC console.log(now.format('MM/DD/YYYY hh:mm:ss a')); // 19/02/2026 02:27:07 sáng

Điều quan trọng cần nhớ về Moment là đối tượng Moment luôn bao gồm thông tin về ngày và giờ. Nếu bạn chỉ cần làm việc với thông tin thời gian, điều này thường ổn nhưng có thể gây ra hành vi không mong muốn trong các tình huống như Giờ tiết kiệm ánh sáng ban ngày hoặc năm nhuận, trong đó ngày có thể ảnh hưởng đến việc tính toán thời gian. Thời gian linh hoạt hơn. Bạn có thể tạo một đối tượng biểu thị ngày và giờ hiện tại bằng cách tạo đối tượng Temporal.Instant. Điều này thể hiện một thời điểm được xác định theo thời gian kể từ “kỷ nguyên” (nửa đêm UTC ngày 1 tháng 1 năm 1970). Temporal có thể tham chiếu thời điểm này với độ chính xác ở mức nano giây. const now = Temporal.Now.instant();

// xem nano giây thô kể từ Kỷ nguyên console.log(now.epochNanoseconds); // 1771466342612000000n

// định dạng cho UTC console.log(now.toString()); // 2026-02-19T01:55:27.844Z

// định dạng cho một múi giờ cụ thể console.log(now.toString({ timeZone: 'America/New_York' })); // 2026-02-18T20:56:57.905-05:00

Các đối tượng Temporal.Instant cũng có thể được tạo trong một ngày và giờ cụ thể bằng cách sử dụng phương thức tĩnh.

const myInstant = Temporal.Instant.from('2026-02-18T21:10:00-05:00');

// Định dạng tức thời theo múi giờ địa phương. Lưu ý rằng điều này chỉ kiểm soát // định dạng - nó không làm thay đổi đối tượng như moment.utc. console.log(myInstant.toString({ timeZone: 'America/New_York' })); // 2026-02-18T21:10:00-05:00

Bạn cũng có thể tạo các loại đối tượng Thời gian khác, bao gồm:

Temporal.PlainDate: Ngày không có thông tin về thời gian. Temporal.PlainTime: Thời gian không có thông tin về ngày tháng. Temporal.ZonedDateTime: Ngày và giờ ở một múi giờ cụ thể.

Mỗi trong số này có một phương thức from có ​​thể được gọi với một đối tượng chỉ định ngày và/hoặc thời gian hoặc một chuỗi ngày để phân tích cú pháp. // Chỉ là một cuộc hẹn hò thôi const hôm nay = Temporal.PlainDate.from({ năm: 2026, tháng: 2, // lưu ý chúng tôi đang sử dụng 2 cho tháng 2 ngày: 18 }); console.log(today.toString()); // 2026-02-18

// Chỉ một thời gian thôi const LunchTime = Temporal.PlainTime.from({ giờ: 12 }); console.log(lunchTime.toString()); // 12:00:00

// Ngày và giờ theo múi giờ Miền Đông Hoa Kỳ const doAt = Temporal.ZonedDateTime.from({ múi giờ: 'Mỹ/New_York', năm: 2026, tháng: 3, ngày: 1, giờ: 12, phút: 0, giây: 0 }); console.log(dueAt.toString()); // 2026-03-01T12:00:00-05:00[America/New_York]

Phân tích cú pháp Chúng tôi đã đề cập đến việc tạo thông tin ngày và giờ theo chương trình. Bây giờ chúng ta hãy xem phân tích cú pháp. Phân tích cú pháp là một lĩnh vực trong đó Moment linh hoạt hơn API tạm thời tích hợp sẵn. Bạn có thể phân tích chuỗi ngày tháng bằng cách chuyển nó tới hàm thời điểm. Với một đối số duy nhất, Moment mong đợi một chuỗi ngày ISO nhưng bạn có thể sử dụng các định dạng thay thế nếu bạn cung cấp đối số thứ hai chỉ định định dạng ngày đang được sử dụng.

const isoDate = khoảnh khắc('2026-02-21T09:00:00'); const formattedDate = moment('21/2/26 9:00:00', 'M/D/YY h:mm:ss');

console.log(isoDate); // Khoảnh khắc<2026-02-21T09:00:00-05:00>

console.log(formattedDate); // Khoảnh khắc<2026-02-21T09:00:00-05:00>

Trong các phiên bản cũ hơn, Moment sẽ đưa ra dự đoán tốt nhất để phân tích bất kỳ chuỗi ngày được định dạng tùy ý nào. Điều này có thể dẫn đến kết quả không thể đoán trước. Ví dụ: 02-03-2026 là ngày 2 tháng 2 hay ngày 3 tháng 3? Vì lý do này, các phiên bản mới hơn của Moment hiển thị cảnh báo không dùng nữa nếu nó được gọi mà không có chuỗi ngày được định dạng ISO (trừ khi đối số thứ hai có định dạng mong muốn cũng được cung cấp). Temporal sẽ chỉ phân tích chuỗi ngày được định dạng cụ thể. Chuỗi phải tuân thủ định dạng ISO 8601 hoặc phần mở rộng của nó, RFC 9557. Nếu một chuỗi ngày không tuân thủ được chuyển đến phương thức from, Temporal sẽ đưa ra RangeError.

// Sử dụng chuỗi ngày RFC 9557 const myDate = Temporal.Instant.from('2026-02-21T09:00:00-05:00[America/New_York]'); console.log(myDate.toString({ timeZone: 'America/New_York' })); // 2026-02-21T09:00:00-05:00

// Sử dụng chuỗi ngày không xác định const otherDate = Temporal.Instant.from('21/2/26 9:00:00'); // RangeError: Lỗi tạm thời: Ký tự không hợp lệ khi phân tích giá trị năm.

Các yêu cầu chính xác của chuỗi ngày phụ thuộc vào loại đối tượng Thời gian mà bạn đang tạo. Trong ví dụ trên, Temporal.Instant yêu cầu ISO đầy đủ8601 hoặc RFC 9557 chỉ định ngày và giờ với chênh lệch múi giờ, nhưng bạn cũng có thể tạo các đối tượng PlainDate hoặc PlainTime chỉ bằng một tập hợp con của định dạng ngày. const myDate = Temporal.PlainDate.from('2026-02-21'); console.log(myDate.toString()); // 2026-02-21

const myTime = Temporal.PlainTime.from('09:00:00'); console.log(myTime.toString()); // 09:00:00

Lưu ý rằng các chuỗi này vẫn phải tuân theo định dạng dự kiến, nếu không sẽ xảy ra lỗi.

// Sử dụng chuỗi thời gian không tuân thủ. Tất cả những thứ này sẽ gây ra RangeError. Temporal.PlainTime.from('9:00'); Temporal.PlainTime.from('9:00:00 AM');

Mẹo chuyên nghiệp: Xử lý các chuỗi không phải ISO Vì Temporal ưu tiên độ tin cậy nên nó sẽ không cố đoán định dạng của chuỗi như 02-01-2026. Nếu nguồn dữ liệu của bạn sử dụng các chuỗi như vậy, bạn sẽ cần thực hiện một số thao tác chuỗi để sắp xếp lại các giá trị thành chuỗi ISO như 2026-02-01 trước khi thử sử dụng chuỗi đó với Temporal.

Định dạng Khi bạn có một đối tượng Khoảnh khắc hoặc Thời gian, có thể bạn sẽ muốn chuyển đổi nó thành một chuỗi được định dạng tại một số điểm. Đây là một ví dụ trong đó Moment ngắn gọn hơn một chút. Bạn gọi phương thức định dạng của đối tượng bằng một chuỗi mã thông báo mô tả định dạng ngày mong muốn. const ngày = khoảnh khắc();

console.log(date.format('MM/DD/YYYY')); // 22/02/2026

console.log(date.format('MMMM Làm YYYY, h:mm:ss a')); // Ngày 22 tháng 2 năm 2026, 8:18:30 chiều

Mặt khác, Temporal yêu cầu bạn phải dài dòng hơn một chút. Các đối tượng tạm thời, chẳng hạn như Instant, có phương thức toLocaleString chấp nhận các tùy chọn định dạng khác nhau được chỉ định làm thuộc tính của một đối tượng.

const date = Temporal.Now.instant();

// không có đối số, chúng ta sẽ nhận được định dạng mặc định cho ngôn ngữ hiện tại console.log(date.toLocaleString()); // 22/2/2026, 8:23:36 PM (giả sử ngôn ngữ là en-US)

// chuyển các tùy chọn định dạng để tạo chuỗi định dạng tùy chỉnh console.log(date.toLocaleString('en-US', { tháng: 'dài', ngày: 'số', năm: 'số', giờ: '2 chữ số', phút: '2 chữ số' })); // Ngày 22 tháng 2 năm 2026 lúc 8:23 tối

// chỉ truyền các trường bạn muốn trong chuỗi định dạng console.log(date.toLocaleString('en-US', { tháng: 'ngắn', ngày: 'số' })); // ngày 22 tháng 2

Định dạng ngày tạm thời thực sự sử dụng API Intl.DateTimeFormat (đã có sẵn trong các trình duyệt hiện đại). Điều đó có nghĩa là bạn có thể tạo một đối tượng DateTimeFormat có thể tái sử dụng bằng các tùy chọn định dạng tùy chỉnh của mình, sau đó chuyển các đối tượng Temporal vào phương thức định dạng của nó. Do đó, nó không hỗ trợ các định dạng ngày tùy chỉnh như Moment. Nếu bạn cần định dạng như 'Q1 2026' hoặc định dạng chuyên biệt khác, bạn có thể cần một số mã định dạng ngày tùy chỉnh hoặc liên hệ với thư viện của bên thứ ba. const formatter = new Intl.DateTimeFormat('en-US', { tháng: '2 chữ số', ngày: '2 chữ số', năm: 'số' });

const date = Temporal.Now.instant(); console.log(formatter.format(date)); // 22/02/2026

Mã thông báo định dạng của Moment viết đơn giản hơn nhưng không thân thiện với ngôn ngữ. Các chuỗi định dạng “mã cứng” như thứ tự tháng/ngày. Ưu điểm của việc sử dụng một đối tượng cấu hình, như Temporal, là nó sẽ tự động thích ứng với bất kỳ ngôn ngữ nào và sử dụng định dạng chính xác. const date = Temporal.Now.instant();

tùy chọn định dạng const = { tháng: 'số', ngày: 'số', năm: 'số' };

console.log(date.toLocaleString('en-US', formatOptions)); // 22/2/2026

console.log(date.toLocaleString('en-GB', formatOptions)); // 22/02/2026

Tính toán ngày Trong nhiều ứng dụng, bạn sẽ cần phải thực hiện một số phép tính vào một ngày. Bạn có thể muốn thêm hoặc bớt các đơn vị thời gian (ngày, giờ, giây, v.v.). Ví dụ: nếu bạn có ngày hiện tại, bạn có thể muốn hiển thị cho người dùng ngày sau 1 tuần nữa. Các đối tượng khoảnh khắc có các phương thức như cộng và trừ để thực hiện các thao tác này. Các hàm này nhận một giá trị và một đơn vị, ví dụ: add(7, 'days'). Tuy nhiên, một điểm khác biệt rất quan trọng giữa Khoảnh khắc và Thời gian là khi thực hiện các phép tính ngày này, đối tượng cơ bản sẽ bị sửa đổi và giá trị ban đầu của nó bị mất. const bây giờ = khoảnh khắc();

console.log(bây giờ); // Khoảnh khắc<2026-02-24T20:08:36-05:00>

const nextWeek = now.add(7, 'ngày'); console.log(nextWeek); // Khoảnh khắc<2026-03-03T20:08:36-05:00>

// Gotcha - đối tượng ban đầu đã bị đột biến console.log(bây giờ); // Khoảnh khắc<2026-03-03T20:08:36-05:00>

Để tránh mất ngày gốc, bạn có thể gọi clone trên đối tượng Moment để tạo bản sao. const bây giờ= khoảnh khắc(); const nextWeek = now.clone().add(7, 'days');

console.log(bây giờ); // Khoảnh khắc<2026-02-24T20:12:55-05:00>

console.log(nextWeek); // Khoảnh khắc<2026-03-03T20:12:55-05:00>

Mặt khác, các đối tượng tạm thời là bất biến. Khi bạn đã tạo một đối tượng như Instant, PlainDate, v.v., giá trị của đối tượng đó sẽ không bao giờ thay đổi. Các đối tượng thời gian cũng có các phương thức cộng và trừ. Temporal hơi kén chọn về đơn vị thời gian nào có thể được thêm vào loại đối tượng nào. Ví dụ: bạn không thể thêm ngày vào Instant:

const now = Temporal.Now.instant(); const nextWeek = now.add({ ngày: 7 }); // RangeError: Lỗi tạm thời: Đơn vị lớn nhất không thể là đơn vị ngày

Điều này là do các đối tượng Instant đại diện cho một thời điểm cụ thể trong UTC và không phụ thuộc vào lịch. Vì độ dài của một ngày có thể thay đổi dựa trên các quy tắc múi giờ chẳng hạn như Giờ tiết kiệm ánh sáng ban ngày nên tính toán này không khả dụng ngay lập tức. Tuy nhiên, bạn có thể thực hiện thao tác này trên các loại đối tượng khác, chẳng hạn như PlainDateTime: const now = Temporal.Now.plainDateTimeISO(); console.log(now.toLocaleString()); // 24/2/2026, 8:23:59 CH

const nextWeek = now.add({ ngày: 7 });

// Lưu ý rằng PlainDateTime ban đầu không thay đổi console.log(now.toLocaleString()); // 24/2/2026, 8:23:59 CH

console.log(nextWeek.toLocaleString()); // 3/3/2026, 8:23:59 CH

Bạn cũng có thể tính toán khoảng thời gian giữa hai đối tượng Khoảnh khắc hoặc Thời gian. Với chức năng khác biệt của Moment, bạn cần cung cấp đơn vị cho mức độ chi tiết, nếu không nó sẽ trả về chênh lệch tính bằng mili giây. const date1 = khoảnh khắc('2026-02-21T09:00:00'); const date2 = khoảnh khắc('2026-02-22T10:30:00');

console.log(date2.diff(date1)); // 91800000

console.log(date2.diff(date1, 'ngày')); // 1

Để thực hiện điều này với một đối tượng Temporal, bạn có thể truyền một đối tượng Temporal khác cho các phương thức của nó. Điều này trả về một đối tượng Temporal.Duration chứa thông tin về chênh lệch thời gian. Đối tượng Thời lượng có các thuộc tính cho từng thành phần của chênh lệch và cũng có thể tạo chuỗi thời lượng theo tiêu chuẩn ISO 8601 biểu thị chênh lệch thời gian.

const date1 = Temporal.PlainDateTime.from('2026-02-21T09:00:00'); const date2 = Temporal.PlainDateTime.from('2026-02-22T10:30:00');

// lớn nhấtUnit chỉ định đơn vị thời gian lớn nhất để biểu thị // trong tính toán thời lượng const diff = date2.since(date1, { lớn nhấtUnit: 'ngày' });

console.log(diff.days); // 1

console.log(diff.hours); // 1

console.log(diff.phút); // 30

console.log(diff.toString()); // P1DT1H30M // (Chuỗi thời lượng ISO 8601: 1 ngày, 1 giờ, 30 phút)

So sánh ngày và giờ Cả Khoảnh khắc và Thời gian đều cho phép bạn so sánh ngày và giờ để xác định ngày và giờ nào đến trước ngày kia, nhưng thực hiện các cách tiếp cận khác nhau với API. Moment cung cấp các phương thức như isBefore, isAfter và isSame để so sánh hai đối tượng Moment. const date1 = khoảnh khắc('2026-02-21T09:00:00'); const date2 = khoảnh khắc('2026-02-22T10:30:00');

console.log(date1.isBefore(date2)); // đúng

Temporal sử dụng phương pháp so sánh tĩnh để thực hiện so sánh giữa hai đối tượng cùng loại. Nó trả về -1 nếu ngày đầu tiên đến trước ngày thứ hai, 0 nếu chúng bằng nhau hoặc 1 nếu ngày đầu tiên đến sau ngày thứ hai. Ví dụ sau đây cho thấy cách so sánh hai đối tượng PlainDate. Cả hai đối số của Temporal.PlainDate.compare đều phải là đối tượng PlainDate.

const date1 = Temporal.PlainDate.from({ năm: 2026, tháng: 2, ngày: 24 }); const date2 = Temporal.PlainDate.from({ năm: 2026, tháng: 3, ngày: 24 });

// date1 đến trước date2, vì vậy -1 console.log(Temporal.PlainDate.compare(date1, date2));

// Lỗi nếu chúng ta cố so sánh hai đối tượng có kiểu khác nhau console.log(Temporal.PlainDate.compare(date1, Temporal.Now.instant())); // TypeError: Lỗi tạm thời: Các trường PlainDate được cung cấp không hợp lệ.

Đặc biệt, điều này giúp bạn dễ dàng sắp xếp một mảng các đối tượng Thời gian theo trình tự thời gian. // Một mảng các đối tượng Temporal.PlainDate const ngày = [ ... ];

// sử dụng Temporal.PlainDate.compare làm hàm so sánh date.sort(Temporal.PlainDate.compare);

Chuyển đổi múi giờ Thư viện Khoảnh khắc cốt lõi không hỗ trợ chuyển đổi múi giờ. Nếu cần chức năng này, bạn cũng cần cài đặt gói moment-timezone. Gói này không thể rung cây và do đó có thể tăng đáng kể kích thước gói của bạn. Sau khi cài đặt múi giờ khoảnh khắc, bạn có thể chuyển đổi các đối tượng Moment sang các múi giờ khác nhau bằng phương thức tz. Giống như các hoạt động Khoảnh khắc khác, điều này làm thay đổi cơ bảnsự vật. // Giả sử giờ miền Đông Hoa Kỳ const bây giờ = khoảnh khắc(); console.log(bây giờ); // Khoảnh khắc<2026-02-28T20:08:20-05:00>

// Chuyển đổi sang giờ Thái Bình Dương. // Giờ miền Đông ban đầu bị mất. now.tz('America/Los_Angeles'); console.log(bây giờ); // Khoảnh khắc<2026-02-28T17:08:20-08:00>

Chức năng múi giờ được tích hợp vào API tạm thời khi sử dụng đối tượng Temporal.ZonedDateTime. Các đối tượng này bao gồm một phương thức withTimeZone trả về một ZonedDateTime mới biểu thị cùng một thời điểm nhưng trong múi giờ đã chỉ định. // Một lần nữa, giả sử giờ miền Đông Hoa Kỳ const now = Temporal.Now.zonedDateTimeISO(); console.log(now.toLocaleString()); // 28/2/2026, 8:12:02 CH EST

// Chuyển đổi sang giờ Thái Bình Dương const nowPacific = now.withTimeZone('America/Los_Angeles'); console.log(nowPacific.toLocaleString()); // 28/2/2026, 5:12:02 chiều theo giờ Thái Bình Dương

// Đối tượng ban đầu không thay đổi console.log(now.toLocaleString()); // 28/2/2026, 8:12:02 CH EST

Lưu ý: Các giá trị được định dạng được trả về bởi toLocaleString, như tên ngụ ý, phụ thuộc vào miền địa phương. Mã mẫu được phát triển bằng ngôn ngữ en-US nên có định dạng như sau: 28/2/2026, 5:12:02 PM PST. Ở một địa phương khác, điều này có thể khác. Ví dụ: trong ngôn ngữ en-GB, bạn sẽ nhận được thông tin như 28/2/2026, 17:12:02 GMT-8. Tái cấu trúc trong thế giới thực Giả sử chúng ta đang xây dựng một ứng dụng để lên lịch sự kiện theo các múi giờ. Một phần của ứng dụng này là một hàm, getEventTimes, lấy chuỗi ISO 8601 biểu thị ngày và giờ của sự kiện, múi giờ địa phương và múi giờ mục tiêu. Hàm tạo chuỗi ngày và giờ được định dạng cho sự kiện ở cả hai múi giờ. Nếu hàm được cung cấp một chuỗi đầu vào không phải là chuỗi ngày/giờ hợp lệ thì hàm đó sẽ báo lỗi. Đây là cách triển khai ban đầu, sử dụng Moment (cũng yêu cầu sử dụng gói moment-timezone).

nhập khoảnh khắc từ 'moment-timezone';

hàm getEventTimes(inputString, userTimeZone, targetTimeZone) { const timeFormat = 'MMM D, YYYY, h:mm:ss a z';

// 1. Tạo thời điểm ban đầu theo múi giờ của người dùng const sự kiệnTime = khoảnh khắc.tz( chuỗi đầu vào, moment.ISO_8601, // Yêu cầu chuỗi ISO 8601 đúng, // Phân tích cú pháp nghiêm ngặt người dùngTimeZone );

// Đưa ra lỗi nếu inputString không thể hiện ngày hợp lệ if (!eventTime.isValid()) { đưa ra Lỗi mới ('Đầu vào ngày/giờ không hợp lệ'); }

// 2. Tính thời gian mục tiêu // QUAN TRỌNG: Chúng ta phải sao chép, nếu không 'eventTime' sẽ thay đổi mãi mãi! const targetTime = eventTime.clone().tz(targetTimeZone);

trở về { cục bộ: eventTime.format(timeFormat), mục tiêu: targetTime.format(timeFormat), }; }

lịch trình const = getEventTimes( '2026-03-05T15:00-05:00', 'Mỹ/New_York', 'Châu Âu/Luân Đôn', );

console.log(lịch trình.local); // Ngày 5 tháng 3 năm 2026, 3:00:00 chiều giờ EST

console.log(lịch trình.target); // Ngày 5 tháng 3 năm 2026, 8:00:00 tối GMT

Trong ví dụ này, chúng tôi đang sử dụng định dạng ngày dự kiến là ISO 8601, được tích hợp hữu ích vào Moment. Chúng tôi cũng đang sử dụng tính năng phân tích cú pháp nghiêm ngặt, có nghĩa là Moment sẽ không cố gắng đoán bằng chuỗi ngày không khớp với định dạng. Nếu một chuỗi ngày không phải ISO được chuyển, nó sẽ dẫn đến một đối tượng ngày không hợp lệ và chúng tôi sẽ đưa ra lỗi. Việc triển khai tạm thời trông tương tự nhưng có một vài điểm khác biệt chính.

hàm getEventTimes(inputString, userTimeZone, targetTimeZone) { // 1. Phân tích cú pháp đầu vào trực tiếp thành Instant, sau đó tạo // a ZonedDateTime trong vùng của người dùng. const instant = Temporal.Instant.from(inputString); const eventTime = instant.toZonedDateTimeISO(userTimeZone);

// 2. Chuyển đổi sang vùng mục tiêu // Điều này tự động trả về một đối tượng MỚI; 'eventTime' là an toàn. const targetTime = eventTime.withTimeZone(targetTimeZone);

// 3. Định dạng bằng Intl (tích hợp sẵn) tùy chọn const = { năm: 'số', tháng: 'ngắn', ngày: 'số', giờ: 'số', phút: '2 chữ số', thứ hai: '2 chữ số', timeZoneName: 'ngắn' };

trở về { địa phương: eventTime.toLocaleString(navigator.lingu, options), mục tiêu: targetTime.toLocaleString(navigator.lingu, options) }; }

lịch trình const = getEventTimes( '2026-03-05T15:00-05:00', 'Mỹ/New_York', 'Châu Âu/Luân Đôn', );

console.log(lịch trình.local); // Ngày 5 tháng 3 năm 2026, 3:00:00 chiều giờ EST

console.log(lịch trình.target); // Ngày 5 tháng 3 năm 2026, 8:00:00 tối GMT

Với Moment, chúng ta phải chỉ định rõ ràng chuỗi định dạng cho chuỗi ngày kết quả. Bất kể vị trí hoặc ngôn ngữ của người dùng, thời gian sự kiện sẽ luôn được định dạng là ngày 5 tháng 3 năm 2026, 3:00:00chiều giờ EST. Ngoài ra, chúng ta không cần phải đưa ra một ngoại lệ một cách rõ ràng. Nếu một chuỗi không hợp lệ được chuyển đến Temporal.Instant.from, Temporal sẽ đưa ra ngoại lệ cho chúng ta. Một điều cần lưu ý là ngay cả khi phân tích cú pháp nghiêm ngặt, phiên bản Moment vẫn nhẹ nhàng hơn. Temporal yêu cầu bù múi giờ ở cuối chuỗi. Bạn cũng nên lưu ý rằng vì chúng tôi đang sử dụng navigator.lingu, mã này sẽ chỉ chạy trong môi trường trình duyệt, vì navigator không được xác định trong môi trường Node.js. Việc triển khai Tạm thời sử dụng ngôn ngữ hiện tại của trình duyệt (navigator.lingu), do đó, người dùng sẽ tự động nhận được thời gian sự kiện được định dạng theo định dạng giờ địa phương của họ. Ở ngôn ngữ en-US, đây là ngày 5 tháng 3 năm 2026, 3:00:00 chiều EST. Tuy nhiên, ví dụ: nếu người dùng ở Luân Đôn thì thời gian sự kiện sẽ được định dạng là ngày 5 tháng 3 năm 2026, 15:00:00 GMT-5. Tóm tắt

hành động Khoảnh khắc.js tạm thời thời gian hiện tại khoảnh khắc() Temporal.Now.zonedDateTimeISO() Phân tích ISO khoảnh khắc(str) Tạm thời.Instant.from(str) Thêm thời gian .add(7, 'ngày') (đột biến) .add({ ngày: 7 }) (đối tượng mới) Sự khác biệt .diff(khác, 'giờ') .since(other).hours Múi giờ .tz('Vùng/Tên') .withTimeZone('Vùng/Tên')

Thoạt nhìn, sự khác biệt có thể hơi khác một chút (và trong trường hợp cú pháp Temporal, đôi khi dài dòng hơn và nghiêm ngặt hơn), nhưng có một số lợi thế chính khi sử dụng Temporal thay vì Moment.js:

Rõ ràng hơn có nghĩa là ít bất ngờ hơn và ít lỗi ngoài ý muốn hơn. Khoảnh khắc có vẻ nhẹ nhàng hơn nhưng nó liên quan đến việc “phỏng đoán”, đôi khi có thể dẫn đến ngày tháng không chính xác. Nếu bạn cung cấp cho Temporal một cái gì đó không hợp lệ, nó sẽ báo lỗi. Nếu mã chạy, bạn biết bạn đã có ngày hợp lệ. Khoảnh khắc có thể thêm kích thước đáng kể vào gói của ứng dụng, đặc biệt nếu bạn đang sử dụng gói múi giờ. Temporal không thêm gì cả (sau khi nó được chuyển đến trình duyệt mục tiêu của bạn). Tính bất biến mang lại cho bạn sự tự tin rằng bạn sẽ không bao giờ mất hoặc ghi đè dữ liệu khi thực hiện các thao tác và chuyển đổi ngày. Các cách biểu thị thời gian khác nhau (Instant, PlainDateTime, ZonedDateTime) tùy thuộc vào yêu cầu của bạn, trong đó Khoảnh khắc luôn là lớp bao quanh dấu thời gian UTC. Temporal sử dụng API quốc tế để định dạng ngày, có nghĩa là bạn có thể có định dạng nhận biết ngôn ngữ mà không cần phải chỉ định rõ ràng mã thông báo.

Ghi chú về Polyfill Như đã đề cập trước đó, có sẵn một Temporal polyfill, được phân phối dưới dạng gói npm có tên @js-temporal/polyfill. Nếu muốn sử dụng Temporal ngay hôm nay, bạn sẽ cần polyfill này để hỗ trợ các trình duyệt như Safari chưa cung cấp API. Tin xấu với điều này là nó sẽ làm tăng kích thước gói của bạn. Tin tốt là nó vẫn cộng ít hơn đáng kể so với thời điểm hoặc múi giờ thời điểm. Dưới đây là so sánh kích thước gói theo báo cáo của Bundlephobia.com, một trang web trình bày thông tin về kích thước gói npm (nhấp vào từng tên gói để xem phân tích Bundlephobia):

Gói Giảm thiểu Giảm thiểu và nén @js-temporal/polyfill 154,1 kB 44,1 kB khoảnh khắc 294,4 kB 75,4 kB múi giờ 1 MB 114,2 kB

Polyfill trước đây cũng có một số vấn đề về hiệu suất xung quanh việc sử dụng bộ nhớ và tại thời điểm viết bài, nó được coi là ở trạng thái alpha. Vì điều này, bạn có thể không muốn sử dụng nó trong sản xuất cho đến khi nó đạt đến trạng thái trưởng thành hơn. Tin tốt khác là hy vọng polyfill sẽ không cần thiết lâu hơn nữa (tất nhiên trừ khi bạn cần hỗ trợ các trình duyệt cũ hơn). Tại thời điểm viết bài, Temporal đã có mặt trên Chrome, Edge và Firefox. Nó chưa hoàn toàn sẵn sàng trong Safari, mặc dù nó dường như có sẵn cờ thời gian chạy trên Bản xem trước công nghệ mới nhất.

You May Also Like

Enjoyed This Article?

Get weekly tips on growing your audience and monetizing your content — straight to your inbox.

No spam. Join 138,000+ creators. Unsubscribe anytime.

Create Your Free Bio Page

Join 138,000+ creators on Seemless.

Get Started Free