我一直在使用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
为什么我认为上一个。情况并非如此:我使用交互式调度程序并对其进行了数千次测试,几乎不会注意到这种错误。
最坏的情况: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字段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函数。
另一个更新的更新的问题
我认为这种格式对您而言无法正常工作。在某些情况下它会起作用,但是总是将“ 23rd”这一天解释为一个月,并给您一个无效的日期。这是另一个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()方法解析日期的字符串表示形式,然后
返回自UTC 1970年1月1日00:00:00以来的毫秒数
或NaN(如果字符串无法识别,或者在某些情况下包含
非法的日期值(例如2015-02-31)。
在ES5之前,不建议使用Date.parse。
字符串完全取决于实现。还有很多
不同主机解析日期字符串(因此日期)的方式不同
字符串应该手动解析(如果有很多库可以提供帮助
不同的格式)。
关于javascript - JavaScript无法正确解析日期,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/38534291/