Invalid date là gì

Các yếu tố cần thiết

JavaScript chính thức hỗ trợ đơn giản hóa của Định dạng mở rộng ISO 8601. Định dạng như sau: YYYY-MM-DDTHH:mm:ss.sssZ. Chữ cái T là dấu phân cách ngày/giờ và Z là phần bù múi giờ được chỉ định là Z (đối với UTC) hoặc + hoặc - theo sau là biểu thức thời gian HH:mm. Một số phần (ví dụ: thời gian) của định dạng đó có thể được bỏ qua.

Lưu ý rằng năm phải có ít nhất bốn chữ số, tháng/ngày/giờ/phút/giây phải có chính xác hai chữ số và mili giây phải có chính xác ba chữ số. Ví dụ: 99-1-1 không phải là chuỗi ngày hợp lệ.

Đây là một số ví dụ về chuỗi ngày (thời gian) hợp lệ:

  • 2018-12-30
  • 2018-12-30T20:59
  • 2018-12-30T20:59:00
  • 2018-12-30T20:59:00.000Z
  • 2018-12-30T20:59:00.000+01:00
  • 2018-12-30T20:59:00.000-01:00

Khi bạn bỏ qua phần bù múi giờ, thời gian ngày được hiểu là giờ địa phương của người dùng. Khi bạn bỏ qua thời gian hoàn toàn, ngày được hiểu là UTC.

Quan trọng : Tất cả các trình duyệt và triển khai cũ hiện đại và hợp lý đều hỗ trợ full-length định dạng thời gian ngày theo thông số kỹ thuật. Tuy nhiên, có sự khác biệt trong việc xử lý chuỗi ngày (thời gian) mà không có múi giờ (xem "Mất bù múi giờ" bên dưới để biết chi tiết). Bạn nên không sử dụng chuỗi thời gian ngày mà không có múi giờ (Trạng thái 2018). Thay vào đó, hãy chuyển một dấu thời gian unix tính bằng mili giây hoặc các đối số riêng biệt cho các phần khác nhau của ngày cho hàm tạo Date.

Hầu hết các trình duyệt cũng hỗ trợ một số định dạng khác nhưng chúng không được chỉ định và do đó không hoạt động trong tất cả các trình duyệt theo cùng một cách. Nếu có, bạn chỉ nên sử dụng các định dạng chuỗi thời gian ngày được giải thích ở trên. Mọi định dạng khác có thể bị hỏng trong các trình duyệt khác hoặc thậm chí trong các phiên bản khác của cùng một trình duyệt.

Nếu bạn chạy vào Invalid Date thay vì một đối tượng ngày, rất có thể bạn đang sử dụng chuỗi thời gian ngày không hợp lệ.


Và bây giờ với một chút chi tiết.

Định dạng chuỗi thời gian ngày

ECMAScript (đặc tả mà ngôn ngữ JavaScript triển khai) đã hỗ trợ các chuỗi ngày trong new Date ( đặc điểm kỹ thuật ) và Date.parse ( đặc điểm kỹ thuật ) kể từ khi thành lập. Tuy nhiên, các phiên bản đầu tiên không thực sự chỉ định định dạng ngày giờ. Điều này đã thay đổi vào năm 2009 khi ES5 được giới thiệu với thông số định dạng ngày giờ.

Những thứ cơ bản

ECMAScript chỉ định Định dạng chuỗi thời gian ngày dưới dạng đơn giản hóa của Định dạng mở rộng ISO 8601 . Định dạng như sau: YYYY-MM-DDTHH:mm:ss.sssZ.

  • YYYY là các chữ số thập phân của năm 0000 đến 9999 trong lịch Gregorian phổ biến.
  • - (dấu gạch nối) xuất hiện hai lần trong chuỗi.
  • MM là tháng trong năm từ 01 (tháng 1) đến 12 (tháng 12).
  • DD là ngày trong tháng từ 01 đến 31.
  • T xuất hiện theo nghĩa đen trong chuỗi, để chỉ sự bắt đầu của phần tử thời gian.
  • HH là số giờ hoàn thành đã trôi qua kể từ nửa đêm dưới dạng hai chữ số thập phân từ 00 đến 24.
  • : (dấu hai chấm) xuất hiện theo nghĩa đen hai lần trong chuỗi.
  • mm là số phút hoàn thành kể từ đầu giờ dưới dạng hai chữ số thập phân từ 00 đến 59.
  • ss là số giây hoàn chỉnh kể từ khi bắt đầu phút là hai chữ số thập phân từ 00 đến 59.
  • . (dấu chấm) xuất hiện theo nghĩa đen trong chuỗi.
  • sss là số mili giây hoàn chỉnh kể từ khi bắt đầu giây thứ hai dưới dạng ba chữ số thập phân.
  • Z là độ lệch múi giờ được chỉ định là "Z" (đối với UTC) hoặc "+" hoặc "-" theo sau là biểu thức thời gian HH:mm

