new Date () đang hoạt động trong Chrome nhưng không hoạt động trên Firefox


89

Tôi đang tạo một chuỗi ngày giờ trông giống như sau: 2010-07-15 11:54:21

Và với đoạn mã sau, tôi nhận được ngày không hợp lệ trong Firefox nhưng hoạt động tốt trong Chrome

var todayDateTime = year + '-' + month + '-' + day + ' ' + hour + ':' + minute + ':' + seconds;
var date1 = new Date(todayDateTime);

Trong firefox date1 đang cho tôi một ngày không hợp lệ, nhưng trong chrome, nó hoạt động tốt, nguyên nhân chính là gì?


2
nếu bạn muốn chơi với nó trong bất kỳ cách nào bạn muốn đi với datejs.com
Sinan

Không phải tất cả các triển khai đều hỗ trợ định dạng trong ECMA-262 vì vậy hãy luôn phân tích cú pháp các chuỗi theo cách thủ công (thư viện có thể trợ giúp nhưng có thể không cần thiết cho các định dạng đơn lẻ).
RobG

Nó hoạt động Firefox ngay bây giờ.
Sm Yamashita

Câu trả lời:


78

Bạn không thể khởi tạo đối tượng ngày tháng theo bất kỳ cách nào bạn muốn. Nó phải theo một cách cụ thể. Dưới đây là một số ví dụ hợp lệ:

new Date() // current date and time
new Date(milliseconds) //milliseconds since 1970/01/01
new Date(dateString)
new Date(year, month, day, hours, minutes, seconds, milliseconds)

hoặc là

d1 = new Date("October 13, 1975 11:13:00")
d2 = new Date(79,5,24)
d3 = new Date(79,5,24,11,33,0)

Chrome phải linh hoạt hơn.

Nguồn: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Date

Từ bình luận của apsillers :

thông số kỹ thuật EMCAScript yêu cầu chính xác một định dạng ngày (tức là YYYY-MM-DDTHH: mm: ss.sssZ) nhưng các định dạng ngày tùy chỉnh có thể được triển khai hỗ trợ miễn phí : " Nếu Chuỗi không tuân theo định dạng [ECMAScript-xác định] đó chức năng có thể trở về bất kỳ định dạng ngày cụ thể cho việc triển khai hoặc các định dạng ngày cụ thể cho việc triển khai. "Chrome và FF chỉ đơn giản là có các" định dạng ngày cụ thể cho việc triển khai "khác nhau.


3
Tôi có một giải pháp mà làm việc trong tất cả các trình duyệt như Firefox: stackoverflow.com/a/21984717/586051
Rahul Desai

7
Về lý do tại sao sự khác biệt về trình duyệt này lại tồn tại: đặc tả EMCAScript yêu cầu chính xác một định dạng ngày (tức là, YYYY-MM-DDTHH:mm:ss.sssZ) nhưng các định dạng ngày tùy chỉnh có thể được triển khai hỗ trợ miễn phí : " Nếu Chuỗi không tuân theo định dạng [ECMAScript do ECMAScript] đó, hàm có thể quay lại bất kỳ định dạng ngày cụ thể cho việc triển khai hoặc các định dạng ngày cụ thể cho việc triển khai. "Chrome và FF chỉ đơn giản là có" định dạng ngày cụ thể cho việc triển khai "khác nhau.
apsillers

Một ví dụ về định dạng ngày (tháng bao gồm ".") Hoạt động trong Chrome nhưng không hoạt động trong Firefox: 'Feb. 14, 2019 '
Codecripblr

23

Điều này hoạt động trên tất cả các trình duyệt -

Ngày mới ('2001/01/31 12:00:00 AM')

new Date('2001-01-31 12:00:00')

Định dạng: YYYY-MM-DDTHH: mm: ss.sss

Chi tiết: http://www.ecma-international.org/ecma-262/5.1/#sec-15.9.1.15


bởi vì chúng ta đều biết đó là tiêu chuẩn quốc tế. w3.org/International/questions/qa-date-format
Bobby Tables

6
Vì vậy, bạn đã thực sự kiểm tra tất cả các trình duyệt ? Và giả sử bạn có, bạn cũng biết rằng tất cả các trình duyệt trong tương lai cũng sẽ hỗ trợ định dạng (không chuẩn) đó?
RobG

1
Điều này làm việc cho tôi. Vì vậy, nếu bạn đã nhận được một chuỗi '2001-1-31 12:00:00', chúng ta chỉ cần thực hiện: new Date (str.replace (/ - / g, '/'));
Jianwu Chen

@JianwuChen Bạn đang cố tình sửa đổi một định dạng chuẩn thành không chuẩn. Không phải là một ý tưởng tốt.
JJJ

2
Sau 3 năm sau, nó không hoạt động trên Edge và Window Safari.
Mg Thar

13

Lựa chọn 1 :

Giả sử chuỗi thời gian của bạn có định dạng giống như sau:

'2016-03-10 16:00:00.0'

Trong trường hợp đó, bạn có thể thực hiện một regex đơn giản để chuyển đổi nó thành ISO 8601:

