JavaScript日期解析错误 - 6月份的日期失败(??) [英] Javascript date parsing bug - fails for dates in June (??)
问题描述
功能定义(带有错误)
函数parseISO8601(timestamp)
{
var regex = new RegExp(^([\\d ] {4}) - ([\\\d] {2}) - ([\\\d] {2})T([\\d] {2}):([\\\ \\ [\\\d] {2}):([\\d] {2})([\\ + \\ - \\\d] {2})$);
var matches = regex.exec(timestamp);
if(matches!= null)
{
var offset = parseInt(matches [8],10)* 60 + parseInt(matches [9],10);
if(matches [7] == - )
offset = -offset;
var date = new Date();
date.setUTCFullYear(parseInt(matches [1],10));
date.setUTCMonth(parseInt(matches [2],10) - 1); // UPDATE - 这是错误的
date.setUTCDate(parseInt(matches [3],10));
date.setUTCHours(parseInt(matches [4],10));
date.setUTCMinutes(parseInt(matches [5],10) - offset);
date.setUTCSeconds(parseInt(matches [6],10));
date.setUTCMilliseconds(0);
返回日期;
}
返回null;
}
测试代码
alert(parseISO8601('2009-05-09T12:30:00-00:00')。toUTCString());
alert(parseISO8601('2009-06-09T12:30:00-00:00')。toUTCString());
alert(parseISO8601('2009-07-09T12:30:00-00:00')。toUTCString());
输出
- 2009年5月9日星期六12:30:00 GMT
- 2009年7月 2009年12月30日GMT
- 星期四,09七月2009 12:30:00 GMT
更新
感谢您的快速回答,问题是Date对象最初是今天7月31日。当月份设置为6月,在我更改之前一天,这是暂时的 6月31日,已经推迟到7月1日。
我以后发现以下是一个更干净的实现,因为它一次设置所有的日期属性:
函数parseISO8601(timestamp)
{
var regex = new RegExp(^([\\\d] {4}) - ([\\\d] {2}) - ([\\\d] {2})T([\ \d] {2}):([\\d] {2}):((\\d] {2})([\\ + \\ - \\d] {2}):([\\\d] {2})$);
var matches = regex.exec(timestamp);
if(matches!= null)
{
var offset = parseInt(matches [8],10)* 60 + parseInt(matches [9],10);
if(matches [7] == - )
offset = -offset;
返回新日期(
Date.UTC(
parseInt(matches [1],10),
parseInt(matches [2],10)
parseInt(matches [3],10),
parseInt(matches [4],10),
parseInt(matches [5],10),
parseInt 6],10)
) - offset * 60 * 1000
);
}
返回null;
}
问题是今天是7月31日。
设置时:
var date = new日期();
然后 date.getUTCDate()
是31当您设置 date.setUTCMonth(5)
(6月)时,您将日期
设置为 6月31 。因为没有6月31日,JavaScript Date
对象将它变成 7月1日。所以在设置后调用 date.setUTCMonth(5)
如果你 alert(date.getUTCMonth());
是 6
。
这不是6月唯一的。在任何一个月31日的任何一个月的31天内使用您的功能将不会出现同样的问题。在二十九(非闰年),二月三十日或三十一日的任何月份使用您的功能也将返回错误的结果。
致电 setUTC *()
,使得任何翻转被正确的值覆盖应该解决这个问题:
var date = new Date();
date.setUTCMilliseconds(0);
date.setUTCSeconds(parseInt(matches [6],10));
date.setUTCMinutes(parseInt(matches [5],10) - offset);
date.setUTCHours(parseInt(matches [4],10));
date.setUTCDate(parseInt(matches [3],10));
date.setUTCMonth(parseInt(matches [2],10) - 1);
date.setUTCFullYear(parseInt(matches [1],10));
I have some javascript which parses an ISO-8601 date. For some reason, it is failing for dates in June. But dates in July and May work fine, which doesn't make sense to me. I'm hoping a fresh set of eyes will help, because I can't see what I'm doing wrong here.
Function definition (with bug)
function parseISO8601(timestamp)
{
var regex = new RegExp("^([\\d]{4})-([\\d]{2})-([\\d]{2})T([\\d]{2}):([\\d]{2}):([\\d]{2})([\\+\\-])([\\d]{2}):([\\d]{2})$");
var matches = regex.exec(timestamp);
if(matches != null)
{
var offset = parseInt(matches[8], 10) * 60 + parseInt(matches[9], 10);
if(matches[7] == "-")
offset = -offset;
var date = new Date();
date.setUTCFullYear(parseInt(matches[1], 10));
date.setUTCMonth(parseInt(matches[2], 10) - 1); //UPDATE - this is wrong
date.setUTCDate(parseInt(matches[3], 10));
date.setUTCHours(parseInt(matches[4], 10));
date.setUTCMinutes(parseInt(matches[5], 10) - offset);
date.setUTCSeconds(parseInt(matches[6], 10));
date.setUTCMilliseconds(0);
return date;
}
return null;
}
Test code
alert(parseISO8601('2009-05-09T12:30:00-00:00').toUTCString());
alert(parseISO8601('2009-06-09T12:30:00-00:00').toUTCString());
alert(parseISO8601('2009-07-09T12:30:00-00:00').toUTCString());
Output
- Sat, 09 May 2009 12:30:00 GMT
- Thu, 09 Jul 2009 12:30:00 GMT
- Thu, 09 Jul 2009 12:30:00 GMT
Update
Thanks for the quick answers, the problem was that the Date object was initially today, which happened to be July 31. When the month was set to June, before I changed the day, it was temporarily June 31, which got rolled forward to July 1.
I've since found the following to be a cleaner implementation, as it sets all the date attributes at once:
function parseISO8601(timestamp)
{
var regex = new RegExp("^([\\d]{4})-([\\d]{2})-([\\d]{2})T([\\d]{2}):([\\d]{2}):([\\d]{2})([\\+\\-])([\\d]{2}):([\\d]{2})$");
var matches = regex.exec(timestamp);
if(matches != null)
{
var offset = parseInt(matches[8], 10) * 60 + parseInt(matches[9], 10);
if(matches[7] == "-")
offset = -offset;
return new Date(
Date.UTC(
parseInt(matches[1], 10),
parseInt(matches[2], 10) - 1,
parseInt(matches[3], 10),
parseInt(matches[4], 10),
parseInt(matches[5], 10),
parseInt(matches[6], 10)
) - offset*60*1000
);
}
return null;
}
The problem is that today is July 31.
When you set:
var date = new Date();
Then date.getUTCDate()
is 31. When you set date.setUTCMonth(5)
(for June), you are setting date
to June 31. Because there is no June 31, the JavaScript Date
object turns it into July 1. So immediately after setting calling date.setUTCMonth(5)
if you alert(date.getUTCMonth());
it will be 6
.
This isn't unique to June. Using your function on the 31st of any month for any other month that does not have 31 days will exhibit the same problem. Using your function on the 29th (non-leap years), 30th or 31st of any month for February would also return the wrong result.
Calling setUTC*()
in such a way that any rollovers are overwritten by the correct value should fix this:
var date = new Date();
date.setUTCMilliseconds(0);
date.setUTCSeconds(parseInt(matches[6], 10));
date.setUTCMinutes(parseInt(matches[5], 10) - offset);
date.setUTCHours(parseInt(matches[4], 10));
date.setUTCDate(parseInt(matches[3], 10));
date.setUTCMonth(parseInt(matches[2], 10) - 1);
date.setUTCFullYear(parseInt(matches[1], 10));
这篇关于JavaScript日期解析错误 - 6月份的日期失败(??)的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!