Đặc tả cũng đề cập rằng nếu "Chuỗi không tuân theo định dạng [đã chỉ định] thì chức năng có thể quay trở lại bất kỳ phương pháp phỏng đoán cụ thể thực hiện hoặc định dạng ngày cụ thể thực hiện" nào có thể dẫn đến các ngày khác nhau trong trình duyệt khác nhau.

ECMAScript không đưa bất kỳ định dạng ngày giờ địa phương nào của người dùng vào tài khoản, điều đó có nghĩa là bạn không thể sử dụng các định dạng ngày giờ theo quốc gia hoặc khu vực cụ thể.

Biểu mẫu Ngày ngắn (và Thời gian)

Các đặc điểm kỹ thuật cũng bao gồm các định dạng ngắn hơn như sau.

Định dạng này bao gồm các hình thức chỉ ngày:
  • YYYY
  • YYYY-MM
  • YYYY-MM-DD
Nó cũng bao gồm các biểu mẫu thời gian hẹn giờ của Nhật Bản bao gồm một trong các biểu mẫu chỉ ngày ở trên ngay sau đó là một trong các biểu mẫu thời gian sau với phần bù múi giờ tùy chọn được thêm vào:
  • THH:mm
  • THH:mm:ss
  • THH:mm:ss.sss

Giá trị dự phòng

[...] Nếu các trường MM hoặc DD vắng mặt "01" được sử dụng làm giá trị. Nếu các trường HH, mm hoặc ss vắng mặt "00" được sử dụng làm giá trị và giá trị của trường sss vắng mặt là "000". Khi không có bù múi giờ, các biểu mẫu chỉ ngày được hiểu là thời gian UTC và biểu mẫu ngày giờ được hiểu là giờ địa phương.

Xem "Mất bù múi giờ" bên dưới để biết thêm thông tin về việc thiếu hỗ trợ trình duyệt.

Hết giá trị ràng buộc

Các giá trị bất hợp pháp (ngoài giới hạn cũng như lỗi cú pháp) trong chuỗi định dạng có nghĩa là chuỗi định dạng không phải là phiên bản hợp lệ của định dạng này.

Ví dụ: new Date('2018-01-32') và new Date('2018-02-29') sẽ dẫn đến Invalid Date.

Năm kéo dài

Định dạng thời gian ngày của ECMAScript cũng chỉ định năm kéo dài là các giá trị năm chữ số. Một ví dụ về định dạng chuỗi năm mở rộng như vậy trông giống như +287396-10-12T08:59:00.992Z biểu thị một ngày trong năm 287394 A.D. Năm kéo dài có thể là dương hoặc âm.

API ngày

ECMAScript chỉ định một phạm vi rộng thuộc tính đối tượng ngày . Đưa ra một đối tượng ngày hợp lệ, bạn có thể sử dụng Date.prototype.toISOString() để có được chuỗi thời gian ngày hợp lệ. Lưu ý rằng múi giờ luôn là UTC.new Date().toISOString() // "2018-08-05T20:19:50.905Z"

Cũng có thể phát hiện xem một đối tượng ngày hợp lệ hay Invalid Date bằng cách sử dụng chức năng sau.function isValidDate(d) { return d instanceof Date && !isNaN(d); }

Nguồn và nhiều thông tin hơn có thể được tìm thấy trong Phát hiện một ngày không hợp lệ của Ngày tháng trong JavaScript .

Ví dụ

Định dạng ngày giờ hợp lệ

Các định dạng thời gian ngày sau đây đều hợp lệ theo đặc điểm kỹ thuật và sẽ hoạt động trong mọi trình duyệt, Node.js hoặc triển khai khác hỗ trợ ES2016 trở lên.2018 2018-01 2018-01-01 2018-01-01T00:00 2018-01-01T00:00:00 2018-01-01T00:00:00.000 2018-01-01T00:00:00.000Z 2018-01-01T00:00:00.000+01:00 2018-01-01T00:00:00.000-01:00 +002018-01-01T00:00:00.000+01:00

Định dạng ngày giờ không hợp lệ

