Countdown Timer to New Year’s Day

December 23, 2020
Frontend JavaScript

Hi! It’s been a while. I’ve been out of the loop for quite some time, but I’m back, and looking forward to the New Year because 2020 has been a lot less fun than everyone hoped it would be. In that spirit, I made a countdown timer, with New Year’s Day as the penultimate date. Bonus, it’s part of the CodePen Challenge!

For starters, we need to find how much time is between now and the new year. We can do this by setting two new Date objects in JS – one for “now” (initialized just by creating the new object) and one for the future date that we’ll call “newYears”, initialized by setting the year as this year + 1, the month as January, and the day as the first. We’ll use the getFullYear() function from the now variable and add one to it to get the next year. This will make this countdown applicable in any year, not just for 2021.

//the present time
var now = new Date();

//the future time
var newYears = new Date(now.getFullYear() + 1, 0, 1);

Converting the Time Components

Now that we’ve got that set, we need to (1) find the difference in time and (2) break down that difference into the components. We can’t just have our countdown timer count milliseconds, we want it broken down in to days, hours, minutes, and seconds – not everybody can quantify what 1595672993 milliseconds is! We’ll start by subtracting now from newYears. Since the date object constructor returns a number in milliseconds, the difference will be in milliseconds. We need to count how many days, hours, minutes, and seconds are in there. To do that, we’ll divide by 1000 to get the difference in seconds, then use the return to calculate the minutes by dividing by 60. We’ll base the calculation of the hours on the return for the minutes and divide by another 60, then divide the hours by 24 to get the amount of days. Whew. Mind you, all we’re doing is counting the amount of each in the calculation, we’re not deprecating the value at all, so simply using these numbers to try to represent the amount of time is not feasible. We’re just doing conversions here.
Of course, we’ll have to invoke the Math().floor() function to round off the number so that it is not a decimal. We’ll deal with the decimals in further calculations.

var diff = newYears - now;

var seconds = Math.floor(diff / 1000);
var minutes = Math.floor(seconds/60);
var hours = Math.floor(minutes/60);
var days = Math.floor(hours/24);

Calculating the Time Components

Now that we’ve done all the conversions, we’ve got to deprecate each value so that we’re not double counting things. Right now, if we just used the values we have, we’d have the same value represented in 4 different ways. What we need to do is deprecate the base value each time we calculate a value. We calculated the days accurately already, so we don’t need to deprecate the base value for that again.
This part took me a while to understand. Basically, if we just use what we have now, what we’ll have is the same value represented in 4 divisions. When writing this, on December 13th at about noon, these are the values I’d have at this point: 18:443:26627:1597672 18 days = 442 hours (about, there is rounding happening) = 26627 minutes = 1597672 seconds. You can see we’re just counting the same number in different values here. We need to take this and convert, then remove that converted number from the variable that we’re basing our conversion on. You’ll see on the “seconds” equation, we’re removing the remainder. Not doing this will lead to a decimal, which is fine, but I didn’t want it for display reasons.

hours = hours - (days * 24);
minutes = minutes - (days * 24 * 60) - (hours * 60);
seconds = (seconds - (days * 24 * 60 * 60) - (hours * 60) - (minutes * 60)) % 60;

Reading and Formatting

So that’s the base of it. We now know how long we have until the new year. We can show this by logging the number, as a string.

console.log(days + " days, " + hours + " hours, " + minutes + " minutes, " + seconds + " seconds until New Years 2021");

//gives you
18 days, 11 hours, 35 minutes, 56 seconds until New Years 2021

Wrapping it up and running it every second

You can format it however you want. I took this a step further and built a simple display, made it a little prettier than just plain text, formatted the numbers a little bit, and made it update the screen every second.
We’ll start by wrapping what we’ve done in a function, and calling it every second (1000 milliseconds, which is the argument that the setInterval function accepts.

setInterval(init, 1000)
function init() {
  var now = new Date();
  var newYears = new Date(now.getFullYear() + 1, 0, 1);
  var diff = newYears - now;
  var seconds = Math.floor(diff / 1000);
  var minutes = Math.floor(seconds/60);
  var hours = Math.floor(minutes/60);
  var days = Math.floor(hours/24);

  hours = hours - (days * 24);
  minutes = minutes - (days * 24 * 60) - (hours * 60);
  seconds = (seconds - (days * 24 * 60 * 60) - (hours * 60) - (minutes * 60)) % 60;

  console.log(days + " days, " + hours + " hours, " + minutes + " minutes, " + seconds + " seconds until New Years 2021");
}

Attaching to DOM

Now, every second, logged to the console will be a slightly formatted reading of the time remaining. We can make this a little better by attaching to the DOM instead of printing to the console. We can also regulate the amount of text to include leading zeros. This will ensure that there are always two characters in the final value. We’ll do this by checking if the value is less than 10. If it is, we’ll attach a leading zero to the string converted value. If not, we’ll just convert it to a string. Then, we’ll attach the string to the DOM.

function init() {
...
...
  days < 10 ? days = '0' + days.toString() : days = days;
  hours < 10 ? hours = '0' + hours.toString() : hours = hours;
  minutes < 10 ? minutes = '0' + minutes.toString() : minutes = minutes;
  seconds < 10 ? seconds = '0' + seconds.toString() : seconds = seconds;

  document.getElementById('days').innerText = days;
  document.getElementById('hours').innerText = hours;
  document.getElementById('mins').innerText = minutes;
  document.getElementById('secs').innerText = seconds;
}

Down below is a pen of all this together. It’s pretty basically styled, but I really wanted to focus on the functionality of the timer. To start blank, I just put “00” in the HTML, which the JS overwrites when the init() function runs.

See the Pen New Year’s Countdown by Nate Northway (@the_Northway) on CodePen.

No Comments...yet

Leave a Reply

Your email address will not be published. Required fields are marked *

Previous Post

Backdrop-filter: Glassmorphism?

From December 15, 2020

Before finding backdrop-filter, I would make text readable by using Photoshop to darken and blur a background image. This function makes that so much easier

Read This Article
Next Post

jQuery vs. Vanilla JS – or A rant against jQuery

From December 31, 2020

jQuery was a great library upon its release, but since 2006, web APIs have improved. Is jQuery really needed anymore? Is all that weight worth it?

Read This Article