'2016-03-10 16:00:00.0'.replace(/ /g,'T')

Điều này sẽ tạo ra kết quả sau:

'2016-03-10T16:00:00.0'

Đây là định dạng ngày giờ chuẩn và do đó được tất cả các trình duyệt hỗ trợ:

document.body.innerHTML = new Date('2016-03-10T16:00:00.0') // THIS IS SAFE TO USE

Lựa chọn 2 :

Giả sử chuỗi thời gian của bạn có định dạng giống như sau:

'02-24-2015 09:22:21 PM'

Tại đây, bạn có thể thực hiện thao tác regex sau:

'02-24-2015 09:22:21 PM'.replace(/-/g,'/');

Điều này cũng tạo ra một định dạng được hỗ trợ bởi tất cả các trình duyệt:

document.body.innerHTML = new Date('02/24/2015 09:22:21 PM') // THIS IS SAFE TO USE

Tùy chọn 3:

Giả sử bạn có một chuỗi thời gian không dễ điều chỉnh theo một trong những tiêu chuẩn được hỗ trợ tốt.

Trong trường hợp đó, tốt nhất bạn chỉ nên chia chuỗi thời gian của mình thành nhiều phần khác nhau và sử dụng chúng làm các tham số riêng lẻ cho Date:

document.body.innerHTML = new Date(2016, 2, 26, 3, 24, 0); // THIS IS SAFE TO USE


1
var d = new Ngày ('2017-08-28 08:02 PM'.replace (/ - / g,' / ')); Điều này hoàn toàn phù hợp với tôi trong chrome cũng như mozilla.
Rahul Mankar

13

Điều này cũng hoạt động trên hầu hết các trình duyệt

new Date('2001/01/31 12:00:00')

Đó là định dạng của

"yyyy/MM/dd HH:mm:ss"

3
Không có gì đảm bảo rằng định dạng sẽ hoạt động trong bất kỳ trình duyệt nào, ít hơn nhiều "tất cả".
RobG

Bạn nói đúng về điều đó, câu trả lời dựa trên kinh nghiệm của tôi.
Alvis

8

Nếu bạn vẫn muốn tạo ngày bằng dấu gạch ngang, bạn có thể sử dụng định dạng này:

var date = new Date('2013-08-31T17:00:00Z')

Nhưng hãy nhớ rằng nó tạo ra thời gian theo UTC. Có nghĩa là, nếu bạn sống ở múi giờ GMT + 3 (3 giờ trước GMT), nó sẽ thêm phần bù múi giờ này vào thời gian. Vì vậy, ví dụ trên sẽ có giá trị này, nếu GMT + 3 (lưu ý rằng đó là giờ 20:00 chứ không phải 17:00):

Sat Aug 31 2013 20:00:00 GMT+0300 (FLE Standard Time)

Đảm bảo thêm ký tự 'Z' ở cuối, vì nếu không Chrome và Firefox sẽ phân tích cú pháp chuỗi khác nhau (một chuỗi sẽ thêm thời gian bù đắp và chuỗi kia thì không).


1
Có chrome và firefox hoạt động khác nhau nếu bạn không cung cấp múi giờ. Và, tôi nghĩ firefox đã làm sai. Nó sẽ giả định là GMT nếu không có múi giờ. Chrome thì không, firefox thì không. ecma-international.org/ecma-262/5.1/#sec-15.9.1.15
Julian Jelfs

@ JulianJelfs— " Nó sẽ giả định là GMT nếu không có múi giờ ", chỉ dành cho ngày (trái với ISO 8601). Đối với chuỗi ngày và giờ, nó phải giả sử cục bộ (phù hợp với ISO 8601). Nhưng trong mọi trường hợp, phân tích cú pháp thủ công là cách an toàn duy nhất để thực hiện.
RobG

5

Tôi đã gặp sự cố tương tự trong cả Firefox và Safari khi làm việc với AngularJS. Ví dụ: nếu ngày trả về từ Angular trông giống như sau:

2014-06-02 10:28:00

sử dụng mã này:

new Date('2014-06-02 10:28:00').toISOString();

trả về lỗi ngày không hợp lệ trong Firefox và Safari. Tuy nhiên trong Chrome, nó hoạt động tốt. Như một câu trả lời khác đã nêu, Chrome rất có thể linh hoạt hơn với việc phân tích cú pháp chuỗi ngày.

Mục tiêu cuối cùng của tôi là định dạng ngày theo một cách nhất định. Tôi đã tìm thấy một thư viện tuyệt vời xử lý được cả vấn đề tương thích giữa các trình duyệt và vấn đề định dạng ngày. Thư viện được gọi là moment.js .

Sử dụng thư viện này, mã sau hoạt động chính xác trên tất cả các trình duyệt mà tôi đã thử nghiệm:

moment('2014-06-02 10:28:00').format('MMM d YY')

Nếu bạn sẵn sàng đưa thư viện bổ sung này vào ứng dụng của mình, bạn có thể dễ dàng xây dựng chuỗi ngày của mình hơn trong khi tránh các vấn đề có thể xảy ra với trình duyệt. Như một phần thưởng, bạn sẽ có một cách tốt để dễ dàng định dạng, thêm, trừ, v.v. ngày nếu cần.