Lưu ý rằng các ví dụ sau không hợp lệ theo thông số kỹ thuật. Tuy nhiên, điều đó không có nghĩa là không có trình duyệt hoặc triển khai nào khác diễn giải chúng thành một ngày. Vui lòng không sử dụng bất kỳ định dạng ngày giờ nào bên dưới vì chúng không chuẩn và có thể bị lỗi trong một số trình duyệt hoặc phiên bản trình duyệt.2018-1-1 // month and date must be two digits 2018-01-01T0:0:0.0 // hour/minute/second must be two digits, millisecond must be three digits 2018-01-01 00:00 // whitespace must be "T" instead 2018-01-01T00 // shortest time part must have format HH:mm 2018-01-01T00:00:00.000+01 // time zone must have format HH:mm

Hỗ trợ trình duyệt

Ngày nay, mọi trình duyệt cũ hiện đại và hợp lý đều hỗ trợ định dạng ngày giờ được giới thiệu với thông số ES5 vào năm 2009. Tuy nhiên, ngay cả ngày nay (Status 2018) có các triển khai khác nhau cho chuỗi thời gian ngày không có múi giờ (xem "Mất bù múi giờ" bên dưới). Nếu bạn cần hỗ trợ các trình duyệt cũ hơn hoặc sử dụng chuỗi không có múi giờ, bạn không nên sử dụng chuỗi thời gian ngày . Thay vào đó, hãy chuyển một số mili giây kể từ ngày 1 tháng 1 năm 1970, 00:00:00 UTC hoặc hai hoặc nhiều đối số đại diện cho các phần ngày khác nha cho hàm tạo Date.

Thiếu múi giờ

ES5.1 không chính xác nói rằng giá trị của phần bù múi giờ vắng mặt là Z mâu thuẫn với ISO 8601. Lỗi này đã được sửa trong ES6 (ES2015) và được mở rộng trong - ES2016 (xem "Thay đổi thông số kỹ thuật ECMAScript" bên dưới). Kể từ ES2016, các chuỗi thời gian ngày không có múi giờ được phân tích cú pháp là giờ địa phương trong khi các chuỗi chỉ ngày được phân tích cú pháp là UTC.

Theo câu trả lời này , một số triển khai không bao giờ thực hiện hành vi được chỉ định trong ES5.1. Một trong số đó dường như là Mozilla Firefox. Các trình duyệt khác có vẻ phù hợp với đặc điểm kỹ thuật của ES2016 (và cao hơn) là Google Chrome 65+, Microsoft Internet Explorer 11 và Microsoft Edge. Phiên bản hiện tại của Apple Safari (11.1.2) là không tuân thủ vì nó phân tích sai chuỗi thời gian ngày mà không có múi giờ (ví dụ: 2018-01-01T00:00) là UTC thay vì giờ địa phương.

Định dạng ngày kế thừa

ES5 đã giới thiệu một đặc tả cho chuỗi thời gian ngày vào năm 2009. Trước đó, không có định dạng cụ thể nào được hỗ trợ bởi tất cả các trình duyệt. Do đó, mỗi nhà cung cấp trình duyệt đã thêm hỗ trợ cho các định dạng khác nhau thường không hoạt động trên các trình duyệt (và phiên bản) khác nhau. Để biết một ví dụ nhỏ về lịch sử cổ đại, xem định dạng ngày .

Hầu hết các trình duyệt vẫn hỗ trợ các định dạng cũ để không phá vỡ tính tương thích ngược của các trang web cũ. Nhưng không an toàn khi dựa vào các định dạng không chuẩn này vì chúng có thể không nhất quán hoặc bị xóa bất cứ lúc nào.

Date.prototype.toString() và Date.prototype.toUTCString()

ES2018 lần đầu tiên đã chỉ định định dạng ngày được trả về bởi Date.prototype.toString() và Date.prototype.toUTCString() . Trước đó, Đặc tả ECMA yêu cầu hàm tạo Date và Date.parse phân tích chính xác các định dạng được trả về bởi các phương thức đó (mặc dù nó không chỉ định định dạng trước năm 2018).

Một giá trị trả về ví dụ của Date.prototype.toString() có thể trông như thế này:Sun Feb 03 2019 14:27:49 GMT+0100 (Central European Standard Time)

Lưu ý rằng tên múi giờ trong ngoặc là tùy chọn và tên chính xác là "phụ thuộc vào việc triển khai".

