【问题标题】:Incrementing date doesnt work as expected in javascript递增日期在 javascript 中无法按预期工作
【发布时间】:2019-09-17 21:31:17
【问题描述】:

在 javascript 中增加日期不能按预期工作。

该功能以前运行良好,但我不知道为什么现在无法运行。

实际结果:
4 月 30 日星期二
5 月 1 日星期三
6 月 1 日星期六
7 月 3 日星期三
8 月 3 日星期六
9 月 4 日星期三
10 月 6 日星期日

预期:
4 月 30 日星期二
5 月 1 日星期三
5 月 2 日星期四
5 月 3 日星期五
5 月 4 日星期六
5 月 5 日星期日
5 月 6 日星期一

var dt = new Date();
var nextDay = new Date(dt);
nextDay.setDate(dt.getDate() + 1);

document.getElementById("datetime1").innerHTML = ("0" + nextDay).substring(1, 12);
nextDay.setDate(dt.getDate() + 2);
document.getElementById("datetime2").innerHTML = ("0" + nextDay).substring(1, 12);
nextDay.setDate(dt.getDate() + 3);
document.getElementById("datetime3").innerHTML = ("0" + nextDay).substring(1, 12);
nextDay.setDate(dt.getDate() + 4);
document.getElementById("datetime4").innerHTML = ("0" + nextDay).substring(1, 12);
nextDay.setDate(dt.getDate() + 5);
document.getElementById("datetime5").innerHTML = ("0" + nextDay).substring(1, 12);
nextDay.setDate(dt.getDate() + 6);
document.getElementById("datetime6").innerHTML = ("0" + nextDay).substring(1, 12);
nextDay.setDate(dt.getDate() + 7);
document.getElementById("datetime7").innerHTML = ("0" + nextDay).substring(1, 12);
nextDay.setDate(dt.getDate() + 8);
pre {
    display: block;
    unicode-bidi: embed;
    font-family: monospace;
    white-space: pre;
}
<pre id="datetime1"></pre>
<pre id="datetime2"></pre>
<pre id="datetime3"></pre>
<pre id="datetime4"></pre>
<pre id="datetime5"></pre>
<pre id="datetime6"></pre>
<pre id="datetime7"></pre>

【问题讨论】:

  • 在这种情况下你应该使用 for-loop。一个小错字可能会破坏您的代码。
  • 我给你做了一个sn-p,所以你有一个minimal reproducible example
  • 旁注:var nextDay = new Date(dt); 不是克隆日期的可靠方法。它在一些 JavaScript 引擎上工作/工作,而不是其他。要可靠地克隆日期,请使用来自getTime(或一元+)的毫秒数:var nextDay = new Date(dt.getTime());var nextDay = new Date(+dt);
  • 如果你的源日期可以有不同的格式,也许使用 moment.js 来格式化日期很有用
  • @AlainIb 对于这个简单的问题,时刻是一个愚蠢的开销

标签: javascript


【解决方案1】:

基本问题是你根据dt更新nextDay

nextDay.setDate(dt.getDate() + 1);

这可能会改变它的月份,然后再重复一遍:

nextDay.setDate(dt.getDate() + 2);

所以:

  • nextDay.setDate(dt.getDate() + 1);:将第 30 天设置为 4 月 29 日,即为 4 月 30 日
  • nextDay.setDate(dt.getDate() + 2);:将第 31 天设为 4 月 30 日,即为 5 月 1 日(4 月只有 30 天)
  • nextDay.setDate(dt.getDate() + 3);:将第 32 天设置为 5 月 1 日,即为 6 月 1 日(5 月只有 31 天)
  • nextDay.setDate(dt.getDate() + 4);:将第 33 天设置为 6 月 1 日,即为 7 月 3 日(6 月只有 30 天)

...等等。将dt.getDate()nextDay.setDate 混合在一起会让您感到困惑,因为dt 会留在四月,而nextDay 会移到下个月。

相反,只需更新相同的日期实例,向前移动 1,并使用循环而不是重复自己:

var dt = new Date();
var nextDay = new Date(+dt);

for (var n = 1; n <= 7; ++n) {
    nextDay.setDate(nextDay.getDate() + 1);
    document.getElementById("datetime" + n).innerHTML = ("0" + nextDay).substring(1, 12);
}
pre {
    display: block;
    unicode-bidi: embed;
    font-family: monospace;
    white-space: pre;
}
<pre id="datetime1"></pre>
<pre id="datetime2"></pre>
<pre id="datetime3"></pre>
<pre id="datetime4"></pre>
<pre id="datetime5"></pre>
<pre id="datetime6"></pre>
<pre id="datetime7"></pre>

旁注:

var nextDay = new Date(dt);

不是克隆日期的可靠方法。它适用于/适用于某些 JavaScript 引擎,*不适用于其他引擎。要可靠地克隆日期,请使用 getTime(或一元 +)中的毫秒自时间值:

var nextDay = new Date(dt.getTime());
// or
var nextDay = new Date(+dt);

我已经在上面做了。


旁注2:

("0" + nextDay).substring(1, 12); 是一种将日期转换为字符串的奇怪方法。我可能会改用 String(nextDay).substring(0, 11) 或日期格式库。

【讨论】:

  • 另外 ("0" + nextDay).substring(1, 12) 可以是 toString 或 toLocaledate
【解决方案2】:

代替

nextDay.setDate(dt.getDate() + 3);

你可以试试

nextDay.setDate(dt.getFullYear(),dt.getMonth(),dt.getDate()+3);

【讨论】:

  • 这行不通。如果您使用setFullYear 而不是setDate,它工作。 (不是我的反对票)-
猜你喜欢
  • 1970-01-01
  • 2016-10-01
  • 2017-03-25
  • 1970-01-01
  • 2014-12-06
  • 1970-01-01
  • 1970-01-01
  • 2021-10-07
  • 1970-01-01
相关资源
最近更新 更多