2012-04-22 28 views
18

Trước hết, tôi nghĩ múi giờ có thể liên quan đến điều này. Tôi đang ở EST/EDT. Ngoài ra, tôi đang thử nghiệm này trên chromium 17/linux.Hàm tạo ngày tháng: đối số dạng số và đối số chuỗi cho các ngày khác nhau trong một số trường hợp

Bây giờ, chúng ta hãy nói rằng tôi tạo ra hai ngày như thế này:

// December 5 

dateFromNumbers = new Date(2020, 11, 5); 
dateFromString = new Date("2020-12-5"); 

Có vẻ như những ngày này nên có timestamps giống hệt nhau, và họ làm:

+dateFromNumbers == +dateFromString; // true 

... ít nhất là trong trường hợp này . Nhưng trong một số trường hợp, họ không:

// December 15 

dateFromNumbers = new Date(2020, 11, 15); 
dateFromString = new Date("2020-12-15"); 

+dateFromNumbers == +dateFromString; // false 

Điều gì đang xảy ra ở đây?

dateFromNumbers; // Tue Dec 15 2020 00:00:00 GMT-0500 (EST) 
dateFromString; // Mon Dec 14 2020 19:00:00 GMT-0500 (EST) 

Hình như dateFromString là 5 giờ sớm hơn dateFromNumbers trong trường hợp này (EST là GMT - 5, tôi chắc chắn rằng nó có liên quan bằng cách nào đó).

Dường như ảnh hưởng đến kết thúc từ tháng 10 đến tháng 12. Đây là một fiddle mà làm cho nó dễ dàng để xem những ngày khác nhau (trừ khi bạn là màu xanh-màu xanh, trong trường hợp đó nó có thể khó nhìn thấy, lời xin lỗi của tôi).

http://jsfiddle.net/9gBfX/

Điều gì cung cấp?


Ghi chú:

  • Bạn có thể đặt múi giờ hệ thống của bạn để EST/EDT để xem ví dụ jsfiddle như tôi nhìn thấy nó.
  • Số tháng của tháng không dựa trên số 0; 11 không phải là lỗi đánh máy.
  • Sự cố này xuất hiện hàng năm mà tôi đã kiểm tra.
+1

Trong trường hợp thứ hai của bạn là ngày 15 tháng 11 năm 2020 và ngày 15 tháng 12 năm 2020. đó có phải là lỗi đánh máy không? – Habib

+0

Chạy Chrome 18.0.1025.162 m, Windows, GMT +2: kết quả có thể tái sản xuất. Nhưng rõ ràng xác định thời gian trong biểu diễn chuỗi giải quyết vấn đề. Tôi thường tránh ngày tháng từ chuỗi vì định dạng hỗ trợ trên các trình duyệt khác nhau và kém tài liệu, mili giây đáng tin cậy hơn rất nhiều. – DCoder

Trả lời

6

Sau khi nhìn vào V8's source code:

// Specification: 
// Accept ES5 ISO 8601 date-time-strings or legacy dates compatible 
// with Safari. 
<...> 
// A string that matches both formats (e.g. 1970-01-01) will be 
// parsed as an ES5 date-time string - which means it will default 
// to UTC time-zone. That's unavoidable if following the ES5 
// specification. 

Đọc mã xung quanh, có vẻ như một chuỗi ngày thời gian với cả tháng và ngày dài 2 biểu tượng được coi là một ES5 ngày thời gian chuỗi hợp lệ.Tiếp tục xuống trong phân tích cú pháp ES5, sau khi phân tích các số ngày tháng và thời gian, có một bình luận:

// Successfully parsed ES5 Date Time String. Default to UTC if no TZ given. 

Trong trường hợp của "YYYY-MM-DD", một lần mã được rằng đến nay, phân tích cú pháp ES5 đã phân tích thành công toàn bộ chuỗi, do đó, nó trả về trước khi trình phân tích cú pháp cũ có cơ hội để bản địa hóa múi giờ. Nếu không (tháng/ngày là một biểu tượng dài), nó được coi là ngày giờ "kế thừa" và trình phân tích cú pháp cũ sẽ xử lý nó và bản địa hoá nó.

2

