Hàm tạo ngày trả về NaN trong IE, nhưng hoạt động trong Firefox và Chrome


79

Tôi đang cố gắng tạo một lịch nhỏ bằng JavaScript. Tôi thấy ngày tháng của mình hoạt động tốt trên Firefox và Chrome, nhưng trong IE, các hàm ngày tháng trả về NaN.

Đây là chức năng:

function buildWeek(dateText){
    var headerDates='';
    var newDate = new Date(dateText);

    for(var d=0;d<7;d++){
        headerDates += '<th>' + newDate + '</th>';
        newDate.setDate(newDate.getDate()+1);
    }                       

    jQuery('div#headerDates').html('<table><tr>'+headerDates+'</tr></table>');
}

dateTextlà thứ Hai của tuần hiện tại mà là thực sự thiết lập trong php theo định dạng của 'm, d, Y', ví dụ "02, 01, 2010".


2
Bạn có một số lỗi sao chép-dán trên mẫu mã của mình, hãy xem câu lệnh for: for(var d=0;d';điều đó sẽ làm tăng SyntaxError...
Christian C. Salvadó

Điều này có trả lời câu hỏi của bạn không? Tại sao Date.parse cho kết quả không chính xác?
Heretic Monkey

Câu trả lời:


67

Hàm tạo Ngày chấp nhận bất kỳ giá trị nào. Nếu [[giá trị]] nguyên thủy của đối số là số, thì Ngày được tạo có giá trị đó. Nếu nguyên thủy [[value]] là Chuỗi, thì đặc tả chỉ đảm bảo rằng phương thức khởi tạo Date và phương thức phân tích cú pháp có khả năng phân tích cú pháp kết quả của Date.prototype.toString và Date.prototype.toUTCString ()

Một cách đáng tin cậy để đặt Ngày là tạo một ngày và sử dụng các phương thức setFullYearsetTime.

Ví dụ về điều đó xuất hiện ở đây: http://jibbering.com/faq/#parseDate

ECMA-262 r3 không xác định bất kỳ định dạng ngày nào. Việc chuyển các giá trị chuỗi cho hàm tạo Date hoặc Date.parse có kết quả phụ thuộc vào việc triển khai. Tốt nhất là nên tránh.


Chỉnh sửa: Mục nhập từ Câu hỏi thường gặp về comp.lang.javascript là: Định dạng ngày tháng cục bộ ISO 8601 mở rộng YYYY-MM-DDcó thể được phân tích cú pháp thành a Datevới như sau: -

/**Parses string formatted as YYYY-MM-DD to a Date object.
 * If the supplied string does not match the format, an 
 * invalid Date (value NaN) is returned.
 * @param {string} dateStringInRange format YYYY-MM-DD, with year in
 * range of 0000-9999, inclusive.
 * @return {Date} Date object representing the string.
 */

  function parseISO8601(dateStringInRange) {
    var isoExp = /^\s*(\d{4})-(\d\d)-(\d\d)\s*$/,
        date = new Date(NaN), month,
        parts = isoExp.exec(dateStringInRange);

    if(parts) {
      month = +parts[2];
      date.setFullYear(parts[1], month - 1, parts[3]);
      if(month != date.getMonth() + 1) {
        date.setTime(NaN);
      }
    }
    return date;
  }

Cảm ơn Garrett. Chức năng bạn cung cấp trong liên kết là chức năng tốt nhất ngắn gọn hơn bất kỳ thứ gì khác mà tôi có thể tìm thấy và nó hoạt động với định dạng ngày tháng mà tôi sử dụng thông qua 99% ứng dụng khác! Nhất quán hơn nhiều so với những gì tôi đang sử dụng.
đạp xe vào

Điều này, than ôi, không tốt, vì nhiều định dạng có cấu trúc chỉ sử dụng định dạng ngày / giờ W3C (ISO-8601 với đầy đủ thông số kỹ thuật hoặc hơn). Vì vậy, mặc dù dấu thời gian tốt hơn theo nhiều cách (đơn giản hơn, hiệu quả hơn, hoạt động với tất cả các trình duyệt), nhưng dữ liệu ngày / giờ chuẩn thường được phân tích cú pháp từ javascript. Tôi tự hỏi liệu jQuery hoặc như vậy sẽ có các phương thức phân tích cú pháp tốt hơn.
StaxMan

3
thanks vì đã chỉ ra, phát điên tại sao chrome làm việc ngày phân tích tốt trong khi IE7 đang nói NAN, điều tốt $ .datepicker.parseDate từ jquery có khả năng phân tích cú pháp ngày
Carlos Jaime C. De Leon

Điều gì sẽ xảy ra nếu bạn muốn cả mili giây?
okysabeni

Tôi đã sử dụng một hàm bắt nguồn từ mã này để phân tích cú pháp ngày / giờ ISO từ một chuỗi. Trong những trường hợp hiếm hoi, tôi sẽ nhập một giá trị có vẻ hợp lệ vào bảng sao kê if (month != date.getMonth() + 1), làm mất hiệu lực ngày. Ví dụ 2014-06-01T01:09:22.68,. Bạn có thể giải thích mục đích của ifcâu nói này ?
Grinn

87

Từ định dạng datetime / timestamp mysql:

var dateStr="2011-08-03 09:15:11"; //returned from mysql timestamp/datetime field
var a=dateStr.split(" ");
var d=a[0].split("-");
var t=a[1].split(":");
var date = new Date(d[0],(d[1]-1),d[2],t[0],t[1],t[2]);

Tôi hy vọng là hữu ích cho ai đó. Hoạt động trong IE FF Chrome


Hoạt động với tất cả các trình duyệt. Thnx
Tejas

1
const a = dateStr.split(' '); const d = a[0].split('-'); const t = a[1].split(':'); currentValue.created_date = new Date(+d[0], (+d[1] - 1), +d[2], +t[0], +t[1]);cho ES5 trở lên.
Sydwell

15

Không sử dụng "new Date ()", vì nó lấy chuỗi ngày đầu vào làm giờ địa phương:

new Date('11/08/2010').getTime()-new Date('11/07/2010').getTime();  //90000000
new Date('11/07/2010').getTime()-new Date('11/06/2010').getTime();  //86400000

chúng ta nên sử dụng "NewDate ()", nó lấy đầu vào là giờ GMT:

function NewDate(str)
         {str=str.split('-');
          var date=new Date();
          date.setUTCFullYear(str[0], str[1]-1, str[2]);
          date.setUTCHours(0, 0, 0, 0);
          return date;
         }
NewDate('2010-11-07').toGMTString();
NewDate('2010-11-08').toGMTString();

7

Đây là một cách tiếp cận khác bổ sung một phương thức cho Dateđối tượng

sử dụng: var d = (new Date()).parseISO8601("1971-12-15");

    / **
     * Phân tích cú pháp ngày đã định dạng ISO 8601 thành đối tượng ngày tháng, ISO 8601 là YYYY-MM-DD
     * 
     * @param {String} ghi ngày tháng dưới dạng chuỗi, ví dụ: 1971-12-15
     * @returns {Date} Đối tượng ngày đại diện cho ngày của chuỗi được cung cấp
     * /
    Date.prototype.parseISO8601 = function (date) {
        var match = date.match (/ ^ \ s * (\ d {4}) - (\ d {2}) - (\ d {2}) \ s * $ /);

        if (khớp) {
            this.setFullYear (parseInt (khớp với [1]));    
            this.setMonth (parseInt (khớp với [2]) - 1);    
            this.setDate (parseInt (khớp với [3]));    
        }

        trả lại cái này;
    };

2

Tôi luôn lưu trữ ngày của mình theo giờ UTC.

Đây là chức năng của riêng tôi được tạo ra từ các chức năng khác nhau mà tôi tìm thấy trong trang này.

Nó sử dụng STRING dưới dạng định dạng mysql DATETIME (ví dụ: 2013-06-15 15:21:41). Việc kiểm tra với regex là tùy chọn. Bạn có thể xóa phần này để cải thiện hiệu suất.

Hàm này trả về một dấu thời gian.

DATETIME được coi là ngày UTC . Cẩn thận: Nếu bạn mong đợi một ngày giờ cục bộ, thì chức năng này không dành cho bạn.

    function datetimeToTimestamp(datetime)
    {
        var regDatetime = /^[0-9]{4}-(?:[0]?[0-9]{1}|10|11|12)-(?:[012]?[0-9]{1}|30|31)(?: (?:[01]?[0-9]{1}|20|21|22|23)(?::[0-5]?[0-9]{1})?(?::[0-5]?[0-9]{1})?)?$/;
        if(regDatetime.test(datetime) === false)
            throw("Wrong format for the param. `Y-m-d H:i:s` expected.");

        var a=datetime.split(" ");
        var d=a[0].split("-");
        var t=a[1].split(":");

        var date = new Date();
        date.setUTCFullYear(d[0],(d[1]-1),d[2]);
        date.setUTCHours(t[0],t[1],t[2], 0);

        return date.getTime();
    }

2

Đây là đoạn mã khắc phục hành vi đó của IE (v ['date'] là chuỗi ngày được phân tách bằng dấu phẩy, ví dụ: "2010,4,1"):

if($.browser.msie){
    $.lst = v['date'].split(',');
    $.tmp = new Date(parseInt($.lst[0]),parseInt($.lst[1])-1,parseInt($.lst[2]));
} else {
    $.tmp = new Date(v['date']);
}

Cách tiếp cận trước đây không coi rằng JS Date month là KHÔNG dựa trên ...

Xin lỗi vì không giải thích quá nhiều, tôi đang làm việc và chỉ nghĩ điều này có thể giúp ích.


1

Đây là cách tiếp cận của tôi:

var parseDate = function(dateArg) {
    var dateValues = dateArg.split('-');
    var date = new Date(dateValues[0],dateValues[1],dateValues[2]);
    return date.format("m/d/Y");
}

thay thế ('-')bằng máy đo độ ẩm bạn đang sử dụng.


1

Gửi văn bản và định dạng ngày tháng mà bạn đang gửi văn bản dữ liệu theo phương thức bên dưới. Nó sẽ phân tích cú pháp và trả về như ngày tháng và điều này độc lập với trình duyệt.

function cal_parse_internal(val, format) {
val = val + "";
format = format + "";
var i_val = 0;
var i_format = 0;
var x, y;
var now = new Date(dbSysCurrentDate);
var year = now.getYear();
var month = now.getMonth() + 1;
var date = now.getDate();

while (i_format < format.length) {
    // Get next token from format string
    var c = format.charAt(i_format);
    var token = "";
    while ((format.charAt(i_format) == c) && (i_format < format.length)) {
        token += format.charAt(i_format++);
    }
    // Extract contents of value based on format token
    if (token == "yyyy" || token == "yy" || token == "y") {
        if (token == "yyyy") { x = 4; y = 4; }
        if (token == "yy")   { x = 2; y = 2; }
        if (token == "y")    { x = 2; y = 4; }
        year = _getInt(val, i_val, x, y);
        if (year == null) { return 0; }
        i_val += year.length;
        if (year.length == 2) {
            if (year > 70) {
                year = 1900 + (year - 0);
            } else {
                year = 2000 + (year - 0);
            }
        }
    } else if (token == "MMMM") {
        month = 0;
        for (var i = 0; i < MONTHS_LONG.length; i++) {
            var month_name = MONTHS_LONG[i];
            if (val.substring(i_val, i_val + month_name.length) == month_name) {
                month = i + 1;
                i_val += month_name.length;
                break;
            }
        }
        if (month < 1 || month > 12) { return 0; }
    } else if (token == "MMM") {
        month = 0;
        for (var i = 0; i < MONTHS_SHORT.length; i++) {
            var month_name = MONTHS_SHORT[i];
            if (val.substring(i_val, i_val + month_name.length) == month_name) {
                month = i + 1;
                i_val += month_name.length;
                break;
            }
        }
        if (month < 1 || month > 12) { return 0; }
    } else if (token == "MM" || token == "M") {     
        month = _getInt(val, i_val, token.length, 2);
        if (month == null || month < 1 || month > 12) { return 0; }
        i_val += month.length;
    } else if (token == "dd" || token == "d") {
        date = _getInt(val, i_val, token.length, 2);
        if (date == null || date < 1 || date > 31) { return 0; }
        i_val += date.length;
    } else {
        if (val.substring(i_val, i_val+token.length) != token) {return 0;}
        else {i_val += token.length;}
    }
}

// If there are any trailing characters left in the value, it doesn't match
if (i_val != val.length) { return 0; }

// Is date valid for month?
if (month == 2) {
    // Check for leap year
    if ((year%4 == 0 && year%100 != 0) || (year%400 == 0)) { // leap year
        if (date > 29) { return false; }
    } else {
        if (date > 28) { return false; }
    }
}
if (month == 4 || month == 6 || month == 9 || month == 11) {
    if (date > 30) { return false; }
}
return new Date(year, month - 1, date);
}

Cảm ơn Valli. Tôi đã đi với câu trả lời của garrett bên dưới, vì hàm mà anh ta liên kết đến nhỏ hơn và hoạt động với định dạng ngày tôi thường sử dụng.
đạp xe vào

0

Hàm tạo Ngày trong JavaScript cần một chuỗi ở một trong các định dạng ngày được phương thức phân tích cú pháp () hỗ trợ.

Rõ ràng, định dạng bạn đang chỉ định không được hỗ trợ trong IE, vì vậy bạn sẽ cần thay đổi mã PHP hoặc phân tích cú pháp chuỗi theo cách thủ công trong JavaScript.


4
Đó nhiêu là khá rõ ràng, nhưng nó sẽ là tốt để biết những gì hỗ trợ các định dạng có thể là ...
StaxMan

0

Bạn có thể sử dụng mã sau để phân tích cú pháp chuỗi ngày ISO8601:

function parseISO8601(d) {
    var timestamp = d;
    if (typeof (d) !== 'number') {
        timestamp = Date.parse(d);
    }
    return new Date(timestamp);
};

0

Hãy thử sử dụng getDatetính năng của datepicker.

$.datepicker.formatDate('yy-mm-dd',new Date(pField.datepicker("getDate")));

0

Tôi đã thử tất cả các giải pháp trên nhưng không có gì hiệu quả với tôi. Tôi đã động não và tìm thấy điều này và hoạt động tốt trong IE11.

value="2020-08-10 05:22:44.0";
var date=new Date(value.replace(" ","T")).$format("d/m/yy h:i:s");
console.log(date);

nếu định dạng $ không hoạt động đối với bạn chỉ sử dụng định dạng.

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.