Javascript未正确解析日期



我一直在Date原型上使用一些扩展来执行一些操作(建议:不要这样做,它会破坏日期对象;在我当前的项目中对我来说太晚了),最近遇到了比平时更多的问题。

为了解析H:m格式的字符串,我制作了一个自定义函数,并将其分配给Date原型,如下所示:

Date.__parse = Date.parse;
Date.parse = function(string){
    var pattern = /^d{1,2}:d{1,2}/ig;
    var today = new Date();
    if ( pattern.exec(string) ){
        var year = today.getFullYear();
        var month = today.getMonth()+1;
        var day = today.getDate();
        var t = year+"-"+month+"-"+day+" "+string;
        var timestamp = Date.__parse(t);
        return new Date(timestamp);
    }
    else{
        return new Date(Date.__parse(string));
    }
}

当你试图记录日期对象,但直到最近还在工作时,这很糟糕。

有一段时间,Date.parse似乎可以处理"d-m-Y"格式的日期,但最近当我这样做时,它会返回"无效日期"。

主要浏览器解析日期的方式是否发生了变化,或者规范是否发生了一些变化,或者我必须假设错误之前就存在,并且它没有触发"无效日期",因为我很幸运?(我主要使用该函数来验证输入字段,所以它很可能会被忽略)。

我想我将不得不编写自己的日期脚本,并完全忘记js-date对象,这真的很可怕(试图使用moment.js,但我使用它的组件的性能非常差,这就是为什么我必须制作自定义函数)。

编辑

为了更好地理解;

我正在做的事情似乎奏效了:

Date.parse("23-7-2016") // Never got an error, expected 23 Jul 2016

我在跟踪验证错误后发现:

var startDate = Date.parse("23-7-2016");
console.log(startDate.toISOString()); //Got Invalid Date

我认为可能发生了什么

var startDate = Date.parse("12-7-2016"); 
// expected 12 Jul 2016, got 7 Dec 2016, silently fails, everyone is happy

为什么我认为prev。情况并非如此:我使用了一个交互式调度器,并对其进行了数千次测试,这样的错误几乎不会被忽视。

最糟糕的情况是:chrome更新并更改了解析日期的方式。

不确定。。。希望有人能启发我

我已经确定您的方法应该适用于任何有效的输入。您的问题很可能是您的正则表达式在23小时以上和59分钟以上有效。

请参阅我的jsfiddle,它列举了所有有效的输入。https://jsfiddle.net/kLngLL72/4/

在我的示例中,我没有覆盖Date.parse函数以防止该函数的无限嵌套。

Date.__parse = Date.parse;
var dparse = function(string){
    var pattern = /^d{1,2}:d{1,2}/ig;
    var today = new Date();
    if ( pattern.exec(string) ){
        var year = today.getFullYear();
        var month = today.getMonth()+1;
        var day = today.getDate();
        var t = year+"-"+month+"-"+day+" "+string;
        var timestamp = Date.__parse(t);
        return new Date(timestamp);
    }
    else{
        return new Date(Date.__parse(string));
    }
}
$("#data").append("<tr><td>" + dparse("01-01-2016 1:31") + "</td></tr>");
$("#data").append("<tr><td>" + dparse("1-1-2016 0:0") + "</td></tr>");
$("#data").append("<tr><td>" + dparse("1-1-2016 12:59") + "</td></tr>");
$("#data").append("<tr><td>" + dparse("1-1-2016 23:59") + "</td></tr>");
$("#data").append("<tr><td>" + dparse("12-31-2016 1:1") + "</td></tr>");
$("#data").append("<tr><td>" + dparse("12-31-2016") + "</td></tr>");
$("#data").append("<tr><td>" + dparse("12-31-2016 24:0") + "</td></tr>");
$("#data").append("<tr><td>" + dparse("12-31-2016 99:99") + "</td></tr>");
for (var i = 0; i < 24; i++)
{
    for (var j = 0; j < 60; j++)
  {
    $("#data").append("<tr><td>" + dparse("12-31-2016 " + i + ":" + j) + "</td></tr>");
  }
}

更新-新JS FIDDLEhttps://jsfiddle.net/mfe55xun/2/这个新的例子,只在中传递小时和分钟字符串

