【问题标题】:new Date() set to 31 december 2014 says 1st december insteadnew Date() 设置为 2014 年 12 月 31 日改为 12 月 1 日
【发布时间】:2014-09-09 09:55:15
【问题描述】:

我正在尝试将字符串转换为 Date 对象,它适用于除 12 月 31 日之外的所有日子,其中对象表示 12 月 1 日而不是 31 日。我不知道为什么。这是我的JavaScript 代码:

var dt = new Date();
dt.setDate("31");
dt.setMonth("11");
dt.setFullYear("2014");

但我的变量值是:

Mon Dec 01 2014 11:48:08 GMT+0100 (Paris, Madrid)

如果我对任何其他日期执行相同操作,我的对象将返回到适当的值。你知道我做错了什么吗?

【问题讨论】:

  • 你应该将整数传递给 setMonth 等,而不是字符串。
  • 可以直接使用Date构造函数的参数:new Date(2014, 11, 31)
  • 顺便说一句。不是 11 月 11 日吗?
  • @JuhaUntinen 不,日期混淆了,因为现在月份只有 30 天。

标签: javascript date datetime


【解决方案1】:

问题是,当您先设置一天时,您仍处于当前月份,因此是 9 月。 9 月只有 30 天,所以:

var dt = new Date(); /* today */
dt.setDate("31"); /* 1st Oct 2014 as should be by spec */
dt.setMonth("11"); /* 1st Dec 2014 */
dt.setFullYear("2014"); /* 1st Dec 2014 */

【讨论】:

  • +1 - 这种虫子会在整个 8 月都处于休眠状态,然后在 9 月咬死你 ;)
  • 一次设置一个组件的日期是不正确的,因为有失败的情况是天第一月份第一,可能在 2/29 的第一年。您必须同时设置所有三个字段。
  • +1 它应该是一个可接受的答案,因为它解释了为什么你应该首先设置月份。这是一个非常 JavaScript 的 WTF
  • 在其他语言中应该是相似的,所以不是“javascript WTF”。
  • 为什么日期对象设置不正确时不抛出?
【解决方案2】:

因为你做的第一件事是

dt.setDate(31)

这会将当前日期设置为 31。当前月份是 9 月,它有 30 天,因此将其环绕。

如果您要打印此点之后的日期,则应为 10 月 1 日。

【讨论】:

  • 有趣的是,这只是因为他在一个月内尝试了 30 天才弹出来的。一个月后,它似乎就可以正常工作了。
【解决方案3】:

已经充分解释了该行为的原因以及如何避免它。

但您的代码中真正的错误是您不应该使用默认构造函数:new Date()。您的代码将生成当前时间为 12 月 13 日的日期。我怀疑这是你想要的。您应该使用以年、月和日为参数的 Date 构造函数。

【讨论】:

  • 我想这是对已接受答案的评论?
  • 并非如此。这是对“我做错了什么?”问题的回答
【解决方案4】:

setMonth 应该在 setDate 之前:(31 天以下的月份不安全

var dt = new Date();
dt.setFullYear(2014);
dt.setMonth(11);
dt.setDate(31);

setMonth的第二个参数也可以用来设置日期。

var dt = new Date();
dt.setFullYear(2014);
dt.setMonth(11, 31);


如果没有为构造函数提供参数,它将根据系统设置使用当前日期和时间

因此,单独使用setMonthsetDate 仍然会导致意外结果。

如果设置的值大于其逻辑范围,则该值将自动调整为相邻值

例如,如果今天是2014-09-30,那么

var dt = new Date();
dt.setFullYear(2014); /* Sep 30 2014 */
dt.setMonth(1);       /* Mar 02 2014, see, here the auto adjustment occurs! */
dt.setDate(28);       /* Mar 28 2014 */

为避免这种情况,请直接使用构造函数设置值。

var dt = new Date(2014, 11, 31);

【讨论】:

  • 确实是我才发现的,但对我来说真的没有意义
  • @user2859409 这可能是因为如果您不先设置月份,则需要当前月份,然后有时可能会进入下个月(根据下面 Jakub 的回答)
  • 对于少于 31 天的几个月,我会毫不犹豫地推荐第一个代码块。例如,如果您想将日期设置为 9 月 15 日,但今天是 8 月 31 日,则日期将回到下个月,您最终将得到 10 月 15 日。第二个代码块 +1:那是更好的方式去。我什至不知道 setMonth 的 2 参数形式存在。
  • 注意,设置前一个月也可能是错误的。但是,在这种情况下不是。如果是 10 月 31 日,那么 setMonth(10) 会将日​​期设置为 11 月 31 日,这将换行到 12 月 1 日。 setDate(31) 则结果为 12 月 31 日。因此,请始终使用 2 参数 setMonth()。
  • +1 但我要强调的是,两个月的选择是首选,以防止副作用。
【解决方案5】:

假设您的意图是同时设置年、月和日期,您可以使用longer date constructor

新日期(年、月、日、时、分、秒、毫秒);

[...]

如果提供了至少两个参数,则缺少的参数是 设置为 1(如果缺少一天)或所有其他设置为 0。

所以你会写:

var dt = new Date(2014, 11, 31);

如前所述,一次设置一部分日期可能会导致溢出:

var dt = new Date(2012, 1, 29); // Feb 29 2012
dt.setFullYear(2014);           // Mar 01 2014 instead of Feb 28 2014

此外,将月份设置在日期之前仍然会导致意外溢出(建议更改方法顺序的答案不正确):

var dt = new Date(2014, 0, 31); // Jan 31 2014
dt.setFullYear(2014);           // Jan 31 2014
dt.setMonth(1);                 // Mar 03 2014 instead of Feb 28 2014
dt.setDate(1);                  // Mar 01 2014

【讨论】:

  • 我喜欢这个答案,因为它在顶部为您提供了正确的解决方案,然后解释了为什么损坏的解决方案不起作用......
【解决方案6】:

答案清楚地表明设置日期的正确顺序是:

  • setFullYear()
  • setMonth()
  • setDate()

我只想指出,首先设置年份也很重要,因为闰年​​是 2 月 29 日。

【讨论】:

  • 没有。订单不保证日期设置正确。请参阅下方已接受和投票最多的答案的 cmets。
  • 如果您的开始日期是 31 日,并且您将其设置为天数较少(如 30)的月份,那么您将在下个月结束。所以这还不够。为了安全起见,您应该在设置月份之前将日期设置为不高于 28 的值。最后将日期再次设置为其最终值,如果它更高的话。
【解决方案7】:
var dt = new Date();
dt.setFullYear(2014);
dt.setMonth(11);
dt.setDate(31);

将值作为整数而不是字符串传递..它将返回正确的值..


更新 - 上面的描述不正确..主要问题是你需要把这三行按正确的顺序排列..即使我更正了顺序之后我也忘了更正描述..:P

【讨论】:

  • 不,不是,这是我在 chrome 控制台中的测试: var dt = new Date();未定义的 dt.setDate(31); 1412157761255 dt.setMonth(11); 1417431761255 dt.setFullYear(2014); 1417431761255 dt Mon Dec 01 2014 12:02:41 GMT+0100(巴黎,马德里)
  • 它与参数的类型无关,与序列有关。你提到的序列好像它是次要的东西......
  • 虽然该代码有效,但您给出了错误的解释,原因是什么。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2013-06-20
  • 1970-01-01
  • 1970-01-01
  • 2014-04-26
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多