JavaScript:意外结果得到一个月中剩余的天数

时间:2018-08-30 01:08:38

标签: javascript date datetime utc

我正在构建一个简单的脚本来显示到月底的天数,以展示对日期在Javascript中的工作方式的理解。也是一样,因为我显然没有。

我想获取当前日期,并将其与该月的最后一天进行比较,以date(this year, this month +1, day 0) - 1 day的形式查看剩余的天数。我可以建立一个数组,告诉它每个月有几天,但是我应该能够使用对日期的内在理解来解决这个问题。

对于预期的产量,本月的最后一天(8月31日)-今天(8月30日)= 1。但是我得到0。

这是我到目前为止所拥有的:

<p id="demo"></p>

<script>
var d = new Date();
var nxt = new Date(d.getFullYear(), d.getMonth() + 1, 0);
nxt.setDate(nxt.getDate() - 1);
document.getElementById("demo").innerHTML = nxt.getDay() - d.getDay();
</script>

目前在AEST中是11点(格林尼治标准时间+ 1000),如果您有任何帮助,请联系我。关键是要做出可以随时随地使用的东西。


我的第一个嫌疑人是时区-我以为如果我使用所有UTC或不使用任何UTC显式信息,这可能会变得均匀。它似乎没有这样做。我曾尝试在不同的范围内查询UTC值,但奇怪的是似乎只能增加不准确性,因此它返回-1。

3 个答案:

答案 0 :(得分:1)

我相信我只是偶然发现了答案-指定日期时 months 的计数范围是0到11,但是 days 的计数范围仍然是1到31。因此,指定

Date(d.getFullYear(), d.getMonth() + 1, 0);

基本上是当月最后一天的简写。然后,下一行是多余的:

nxt.setDate(nxt.getDate() - 1);

这将给出错误的结果,因为它基本上会第二次递减。问题不在于UTC / nonUTC,而是不正确的日期指定。不确定此速记是否会导致其他问题。

答案 1 :(得分:1)

对于想知道为什么零日值会导致这种行为的人,JavaScript... return last available date of calendar提供了一个有用的解释。

以下用于计算当月剩余天数的普通js方法与您所做的工作略有不同,其中简要说明了如何利用月索引和零天来获取当月的最后一天。

const year = 2018;
const month = 7; // months indexed from 0 (Jan) to 11 (Dec)
const day = 30;

// current datetime
let date = new Date(year, month, day);

// add 1 to get next month, set day to 0 to roll it back to last day of current month
let last = new Date(date.getFullYear(), date.getMonth() + 1, 0).getDate();

// difference between last day of the month and input date
let diff = last - date.getDate();

console.log(diff);

下面是一个代码段,您可以在其中尝试不同日期的结果。

const year = document.querySelector('#year');
const month = document.querySelector('#month');
const day = document.querySelector('#day');
const button = document.querySelector('button');
const result = document.querySelector('#result');

const remainDays = (y, m, d) => {
  let date = new Date(y, m, d);
  let last = new Date(date.getFullYear(), date.getMonth() + 1, 0).getDate();
  let diff = last - date.getDate();
  result.textContent = diff;
}

button.addEventListener('click', () => {
  remainDays(year.value, month.value, day.value);
});

remainDays(year.value, month.value, day.value);
div {
  padding: 5px;
  display: flex;
  flex-direction: column;
  max-width: 400px;
}
<div>
  <label for="year">Year</label>
  <input id="year" name="year" type="text" value="2018" />
</div>
<div>
  <label for="month">Month Index</label>
  <input id="month" name="month" type="text" value="7" />
  <span>Enter month index between 0 (Jan) and 11 (Dec)</span>
</div>
<div>
  <label for="day">Day</label>
  <input id="day" name="day" type="text" value="30" />
</div>
<div>
  <button>Get Month Days Remaining</button>
</div>
<div>
  <span>Result:</span>
  <span id="result"></span>
</div>

答案 2 :(得分:0)

您必须记住,在浏览器中,日期始终位于当前系统设置时区。

如果您可以使用moments库,则可以通过提供您可能需要的几乎所有功能来解决所有与日期相关的常见问题

这是datediff示例代码:

var today = new Date(), y = today.getFullYear(), m = today.getMonth();
var lastDay = new Date(y, m + 1, 0);
var diff = lastDay.diff(today, 'days', true);

现在,由于两个日期都是在同一浏览器中创建的,因此它们将具有相同的时区,并且不会产生任何问题。但是,如果说一个日期是从服务器返回的,并用GMT / UTC表示,那么您也需要在同一时区转换另一个日期。再次,moments.js将能够在此提供帮助。