Date.prototype.toUTCString() trả về một ngày có định dạng tương tự như Date.prototype.toString() nhưng với độ lệch múi giờ bằng không. Một định dạng ví dụ có thể trông như thế này:Sun, 03 Feb 2019 13:27:49 GMT

Lưu ý rằng có dấu phẩy , sau ngày trong tuần và tháng ngày được đảo ngược so với Date.prototype.toUTCString().

Vì các định dạng này chỉ được chỉ định vào năm 2018, bạn không nên dựa vào chúng hoạt động như nhau trong các triển khai khác nhau (đặc biệt là các trình duyệt cũ hơn).

Node.js

Node.js đang chạy trên công cụ JavaScript V8 cũng được sử dụng trong Google Chrome. Vì vậy cùng thông số kỹ thuật về định dạng chuỗi thời gian ngày được áp dụng. Vì mã chạy trong phần phụ trợ, mặc dù giờ địa phương của người dùng không ảnh hưởng đến múi giờ nhưng chỉ có các cài đặt trên máy chủ làm. Hầu hết nền tảng là nhà cung cấp dịch vụ (PaaS) mà các ứng dụng Host Node.js sử dụng UTC làm múi giờ mặc định của chúng.

Thư viện ngày giờ

Khoảnh khắc

Moment.js là một thư viện rất phổ biến để giúp xử lý ngày trong JavaScript và nó cũng hỗ trợ nhiều định dạng hơn so với ECMAScript chỉ định. Ngoài ra, Moment.js cũng hỗ trợ tạo các đối tượng ngày dựa trên chuỗi và định dạng tùy ý .

Luxon

Luxon hỗ trợ phân tích cú pháp của các định dạng ISO 8601, HTTP, RFC2822, SQL và tùy ý. Nhưng chỉ sử dụng các chức năng khác nhau cho các định dạng thời gian ngày khác nhau.

Thay đổi thông số kỹ thuật ECMAScript

Danh sách các thay đổi đáng chú ý trong thông số kỹ thuật ECMAScript liên quan đến các định dạng chuỗi thời gian ngày.

Thay đổi trong ES2018

Giới thiệu một đặc điểm kỹ thuật cho các định dạng ngày được trả về bởi Date.prototype.toString() và Date.prototype.toUTCString() .

Thay đổi trong ES2017

Không có thay đổi đáng chú ý.

Thay đổi trong ES2016

Nếu phần bù múi giờ không có, ngày giờ được hiểu là giờ địa phương.

Khi không có bù múi giờ, các biểu mẫu chỉ ngày được hiểu là thời gian UTC và biểu mẫu ngày giờ được hiểu là giờ địa phương.

Thay đổi trong ES6 (ES2015)

Giá trị của phần bù múi giờ vắng mặt là Z.

Nếu phần bù múi giờ không có, ngày giờ được hiểu là giờ địa phương.

Từ Sửa chữa và làm rõ trong ECMAScript 2015 với Tác động tương thích có thể có :

Nếu không có bù múi giờ, múi giờ địa phương được sử dụng. Phiên bản 5.1 đã tuyên bố không chính xác rằng một múi giờ bị thiếu nên được hiểu là "z".

Xem Định dạng chuỗi thời gian ngày: chênh lệch múi giờ mặc định từ ES5 không tương thích web để biết thêm chi tiết về thay đổi đó.

Thay đổi trong ES5.1

Nếu các trường MM hoặc DD vắng mặt 01 được sử dụng làm giá trị. Nếu các trường HH, mm hoặc ss vắng mặt 00 được sử dụng làm giá trị và giá trị của trường sss vắng mặt là 000. Giá trị của phần bù múi giờ vắng mặt là Z.

Thay đổi trong ES5

Lần đầu tiên giới thiệu định dạng chuỗi thời gian ngày cho đặc tả ECMAScript.

ECMAScript xác định định dạng trao đổi chuỗi cho thời gian ngày dựa trên việc đơn giản hóa Định dạng mở rộng ISO 8601. Định dạng như sau: YYYY-MM-DDTHH:mm:ss.sssZ

Đồng thời giới thiệu Date.prototype.toISOString() trả về chuỗi thời gian ngày theo định dạng đã chỉ định đó.

Thay đổi trong ES

Không dùng Date.prototype.toGMTString() và thay thế nó bằng Date.parse(x.toUTCString()) trong phần đề cập rằng định dạng được trả về bởi các phương thức này phải được phân tích chính xác bằng cách áp dụng Date.parse. Lưu ý rằng định dạng được trả về bởi Date.parse(x.toUTCString()) là "phụ thuộc vào việc triển khai".

