FF1+ IE8+ Chrome

Universal Countdown Script

Author: Dynamic Drive

Note (Nov 22nd, 16'): Script rewritten to use moment.js library for built in way to get time zone offsets.

Description: There are basically two types of JavaScript countdown scripts, depending on what you're trying to do. The first type counts down using the time of the visitor's computer, which obviously varies depending on the visitor, and is great for counting down to "relative" events such as Christmas, your friend's birthday etc (See "Dynamic Countdown script"). The second type counts down using a specific local time (ie: Time in New York), and is great for counting down to "absolute" events where the target date/time is tied to a certain time zone, such as the launch date of a web site, the date/time of the next Solar Eclipse, the Tokyo Olympics in 2020 etc.

This is a Universal Countdown script that lets you count down to absolute events, by using the moment.js library to retrieve the corresponding time zone offset for the target date so the count down is relative to the date and time in that location. This script is extremely flexible- you can customize exactly how to display the output, or even specify a custom action to perform at the end of the countdown (ie: go to another page).


Example 1

left until New Years 2019 in London, England

Example 2

left until Christmas 2018 in Vancouver, BC

Example 3

Tokyo Olympics Countdown (Aug 9th, 2020 Tokyo Time)

Example 4: Universal Count Down Wall

Directions: Developer's View

Step 1: Insert the below script into the HEAD section of your page:

Select All

The code references three external libraries, which you should download below:

Step 2: Inside BODY, define a DIV or SPAN tag with a unique ID that will display the count down to the target local date, then invoke "new countDownLocalTime()" to populate it. The following shows the markup and invocation code for the 3 counters above:

Select All

Read on for more details on setting up the script.

Step by Step Setup Guide

To set up a universal count down, first, define a DIV or SPAN that will display the result, then call new countDownLocalTime following the markup:

<span id="nylondon2019"></span> left until New Years 2019 in London, England

var newyearsdiv = document.getElementById("nylondon2019") // reference SPAN for upcoming usage
var uniquevar = new countDownLocalTime("2019-01-01 00:00:00", "Europe/London") // create new instance of countDownLocalTime
uniquevar.oncountdown = function(ms){ // define call back function, called every second until time's up
 // ms contains the number of milliseconds remaining
 // custom code to run every second the counter is ticking down
uniquevar.start() // start count down

In the above case, we define a SPAN with id="nylondon2019" to count down to 2019 New Years (January 2019-01-01) London Time, then create a reference to it by way of variable "newyeardiv" to come back to later.

Here comes the crucial part- following the markup, we invoke a new instance of countDownLocalTime() (with the keyword new proceeding it) to create a count down to the desired target location's date and time, by calling:

var uniquevar = new countDownLocalTime("2019-01-01 00:00:00", "Europe/London")

where uniquevar should be an arbitrary but unique variable to reference this count down instance. Inside countDownLocalTime(), populate it with the following two parameters:

  1. Target Date Time ISO String: The target date and time to count down to in the form of a valid  ISO 8601 string, such as "2019-01-11 15:30:00"
  2. Time Zone ID String: A valid time zone identifier string to specify the time zone of the target location you wish the target date to be based on, such as "Asia/Jakarta".

Once the target date/time and the time zone it's in has been locked in, the remaining two steps are to define our own oncountdown function to handle the data that contains how much time remains, and finally, to call uniquevar.start() to jump start the count down:

uniquevar.oncountdown = function(ms){// custom code to handle time remaining, updated every sec}
uniquevar.start() // start count down

We'd be amiss to not explain oncountdown in more detail, so lets focus on that next.

Defining Your oncountdown event handler to customize the output of the countdown

The oncountdown event handler, once a new instance of countDownLocalTime() has been instantiated, gets called every second until the target date has been reached, and is where you define how to handle and display the count down. Expanding on the instructions above, here is a sample oncountdown event handler that displays the output inside the "nylondon2019" DIV in terms of "days", "hours", "minutes", and "seconds" remaining:

uniquevar.oncountdown = function(ms){
	if (ms <= 0){ // if time's up
		alert("2019 New Years is Upon Us in London!") // do something
		var timeleft = countDownLocalTime.formatDuration(ms, "days") // format time using formatDuration(timeleftms, "baseunit") function
		newyearsdiv.innerHTML = timeleft.days + ' Days ' + timeleft.hours + ' Hours ' + timeleft.minutes + ' Minutes ' + timeleft.seconds + ' Seconds '

The ms parameter always contains the time remaining in milliseconds until the target date. Inside your function, you can check for when ms is below 0 to know when the date has been reached, and act appropriately (such as navigate to a URL).

Formatting the Time left using countDownLocalTime.formatDuration()

Until the ms value reaches 0 or less, we should parse the value into the desired format, and display the output to the user. One such way is to use the built-in function:

countDownLocalTime.formatDuration(ms, "days")

It accepts two parameters, 1) the time remaining, 2) plus the desired base unit,  and returns an object containing the time left in that unit and down to the "seconds" unit. For the desired base unit, enter one of the following strings: "days", "hours", minutes", or "seconds".

Lets say we wish to display the time remaining in terms of hours and downwards. Enter "hours" for countDownLocalTime.formatDuration() second parameter:

var timeleft = countDownLocalTime.formatDuration(ms, "hours")

The function returns the following object:

	days: "n/a"
	hours: 4,
	minutes: 45,
	seconds: 10

The "days" field will contain "n/a" in this case, as it's not being used. The other fields now contain the time left starting with the specified base unit and down to the seconds remaining, cumulatively adding up to the total time left until the target date. With this returned object you can then proceed to easily display the remaining time by referencing each field in your custom code that follows:

newyearsdiv.innerHTML = timeleft.hours + ' Hours ' + timeleft.minutes + ' Minutes ' + timeleft.seconds + ' Seconds '

The above demonstrates the simplest way to output the result, as simply a string of text containing the hours, minutes, and finally, seconds left until the target date.

Formatting the Time left using moment.duration()

Another way to format the ms value that gets passed into the oncountdown event handler is using moment.js's duration() method:

var timeleft = moment.duration(ms)

It takes the time remaining in milliseconds and lets you output the result in two distinct ways:

  • timeleft.humanize(): In a wordy, human friendly form, such as "1 year", "a few hours", "2 minutes" etc.
  • timeleft.years(), timeleft.months() etc: In terms of years, months, days, hours, minutes, and seconds left. Each corresponding field's value is cumulative in addition to the others, starting from timeleft.years() all the way down to timeleft.seconds(), which together add up to the total time left. Each field's value wraps at different values, such as (0-30) for the month field, (0-59) for minutes before the next higher up field gets a +1 added to it instead. See the duration() documentation for more info.

Use moment.duration(ms) for a quick and easy way to display the output as "humanized words", or to display the result with "years" as the top level unit, for example:

uniquevar.oncountdown = function(ms){
	var output = ''
	if (ms <= 0){ // if time's up
		output = "Tokyo Olympics Starts Today!!"
		var timeleft = moment.duration(ms) // format time using moment.js Durations object http://momentjs.com/docs/#/durations/
		if (timeleft.years() > 0) output += timeleft.years() + ' <sup>years</sup> ' // show years left
		output += timeleft.months() + ' <sup>months</sup> ' // show months left (0-11) http://momentjs.com/docs/#/durations/months/
		output += timeleft.days() + ' <sup>days</sup> ' // show days left (0-30) 
		output += timeleft.hours() + ' <sup>hours</sup> ' // show hours left (0-24)
		output += timeleft.minutes() + ' <sup>minutes</sup> ' // show minutes left (0-59)
		output += timeleft.seconds() + ' <sup>seconds</sup> ' // show seconds left (0-59)
	tokyodiv.innerHTML = output

For any other output where the top level unit is "days" or lower, it's probably easier just to turn to the countDownLocalTime.formatDuration() method instead.

Regardless of the way you choose to parse the ms parameter, the takeaway is that the oncountdown event handler is automatically invoked every second until the ms value decrements to 0 or below (whichever comes first). With a little JavaScript chops, you can display the result in a variety of creative ways.