JavaScript日期解析错误 - 6月份的日期失败(??) [英] Javascript date parsing bug - fails for dates in June (??)

查看:149
本文介绍了JavaScript日期解析错误 - 6月份的日期失败(??)的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一些JavaScript解析ISO-8601的日期。由于某些原因,6月份的日期不正确。但7月和5月的日期工作正常,这对我来说没有意义。我希望一组新的眼睛会有所帮助,因为我看不到我在这里做错什么。



功能定义(带有错误)



 函数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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