Javascript 没有正确解析日期

标签 javascript datetime

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

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

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

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

最坏的情况: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 FIDDLE https://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

The Date.parse() method parses a string representation of a date, and returns the number of milliseconds since January 1, 1970, 00:00:00 UTC or NaN if the string is unrecognised or, in some cases, contains illegal date values (e.g. 2015-02-31).

It is not recommended to use Date.parse as until ES5, parsing of strings was entirely implementation dependent. There are still many differences in how different hosts parse date strings, therefore date strings should be manually parsed (a library can help if many different formats are to be accommodated).

关于Javascript 没有正确解析日期,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/38534291/

相关文章:

javascript - 仅当我有两个 <li> 标签时图像才会更改

javascript - 如何检测广告?

php - 确定第二天下午 6 点

php - 按小时分组,然后正确排序 (22-23-0-1-2 ...)

pandas - 从 Pandas 数据框中的日期获取财政年度并添加为新列

javascript - 设置附加到文本区域的字符串的顺序

javascript - Node.js:从字符串读取电子邮件的正则表达式

javascript - 如何调用inner.html中的函数

java - 在android中将字符串转换为日期的最佳方法

c# - 日期比较 - 如何检查是否已经过去 20 分钟?