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


79

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

这是函数:

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

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


2
你有你的代码示例一些复制粘贴错误,看看for语句:for(var d=0;d';将提出一个SyntaxError...
基督教C. SALVADO

Answers:


67

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

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

例如:http//jibbering.com/faq/#parseDate

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


编辑: 来自comp.lang.javascript常见问题解答的条目是:扩展ISO 8601本地日期格式YYYY-MM-DD可以通过Date以下方式解析为:

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

谢谢加勒特。您在链接中提供的功能比我所能找到的其他任何功能都要简洁得多,并且可以与我在应用程序的其他99%中使用的日期格式配合使用!比我使用的要一致得多。
踏板

is,这不好,因为许多结构化格式仅使用W3C日期/时间格式(具有完整规格的ISO-8601)。因此,虽然时间戳在许多方面都更好(更简单,更有效,可与所有浏览器一起使用),但通常需要使用javascript解析标准日期/时间数据。我想知道jQuery或类似的语言是否会有更好的解析方法。
StaxMan 2010年

3
感谢您指出,发疯了为什么chrome在ie7说NAN时可以很好地解析日期,jquery的好东西$ .datepicker.parseDate能够解析日期
Carlos Jaime C. De Leon

如果您也想要毫秒级怎么办?
okysabeni

我一直在使用从此代码派生的函数,以便从字符串中解析ISO日期/时间。在极少数情况下,我会在if (month != date.getMonth() + 1)语句中输入看似有效的值,从而使日期无效。例如,2014-06-01T01:09:22.68。您能否解释此if声明的目的?
Grinn 2014年

87

从mysql datetime / timestamp格式:

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

我希望对某人有用。在IE FF Chrome中工作


适用于所有浏览器。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]);对于ES5或更高版本。
Sydwell

15

不要使用“ 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

我们应该使用“ 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();

7

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

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

    / **
     *将ISO 8601格式的日期解析为日期对象,ISO 8601为YYYY-MM-DD
     * 
     * @param {String}将日期作为字符串日期,例如1971-12-15
     * @returns {Date}日期对象,表示提供的字符串的日期
     * /
    Date.prototype.parseISO8601 =函数(日期){
        var matchs = date.match(/ ^ \ s *(\ d {4})-(\ d {2})-(\ d {2})\ s * $ /);

        如果(匹配){
            this.setFullYear(parseInt(matches [1]));    
            this.setMonth(parseInt(matches [2])-1);    
            this.setDate(parseInt(matches [3]));    
        }

        返回这个
    };

2

我总是将日期存储在UTC时间。

这是我自己的功能,由我在本页中找到的不同功能组成。

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

该函数返回一个时间戳。

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

2

这是修复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']);
}

以前的方法不认为JS Date月基于零...

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


1

这是我的方法:

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

('-')您正在使用的分度计替换。


1

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

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

谢谢瓦利。由于他链接的功能较小,因此我使用了Garrett的答案,并使用了我经常使用的日期格式。
踏板

0

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

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


4
那是显而易见的,但是最好知道支持的格式是什么……
StaxMan 2010年

0

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

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


0

我尝试了上述所有解决方案,但对我没有任何帮助。我做了一些头脑风暴,发现了这一点,并且在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);

如果$ format不适用于您,则仅使用format。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.