Sử dụng "-" làm dấu phân cách ngày cho ngày của Hoa Kỳ gây nhầm lẫn cho một số trình duyệt, một số sẽ thực hiện số học ngày sẽ trả về NaN, vì vậy hãy sử dụng dấu phân tách ngày "/". Một giải pháp nhận thức văn hóa là sử dụng date.js, một trình xử lý ngày tháng JavaScript nổi bật, giải quyết các vấn đề giống như vấn đề bạn đã chỉ ra (http://www.datejs.com/). Sử dụng phương pháp phân tích cú pháp loại bỏ tất cả sự nhầm lẫn:

Date.parse("2020-12-15").toString() // yields the correct date ("Tue Dec 15 00:00:00 PST 2020"). 
+2

Thử sử dụng "/" thay vì "-". –

+0

GGG đã đúng khi bỏ phiếu cho câu trả lời của tôi. Tôi nên đã xây dựng và bây giờ đã làm như vậy. –

+0

Tôi đã không downvote nó mặc dù. –

2

chuyển tiếp trên this post, có vẻ như chuỗi nhà xây dựng lập luận 's Date là thực hiện nhạy cảm, do nhiều Date.parse() triển khai bởi các trình duyệt.

phép đo của bạn là chính xác và có thể bạn nên tránh sử dụng hàm tạo này hoàn toàn, nếu bạn muốn trình duyệt phân tích cú pháp EST chính xác.

2

Có vẻ như hàm tạo ngày yêu cầu không gian thay vì '-'. Đó là cách được khuyến nghị. Kiểm tra liên kết này:
3.3. Date and Time Specification

Mặc dù không gian foldingwhite được phép suốt ngày thời gian đặc điểm kỹ thuật, nó được khuyến khích rằng một không gian duy nhất được sử dụng trong mỗi nơi mà FWS xuất hiện (cho dù đó là buộc hay tùy chọn)

Ngoài ra kiểm tra liên kết này:
https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/Date

dateString: Chuỗi giá trị đại diện cho một ngày. Chuỗi phải ở định dạng được công nhận bởi phương thức phân tích cú pháp (dấu thời gian RFC 2822 tương thích IETF).

Tôi đã thử mã sau đây và nó trả về true

dateFromNumbers = new Date(2020, 11, 15); 
dateFromString = new Date("2020 12 15"); 
alert(+dateFromNumbers == +dateFromString);​ 

Ngoài ra nó không phải là một vấn đề bắt đầu với những tháng tháng Mười, nó có làm gì với những tháng đôi chữ số. Nếu tôi cố gắng cùng một phương pháp với tháng sau đó:

dateFromNumbers = new Date(2020, 8, 15); 
dateFromString = new Date("2020-09-15"); 
alert(+dateFromNumbers == +dateFromString);​ // This returns false 

Nhưng nếu tôi sử dụng chữ số duy nhất cho tháng chín sau đó nó trả về true

dateFromNumbers = new Date(2020, 8, 15); 
dateFromString = new Date("2020-9-15"); 
alert(+dateFromNumbers == +dateFromString);​ // This returns true 

Và nếu không gian sử dụng với hai con số Tháng Chín, sau đó nó trả về true

dateFromNumbers = new Date(2020, 8, 15); 
dateFromString = new Date("2020 09 15"); 
alert(+dateFromNumbers == +dateFromString);​//This returns true 
3

Đây là bản vẽ câu trả lời được đơn giản hóa từ các câu trả lời khác.

ngày nhận dạng chuỗi khác nhau

  • ngày Nonstandard
  • RFC 2282 ngày
  • ES 5 ngày

Hầu hết các định dạng được hiểu là ngày địa phương

Trên trang 14 của RFC 2282, chúng tôi thấy:

Ngày và giờ trong ngày thể hiện giờ địa phương.

Ngày không chuẩn được xử lý theo cách tương tự. định dạng

ES 5 được hiểu như là UTC

Trong section 15.9.1.15 của ES 5 đặc tả chúng ta thấy:

Giá trị của một múi giờ vắng mặt bù đắp là “Z”.

"Z" đại diện cho thời gian UTC.

Các thứ mười tháng Mười

ES 5 ngày định dạng đòi hỏi tháng hai con số và ngày. Các tháng và ngày trong bài gốc không phải là 0-đệm. "2020-9-9" không phải là đại diện ngày ES 5 hợp lệ; đó là định dạng không chuẩn, vì vậy nó được diễn giải theo giờ địa phương. "2020-10-10" một đại diện ngày ES 5 hợp lệ, vì vậy nó phải được diễn giải bằng UTC.

cách giải quyết có thể

  • Không sử dụng chuỗi constructor/Date.parse!
  • Thay đổi ký tự dấu tách sao cho định dạng không bao giờ khớp với định dạng ES 5.
  • Chỉ định múi giờ.
  • Điều chỉnh ngày thành giờ địa phương. Nếu họ có giờ hoặc phút: date.setMinutes(date.getTimezoneOffset()); (điều này dường như hoạt động, dù sao).
Các vấn đề liên quan