新的日期()设置为2014年12月31日,而不是12月1日

use*_*409 80 javascript datetime date

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

var dt = new Date();
dt.setDate("31");
dt.setMonth("11");
dt.setFullYear("2014");
Run Code Online (Sandbox Code Playgroud)

但我的变量值是:

Mon Dec 01 2014 11:48:08 GMT+0100 (Paris, Madrid)
Run Code Online (Sandbox Code Playgroud)

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

Jak*_*lek 120

问题是,当你先设定一天时,你仍然在当月,所以九月.九月只有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 */
Run Code Online (Sandbox Code Playgroud)

  • +1 - 这是一种在8月份都处于休眠状态的虫子,然后在9月份咬你的屁股;) (22认同)
  • 永远没有权利一次设置一个组件的日期,因为有故障情况,第一天_和_与月首先,_和_可能与第一年2月29日.您必须同时设置所有三个字段. (19认同)
  • +1,它应该是一个公认的答案,因为它解释了为什么你应该先设置月份.这是一个非常javascript的WTF (5认同)
  • 应该与其他语言类似,所以不是"javascript WTF". (2认同)

xda*_*azz 84

setMonth 应该在之前 setDate:( 少于31天的月份不安全)

var dt = new Date();
dt.setFullYear(2014);
dt.setMonth(11);
dt.setDate(31);
Run Code Online (Sandbox Code Playgroud)

并且setMonth第二个参数也可用于设定日期.

var dt = new Date();
dt.setFullYear(2014);
dt.setMonth(11, 31);
Run Code Online (Sandbox Code Playgroud)


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

因此,单独使用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 */
Run Code Online (Sandbox Code Playgroud)

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

var dt = new Date(2014, 11, 31);
Run Code Online (Sandbox Code Playgroud)

  • @ user2859409这可能是因为如果你没有先设置月份,则需要当月,然后可能有时会进入下个月(根据Jakub的答案如下) (15认同)
  • 请注意,在一天之前设置月份也可能是错误的.但不是在这种情况下.如果是10月31日,那么setMonth(10)将日期设置为11月31日,它将包装到12月1日.setDate(31)然后结果是12月31日.所以,总是使用2参数setMonth(). (10认同)
  • 我会毫不犹豫地推荐少于31天的第一段代码.例如,如果您想将日期设置为9月15日,但今天是8月31日,那么日期将回到下个月,您将在10月15日结束.第二个代码块的+1:这是更好的方式去.我甚至不知道`setMonth`的2参数形式存在. (3认同)

fun*_*bro 23

这是因为你做的第一件事就是

dt.setDate(31)
Run Code Online (Sandbox Code Playgroud)

这将当前日期设置为31.当前月份是9月,有30天,所以它将它包裹起来.

如果你打印出这一点之后的日期,那就是10月1日.

  • 有趣的是,这只是突然出现,因为他在一个月内尝试了30天.一个月后,它似乎只是工作正常. (12认同)

Sal*_*n A 13

假设您的意图是同时设置年,月和日期,您可以使用更长的日期构造函数:

新日期(年,月,日,小时,分钟,秒,毫秒);

[...]

如果提供了至少两个参数,则缺少的参数要么设置为1(如果缺少一天),要么设置为0.

所以你会写:

var dt = new Date(2014, 11, 31);
Run Code Online (Sandbox Code Playgroud)

如已经建立的那样,一次设置一部分日期可能会导致溢出:

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

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

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


Flo*_*n F 7

行为的原因以及如何避免这种行为已得到充分解释.

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