Thay đổi trong ES2

Không có thay đổi đáng chú ý.

Thông số ban đầu: ES1

ES1 đã giới thiệu các chuỗi thời gian ngày được sử dụng trong new Date(value) và Date.parse(value). Tuy nhiên, nó không chỉ định định dạng ngày (thời gian) thực tế, thậm chí nó còn tuyên bố rằng

[...] Giá trị được tạo bởi Date.parse phụ thuộc vào việc triển khai [...]

Các đặc điểm kỹ thuật cũng đề cập rằng

Nếu x là bất kỳ đối tượng Ngày nào [...], thì tất cả các biểu thức sau sẽ tạo ra cùng một giá trị số trong triển khai đó [...]:
  • [...]
  • Date.parse(x.toString())
  • Date.parse(x.toGMTString())

Tuy nhiên, giá trị được trả về của cả Date.prototype.toString() và Date.prototype.toGMTString() được chỉ định là "phụ thuộc thực hiện".

Vậy tôi nên sử dụng định dạng ngày giờ nào?

Khuyến cáo chung là không nên sử dụng trình phân tích cú pháp tích hợp vì nó không đáng tin cậy, vì vậy câu trả lời cho "nên" là "không". Xem Tại sao Date.parse cho kết quả không chính xác?

Tuy nhiên, như str nói, bạn có thể sử dụng định dạng được chỉ định trong ECMA-262 với múi giờ: YYYY-MM-DDTHH:mm:ss.sssZ hoặc YYYY-MM-DDTHH:mm:ss.sss±HH:mm, không tin bất kỳ định dạng nào khác.

Có phải tất cả các trình duyệt hỗ trợ các định dạng giống nhau?

Không.

Làm thế nào để Mozilla Firefox, Google Chrome, Microsoft Internet Explorer, Microsoft Edge và Apple Safari xử lý chuỗi thời gian ngày?

Khác nhau. Bất cứ điều gì khác ngoài định dạng trong ECMA-262 đều phụ thuộc vào việc triển khai và có lỗi trong việc phân tích định dạng ECMA-262.

Còn Node.js thì sao?

Có khả năng khác nhau một lần nữa, xem ở trên.

Liệu nó có định dạng ngày địa phương để xem xét? Ví dụ. nếu tôi sống ở Thụy Sĩ và định dạng ngày là 30/07/2012, tôi có thể sử dụng Ngày mới ('30 .07.2018 ') không?

Có lẽ. Vì nó không phải là định dạng chuẩn, phân tích cú pháp phụ thuộc vào việc triển khai, nên có thể, có thể không.

Liệu nó có xem xét múi giờ địa phương?

Nó sử dụng phần bù múi giờ của máy chủ trong đó chuỗi được phân tích cú pháp là cục bộ và để tạo chuỗi được hiển thị bằng thời gian cục bộ. Mặt khác, nó sử dụng UTC (và giá trị thời gian nội bộ là UTC).

Làm cách nào tôi có thể nhận được chuỗi thời gian ngày từ một đối tượng ngày?

Date.parse.toString hoặc xem Tôi có thể tìm tài liệu về định dạng ngày trong JavaScript ở đâu?

Làm cách nào để phát hiện chuỗi thời gian ngày không hợp lệ?

Một trong 3 câu trả lời đầu tiên ở đây nên trả lời rằng.

Làm thế nào để các thư viện ngày như Moment.js xử lý chuỗi ngày?

Họ phân tích chúng dựa trên định dạng mặc định hoặc được cung cấp. Đọc nguồn (ví dụ: fecha.js là một trình phân tích cú pháp và trình định dạng đơn giản với mã được viết tốt, dễ theo dõi).

Trình phân tích cú pháp không khó viết, nhưng cố gắng đoán định dạng đầu vào (vì trình phân tích cú pháp tích hợp có xu hướng làm) là không đầy đủ, không đáng tin cậy và không nhất quán trong quá trình triển khai. Vì vậy, trình phân tích cú pháp nên yêu cầu định dạng được cung cấp trừ khi chuỗi đầu vào ở định dạng mặc định của trình phân tích cú pháp.

PS

Có những thay đổi về định dạng của chuỗi mà việc triển khai phải hỗ trợ cho việc phân tích cú pháp và định dạng trong ECMAScript 2019 (hiện đang trong dự thảo), nhưng tôi nghĩ rằng lời khuyên chung để tránh các chương trình phân tích cú pháp được xây dựng sẽ tồn tại trong một thời gian.