Day of Year does not update in JavaScript?

Viewed 71

I have JavaScript Code that calculates the day of the year (for example, January 1 would be 1 and October 30 would be 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;
}

The code gets refreshed every second, since it is a clock app. However, when the clock hits 00:00:00 on the next day the Day of the Year does not update until hours later. What might be causing this?

Thanks!

1 Answers

You are creating a Date using local values, but counting UTC days so it ticks over at UTC midnight, not local midnight. Also, the algorithm is way too complex. Just use UTC for everything, e.g.

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()) could also be (+d + d.getTimezoneOffset() * 6e4), which is a little shorter but maybe less readable.

To have it tick over at UTC midnight:

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)));

Related