Universal Countdown Script
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).
Demos:
Example 1
Example 2
Example 3
Example 4: Universal Count Down Wall
Step 1: Insert the below script into the HEAD section of your page:
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:
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 countDownLocalTim
e
following the markup:
<span id="nylondon2019"></span> left until New Years 2019 in London, England <script> 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 </script>
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:
-
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
" - 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 } else{ 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 fromtimeleft.years()
all the way down totimeleft.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 theduration()
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!!" } else{ 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.