JavaScript 年中的第几天不更新?

Day of Year does not update in JavaScript?

我有 JavaScript 计算一年中第几天的代码(例如,1 月 1 日为 1,10 月 30 日为 304):

var now = new Date();

//leap year rules:
//  The year must be evenly divisible by 4;
//  If the year can also be evenly divided by 100, it is not a leap year
//  Unless the year is also evenly divisible by 400. Then it is a leap year.

if(now.getUTCFullYear() % 4 == 0){
  //if the year is a leap year:
  if(now.getUTCFullYear() % 100 != 0){
    var day = Math.ceil((now - new Date(now.getFullYear(),0,1)) / 86400000);
    document.getElementById('dayOfYear').innerHTML = day;
  }
  else if(now.getUTCFullYear() % 100 == 0 && now.getUTCFullYear() % 400 == 0){
    var day = Math.ceil((now - new Date(now.getFullYear(),0,1)) / 86400000);
    document.getElementById('dayOfYear').innerHTML = day;
  }
  else{
    var day = Math.ceil((now - new Date(now.getFullYear(),0, 0)) / 86400000);
    document.getElementById('dayOfYear').innerHTML = day;
  }
  
}
else{
  //if the year is NOT a leap year
  var day = Math.ceil((now - new Date(now.getFullYear(),0, 0)) / 86400000);
  document.getElementById('dayOfYear').innerHTML = day;
}

代码每秒刷新一次,因为它是一个时钟应用程序。但是,当时钟在第二天到达 00:00:00 时,一年中的第几天直到数小时后才会更新。可能是什么原因造成的?

谢谢!

您正在使用本地值创建日期,但计算的是 UTC 天数,因此它在 UTC 午夜而不是当地午夜结束。另外,算法太复杂了。只需对所有内容使用 UTC,例如

function getDayOfYear(d = new Date()) {
  // Start of year
  let yearStart = Date.UTC(d.getFullYear(), 0, 1);
  // Get difference to now / ms in one day
  return Math.floor(((Date.UTC(d.getFullYear(), d.getMonth(), d.getDate()) - yearStart)) / 8.64e7) + 1;
}

[new Date(2020,0,1),  // 1 Jan 2020 
 new Date(),          // today
 new Date(2020,11,31) // 31 Dec 2020
].forEach(d => console.log(d.toDateString() + ' is day ' + getDayOfYear(d)));

PS (Date.UTC(d.getFullYear(), d.getMonth(), d.getDate()) 也可以是 (+d + d.getTimezoneOffset() * 6e4),它更短一些,但可能不太可读。

让它在 UTC 午夜结束:

function getUTCDayOfYear(d = new Date()) {
  // Start of year
  let yearStart = Date.UTC(d.getUTCFullYear(), 0, 1);
  // Get difference to now / ms in one day
  return Math.floor(((Date.UTC(d.getUTCFullYear(), d.getUTCMonth(), d.getUTCDate()) - yearStart)) / 8.64e7) + 1;
}

[new Date(Date.UTC(2020,0,1)),  // 1 Jan 2020 UTC
 new Date(Date.UTC(2020,11,31)) // 31 Dec 2020 UTC
].forEach(d => console.log(d.toString() + ' is on UTC day ' + getUTCDayOfYear(d)));