Javascript 日期构造函数在 IE 中返回 NaN,但在 Firefox 和 Chrome 中有效

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/2182246/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-22 23:08:04  来源:igfitidea点击:

Date constructor returns NaN in IE, but works in Firefox and Chrome

javascriptinternet-explorerdate

提问by pedalpete

I'm trying to build a little calendar in JavaScript. I have my dates working great in Firefox and Chrome, but in IE the date functions are returning NaN.

我正在尝试用 JavaScript 构建一个小日历。我的日期在 Firefox 和 Chrome 中运行良好,但在 IE 中,日期函数返回 NaN。

Here is the function :

这是功能:

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>');
}

dateTextis the Monday of the current week which is actually set in php in the format of 'm, d, Y', e.g. "02, 01, 2010".

dateText是当前周的星期一,它实际上是在php中以'm, d, Y'的格式设置的,例如"02, 01, 2010"

采纳答案by Garrett

The Date constructor accepts any value. If the primitive [[value]] of the argument is number, then the Date that is created has that value. If primitive [[value]] is String, then the specification only guarantees that the Date constructor and the parse method are capable of parsing the result of Date.prototype.toString and Date.prototype.toUTCString()

Date 构造函数接受任何值。如果参数的原始 [[value]] 是数字,则创建的日期具有该值。如果原始 [[value]] 是 String,那么规范只保证 Date 构造函数和 parse 方法能够解析 Date.prototype.toString 和 Date.prototype.toUTCString() 的结果

A reliable way to set a Date is to construct one and use the setFullYearand setTimemethods.

设置 Date 的一种可靠方法是构造一个并使用setFullYearsetTime方法。

An example of that appears here: http://jibbering.com/faq/#parseDate

一个例子出现在这里:http: //jibbering.com/faq/#parseDate

ECMA-262 r3 does not define any date formats. Passing string values to the Date constructor or Date.parse has implementation-dependent outcome. It is best avoided.

ECMA-262 r3 没有定义任何日期格式。将字符串值传递给 Date 构造函数或 Date.parse 具有依赖于实现的结果。最好避免。



Edit:编辑:comp.lang.javascript FAQ 中的条目是:可以将扩展的 ISO 8601 本地日期格式YYYY-MM-DDYYYY-MM-DD解析为DateDate以下内容:-

/**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;
  }

回答by Qlimax

From a mysql datetime/timestamp format:

从 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]);

I hope is useful for someone. Works in IE FF Chrome

我希望对某人有用。适用于 IE FF Chrome

回答by diyism

Don't use "new Date()", because it takes the input date string as local time:

不要使用“new Date()”,因为它将输入日期字符串作为本地时间:

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

we should use "NewDate()", it takes the input as GMT time:

我们应该使用“NewDate()”,它将输入作为 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();

回答by magikMaker

Here's another approach that adds a method to the Dateobject

这是另一种向Date对象添加方法的方法

usage: var d = (new Date()).parseISO8601("1971-12-15");

用法: var d = (new Date()).parseISO8601("1971-12-15");

    /**
     * Parses the ISO 8601 formated date into a date object, ISO 8601 is YYYY-MM-DD
     * 
     * @param {String} date the date as a string eg 1971-12-15
     * @returns {Date} Date object representing the date of the supplied string
     */
    Date.prototype.parseISO8601 = function(date){
        var matches = date.match(/^\s*(\d{4})-(\d{2})-(\d{2})\s*$/);

        if(matches){
            this.setFullYear(parseInt(matches[1]));    
            this.setMonth(parseInt(matches[2]) - 1);    
            this.setDate(parseInt(matches[3]));    
        }

        return this;
    };

回答by Gabriel

I always store my date in UTC time.

我总是以 UTC 时间存储我的日期。

This is my own function made from the different functions I found in this page.

这是我自己的函数,由我在此页面中找到的不同函数组成。

It takes a STRING as a mysql DATETIME format (example : 2013-06-15 15:21:41). The checking with the regex is optional. You can delete this part to improve performance.

它采用 STRING 作为 mysql DATETIME 格式(例如:2013-06-15 15:21:41)。使用正则表达式进行检查是可选的。您可以删除此部分以提高性能。

This function return a timestamp.

此函数返回一个时间戳。

The DATETIME is considered as a UTC date. Be carefull : If you expect a local datetime, this function is not for you.

DATETIME 被视为 UTC 日期。注意:如果您期望本地日期时间,则此功能不适合您。

    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();
    }

回答by Martin Zeitler

Here's a code snippet that fixes that behavior of IE (v['date'] is a comma separated date-string, e.g. "2010,4,1"):

这是修复 IE 行为的代码片段(v['date'] 是逗号分隔的日期字符串,例如“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']);
}

The previous approach didn't consider that JS Date month is ZERO based...

之前的方法没有考虑到 JS 日期月份是基于零的......

Sorry for not explaining too much, I'm at work and just thought this might help.

抱歉没有解释太多,我正在工作,只是认为这可能会有所帮助。

回答by valli

Send the date text and format in which you are sending the datetext in the below method. It will parse and return as date and this is independent of browser.

使用以下方法发送日期文本和格式。它将解析并返回为日期,这与浏览器无关。

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);
}

回答by xin

Here's my approach:

这是我的方法:

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

replace ('-')with the delimeter you're using.

替换('-')为您正在使用的分隔符。

回答by richardtallent

The Date constructor in JavaScript needs a string in one of the date formats supported by the parse() method.

JavaScript 中的 Date 构造函数需要 parse() 方法支持的日期格式之一的字符串。

Apparently, the format you are specifying isn't supported in IE, so you'll need to either change the PHP code, or parse the string manually in JavaScript.

显然,IE 不支持您指定的格式,因此您需要更改 PHP 代码,或在 JavaScript 中手动解析字符串。

回答by isaranchuk

You can use the following code to parse ISO8601 date string:

您可以使用以下代码解析 ISO8601 日期字符串:

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