Date.__parse = Date.parse;
var dparse = function(string){
    var pattern = /^d{1,2}:d{1,2}/ig;
    var today = new Date();
    if ( pattern.exec(string) ){
        var year = today.getFullYear();
        var month = today.getMonth()+1;
        var day = today.getDate();
        var t = year+"-"+month+"-"+day+" "+string;
        var timestamp = Date.__parse(t);
        return new Date(timestamp);
    }
    else{
        return new Date(Date.__parse(string));
    }
}
$("#data").append("<tr><td>" + dparse("99:99") + "</td></tr>");
for (var i = 0; i < 24; i++)
{
    for (var j = 0; j < 60; j++)
  {
    $("#data").append("<tr><td>" + dparse(i + ":" + j) + "</td></tr>");
  }
}

更新

需要注意的是,如果您的输入字符串中包含日期,则常规date.parse将处理具有H:m格式的字符串:

Date.parse("1/2/2016 4:3")

您只需要将"4:3"附加到当前日期字符串中,就可以删除自定义date.parse函数。

更新问题的另一个更新

我认为这种格式对你来说从来都不正确。它在某些情况下会起作用,但它总是会将"23日"解释为一个月,并给你一个无效的日期。这里是另一个jsfiddle示例,它以该格式循环显示所有可能的日期,请注意,只有第1-12天工作。https://jsfiddle.net/mfe55xun/6/

Date.__parse = Date.parse;
var dparse = function(string){
    var pattern = /^d{1,2}:d{1,2}/ig;
    var today = new Date();
    if ( pattern.exec(string) ){
        var year = today.getFullYear();
        var month = today.getMonth()+1;
        var day = today.getDate();
        var t = year+"-"+month+"-"+day+" "+string;
        var timestamp = Date.__parse(t);
        return new Date(timestamp);
    }
    else{
        return new Date(Date.__parse(string));
    }
}
for (var i = 0; i <= 31; i++)
{
    for (var j = 0; j <= 12; j++)
  {
    $("#data").append("<tr><td>" + i + "-" + j + "-2016 = " + dparse(i + "-" + j + "-2016" ) + "</td></tr>");
  }
}

查看结果循环:

test results
0-0-2016 = Invalid Date
0-1-2016 = Invalid Date
0-2-2016 = Invalid Date
0-3-2016 = Invalid Date
0-4-2016 = Invalid Date
0-5-2016 = Invalid Date
0-6-2016 = Invalid Date
0-7-2016 = Invalid Date
0-8-2016 = Invalid Date
0-9-2016 = Invalid Date
0-10-2016 = Invalid Date
0-11-2016 = Invalid Date
0-12-2016 = Invalid Date
1-0-2016 = Invalid Date
1-1-2016 = Fri Jan 01 2016 00:00:00 GMT-0500 (Eastern Standard Time)
1-2-2016 = Sat Jan 02 2016 00:00:00 GMT-0500 (Eastern Standard Time)
1-3-2016 = Sun Jan 03 2016 00:00:00 GMT-0500 (Eastern Standard Time)
1-4-2016 = Mon Jan 04 2016 00:00:00 GMT-0500 (Eastern Standard Time)
1-5-2016 = Tue Jan 05 2016 00:00:00 GMT-0500 (Eastern Standard Time)
1-6-2016 = Wed Jan 06 2016 00:00:00 GMT-0500 (Eastern Standard Time)
1-7-2016 = Thu Jan 07 2016 00:00:00 GMT-0500 (Eastern Standard Time)
1-8-2016 = Fri Jan 08 2016 00:00:00 GMT-0500 (Eastern Standard Time)
1-9-2016 = Sat Jan 09 2016 00:00:00 GMT-0500 (Eastern Standard Time)
1-10-2016 = Sun Jan 10 2016 00:00:00 GMT-0500 (Eastern Standard Time)
1-11-2016 = Mon Jan 11 2016 00:00:00 GMT-0500 (Eastern Standard Time)
1-12-2016 = Tue Jan 12 2016 00:00:00 GMT-0500 (Eastern Standard Time)

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

Date.parse()方法解析日期的字符串表示形式,并且返回自1970年1月1日00:00:00 UTC以来的毫秒数或者NaN,如果字符串未被识别,或者在某些情况下包含非法日期值(例如2015-02-31)。

不建议在ES5之前使用Date.parse,解析字符串完全依赖于实现。还有很多不同主机解析日期字符串的方式不同,因此日期字符串应该手动解析(如果很多要适应不同的格式)。

相关内容

  • 没有找到相关文章

最新更新