Javascript日期解析错误 - 6月的日期失败(??)

Kip*_*Kip 6 javascript parsing date

我有一些解析ISO-8601日期的JavaScript.出于某种原因,6月份的日期失败了.但7月和5月的日期工作正常,这对我来说没有意义.我希望一双新的眼睛会有所帮助,因为我无法看到我在这里做错了什么.

功能定义(带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;
}
Run Code Online (Sandbox Code Playgroud)

测试代码

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());
Run Code Online (Sandbox Code Playgroud)

产量

  • 2009年5月9日星期六格林威治标准时间12:30:00
  • 星期四,2009年7月9 日12:30:00 GMT
  • 星期四,2009年7月9日12:30:00 GMT

更新

感谢快速回答,问题是Date对象最初是今天,恰好是7月31日.当月份设置为6月,在我改变那天之前,它暂时是6月31日,已经推进到7月1.

我已经发现以下是一个更清晰的实现,因为它一次设置所有日期属性:

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;
}
Run Code Online (Sandbox Code Playgroud)

Gra*_*ner 13

问题是今天是7月31日.

当你设置:

var date = new Date();
Run Code Online (Sandbox Code Playgroud)

然后date.getUTCDate()是31.当您设置date.setUTCMonth(5)(6月)时,您将设置date6月31日.由于没有6月31日,JavaScript Date对象将其转换为7月1日.所以在设定通话后立即date.setUTCMonth(5)如果你alert(date.getUTCMonth());6.

这不是六月独有的.对于没有31天的任何其他月份,在任何月份的31日使用您的功能都会出现同样的问题.在2月29日(非闰年),任何月份的30日或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));
Run Code Online (Sandbox Code Playgroud)

  • 另外,如果我将日期初始化为"新日期(0)",则可以(因为那是'1970-01-01T00:00:00-00:00') (2认同)

Gre*_*reg 5

日期对象以当前日期开始.这是今天的第31场所以设置2009-06-09给出:

var date = new Date();     // Date is 2009-07-31
date.setUTCFullYear(2009); // Date is 2009-07-31
date.setUTCMonth(6 - 1);   // Date is 2009-06-31 = 2009-07-01
date.setUTCDate(9);        // Date is 2009-07-09
Run Code Online (Sandbox Code Playgroud)

如果您在开始之前将日期设置为1,那么您应该是安全的.