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

时间:2009-07-31 18:55:47

标签: 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;
}

测试代码

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
  • 周一,09 7月 2009年12:30:00 GMT
  • 2009年7月9日星期四12:30:00 GMT

更新

感谢快速解答,问题是Date对象最初是今天,恰好是7月31日。当月份设置为6月,在我改变了一天之前,它暂时 6月31日< / strong>,已推进到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;
}

5 个答案:

答案 0 :(得分:13)

问题是今天是7月31日。

设置时:

var date = new Date();

然后date.getUTCDate()为31.当您设置date.setUTCMonth(5)(6月)时,您将date设置为 6月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));

答案 1 :(得分: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

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

答案 2 :(得分:3)

因为今天是7月31日。格兰特解释了这个问题。以下是我认为更简单的解决方案。在1月1日初始化您的日期。

var date = new Date(2009,0,1,0,0,0);

答案 3 :(得分:0)

这是您更改日期的顺序。 该日期从7月31日开始,因此月份的设置失败,因为6月份没有31。 (实际上它正在延续到jul-1。)

设置完整年份后,添加:

date.setYUTCDate(1);

这是本月的第一个月,其中每个月都有效。

答案 4 :(得分:0)

看起来像个错误?

C:\Documents and Settings\me>java org.mozilla.javascript.tools.shell.Main
Rhino 1.7 release 2 2009 03 22
js> date = new Date();
Fri Jul 31 2009 15:18:38 GMT-0400 (EDT)
js> date.setUTCMonth(5); date.toUTCString();
Wed, 01 Jul 2009 19:18:38 GMT
js> date.setUTCMonth(5); date.toUTCString();
Mon, 01 Jun 2009 19:18:38 GMT
编辑:没关系,我猜。问题已由更有知识的人回答了。