Bạn phải luôn chuyển định dạng thành moment.js khi phân tích cú pháp chuỗi, nếu không nó chỉ đoán cho đến khi tìm thấy một định dạng tạo ngày hợp lệ.
RobG

4

Điều này sẽ làm việc cho bạn:

var date1 = new Date(year, month, day, hour, minute, seconds);

Tôi đã phải tạo một chuỗi ngày biểu mẫu nên tôi đã làm như thế này:

var d = '2013-07-20 16:57:27';
var date1 = new Date(d.substr(0, 4), d.substr(5, 2), d.substr(8, 2), d.substr(11, 2), d.substr(14, 2), d.substr(17, 2));

Hãy nhớ rằng các tháng trong javascript là từ 0 đến 11, vì vậy bạn nên giảm giá trị tháng đi 1, như sau:

var d = '2013-07-20 16:57:27';
var date1 = new Date(d.substr(0, 4), d.substr(5, 2) - 1, d.substr(8, 2), d.substr(11, 2), d.substr(14, 2), d.substr(17, 2));

2

Giải pháp đơn giản, giải pháp này hoạt động với tất cả các trình duyệt,

var StringDate = "24-11-2017"   
var DateVar = StringDate.split("-");
var DateVal = new Date(DateVar[1] + "/" + DateVar[0] + "/" + DateVar[2]);
alert(DateVal);

1

Một tình huống mà tôi gặp phải là khi xử lý mili giây. FF và IE sẽ không phân tích cú pháp chuỗi ngày này một cách chính xác khi cố gắng tạo một ngày mới. "2014/11/24 17:38:20.177Z" Họ không biết làm thế nào để xử lý .177Z. Tuy nhiên, Chrome sẽ hoạt động.


0

Trên thực tế, Chrome linh hoạt hơn khi xử lý các định dạng chuỗi khác nhau. Ngay cả khi bạn không tìm ra định dạng Chuỗi của nó, Chrome vẫn có thể chuyển đổi thành công Chuỗi thành Ngày mà không gặp lỗi. Như thế này:

  var outputDate = new Date(Date.parse(inputString));

Nhưng đối với Firefox và Safari, mọi thứ trở nên phức tạp hơn. Trên thực tế, trong tài liệu của Firefox, nó đã nói: ( https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Date/parse )

Chuỗi đại diện cho ngày RFC2822 hoặc ISO 8601 (có thể sử dụng các định dạng khác, nhưng kết quả có thể không mong muốn).

Vì vậy, khi muốn sử dụng Date.parse trên Firefox và Safari, bạn nên cẩn thận. Đối với tôi, tôi sử dụng một phương pháp thủ thuật để đối phó với nó. (Lưu ý: không phải lúc nào nó cũng đúng cho mọi trường hợp)

if (input.indexOf("UTC") != -1) {
  var tempInput = inputString.substr(0, 10) + "T" + inputString.substr(11, 8) + "Z";
  date = new Date(Date.parse(tempInput));
}

Tại đây, nó chuyển đổi 2013-08-08 11:52:18 UTC thành 2013-08-08T11: 52: 18Z trước tiên và sau đó định dạng của nó là phù hợp với các từ trong tài liệu của Firefox. Lúc này, Date.parse sẽ luôn ở ngay trong mọi trình duyệt.


0

Đây là những gì đã làm việc cho tôi FirefoxChrome:

// The format is 'year-month-date hr:mins:seconds.milliseconds'
const d = new Date('2020-1-4 12:00:00.999') 
// we use the `.` separator between seconds and milliseconds.

Chúc may mắn...


-1

Trong Firefox, mọi Ngày không hợp lệ đều được trả về dưới dạng đối tượng Ngày dưới dạng Ngày 1899-11-29T19:00:00.000Z, do đó hãy kiểm tra xem trình duyệt có phải là Firefox hay không, sau đó lấy đối tượng Ngày của chuỗi "1899-11-29T19:00:00.000Z".getDate(). Cuối cùng là so sánh với ngày tháng.


Điều này không giải thích nguyên nhân của vấn đề mà là kết quả của vấn đề sẽ như thế nào.
Rytis

-1

Tôi đã sử dụng định dạng ngày tháng sau đây và nó hoạt động trên tất cả các trình duyệt.

var target_date = new Date("Jul 17, 2015 16:55:22").getTime();

var days, hours, minutes, seconds;

var countdown = document.getElementById("countdown");

remaining = setInterval(function () {

    var current_date = new Date().getTime();
    var seconds_left = (target_date - current_date) / 1000;
    days = parseInt(seconds_left / 86400);
    seconds_left = seconds_left % 86400;
    hours = parseInt(seconds_left / 3600);
    seconds_left = seconds_left % 3600;
    minutes = parseInt(seconds_left / 60);
    seconds = parseInt(seconds_left % 60);
    countdown.innerHTML = "<b>"+days + " day, " + hours + " hour, "
        + minutes + " minute, " + seconds + " second.</b>";  
}, 1000);
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.