HTML Countdown to Date v3 (Javascript Timer)

Description

  • The following Javascript generator will help you create a countdown clock that will count down the seconds, minutes, hours, days, weeks, years remaining until your target date.
  • This is the third version of this script. Behavior is the same as v2, but the internals are completely rewritten in order to make handling multiple countdowns more efficient and allow for easier drop-in changes.

Note

  • Display Settings
    • Disabled If the number is disabled, it will never be shown. Any amount that exists is passed on to smaller increments. (eg; 4 hours disabled will display as 240 mins instead)
    • Show 0-99+ The number is always shown (even if it is a zero)
    • Show 1-99+ The number is shown if its value is 1 or more (zero is hidden)
    • Show 00-99+ The number is always shown (even if it is a zero). A two-digit number is always shown (for 0-9)
    • Show 01-99+ The number is shown if its value is 1 or more (zero is hidden). A two-digit number is shown for 1-9
  • If you want to change the size, font, or color you can edit the last line of your generated code and add a style="" property like: <div id="countbox1" style="font:14pt Arial; color:#FF0000;"></div>
  • Enabling Milliseconds requires the browser to update the countdown about 40 times every second (when disabled it only runs/updates once per second). Enabling milliseconds uses WAY more processing power, although it shouldn't cause problems unless the computer or browser is very old.

Steps

  1. Fill in the required target Date and target Time information
  2. Fill in how you want your countdown to be displayed
  3. Generate the HTML and JavaScript code for your countdown (button at bottom)
  4. You can preview your script (button at bottom)
  5. Copy and Paste the Source Code into your HTML page


Date Expires
Year:
Month:
Day:
Time Expires
Hour:
Minute:
Second:


Display Settings
NOTE: the default display setting will work for most people
They only need to be changed if you want to customize what is shown
Show Years: Disabled
Show 0-99+
Show 1-99+
Show 00-99+
Show 01-99+
Wording:
singular
plural
Show Weeks: Disabled
Show 0-99+
Show 1-99+
Show 00-99+
Show 01-99+
Wording:
singular
plural
Show Days: Disabled
Show 0-99+
Show 1-99+
Show 00-99+
Show 01-99+
Wording:
singular
plural
Show Hours: Disabled
Show 0-23
Show 1-23
Show 00-23
Show 01-23
Wording:
singular
plural
Show Minutes: Disabled
Show 0-59
Show 1-59
Show 00-59
Show 01-59
Wording:
singular
plural
Show Seconds: Disabled
Show 0-59
Show 1-59
Show 00-59
Show 01-59
Wording:
singular
plural
Show Milliseconds: Disabled
Show .000-.999
 



Source Code:
Your countdown expires: (select Preview first)

Comments

Consolidated answers for changing the text that is generated after timer expires

In expire: function(idxs) change the "Now!" text in line: this.display(this.counts[idxs[x]], "Now!");To whatever you want. Like: this.display(this.counts[idxs[x]], "Party Time");

If you want to forward the user's browser to a new page once the countdown has expired, edit your code and change:
expire: function(idxs){
for(var x in idxs) {
this.display(this.counts[idxs[x]], "Now!");
this.counts.splice(idxs[x], 1);
}
},
to:
expire: function(idxs){
window.location="index2.html";
},
just be aware it is not secure. Anyone can find the new page by looking at the page source. Also, anyone who visits the page with the countdown expired would always get forwarded to index2.html

If you want to show a unique message if the countdown will expire today (less than 24hrs left) inside tick: function() you can replace:
if(amount<0){
expired.push(idx);
}
with:
if(amount < 0){
expired.push(idx);
}
else if(amount < 86400000){// if time remaining is less than one day (60s*60m*24h*1000ms)
this.display(cnt, "Today!");
}
That will show "Today!" messages if less than 24hrs are left, "Now!" if the countdown has expired, and the time remaining if it is more than 24hrs away.

Expanding on the above, you can use any math in the (amount < 86400000) check. The number represents milliseconds.
Example: to show "Finished?" if the time has expired, but it expired less than 120 minutes ago (7200000 milliseconds in the past) use:
if(amount < -7200000){// if time remaining is less than 120 mins (120m*60s*1000ms)
this.display(cnt, "Finished?");
}
else if(amount < 0){
expired.push(idx);
}

Thanks for this great code! I created a table format for outputting the results. Below is what I did.

Replaced:

format: function(r){
var out="";
if(r.d != 0){out += r.d +" "+((r.d==1)?"day":"days")+", ";}
if(r.h != 0){out += r.h +" "+((r.h==1)?"hour":"hours")+", ";}
                out += r.m +" "+((r.m==1)?"min":"mins")+", ";
out += r.s +" "+((r.s==1)?"sec":"secs")+", ";
return out.substr(0,out.length-2);
},

With:
format: function(r){
// Table Format with Digital Readout
var out = "<table cellspacing=0 cellpadding=0 border=0 class=cdTimer>";
out += "<td align=center class='cdTimerTitle cdTimerVLine'>"+((r.d==1)?"DAY":"DAYS")+"</td>";
out += "<td align=center class='cdTimerTitle cdTimerVLine'>"+((r.d==1)?"HR":"HRS")+"</td>";
out += "<td align=center class='cdTimerTitle cdTimerVLine'>MIN</td>";
out += "<td align=center class='cdTimerTitle'>SEC</td><tr>";
out += "<td align=center class='cdTimerDigit cdTimerVLine'>"+ r.d +"</td>";
out += "<td align=center class='cdTimerDigit cdTimerVLine'>"+ r.h +"</td>";
out += "<td align=center class='cdTimerDigit cdTimerVLine'>"+ r.m +"</td>";
out += "<td align=center class='cdTimerDigit'>"+ r.s +"</td></table>";

return out.substr(0,out.length-2);
},

Here is the CSS:
.cdTimer {
  background: -webkit-linear-gradient(90deg, #ccc 2%, white 20%, white 50%, DarkCyan 60%);
  background: -moz-linear-gradient(90deg, #ccc 2%, white 20%, white 50%, DarkCyan 60%);
  background: -ms-linear-gradient(90deg, #ccc 2%, white 20%, white 50%, DarkCyan 60%);
  background: -o-repeating-linear-gradient(90deg, #ccc 2%, white 20%, white 50%, DarkCyan 60%);
  background: -linear-gradient(90deg, #ccc 2%, white 20%, white 50%, DarkCyan 60%);
  border: 1px solid #808080;
  padding: 0 3px;
  border-radius: 5px;
  -moz-border-radius: 5px;
  -webkit-border-radius: 5px;
  }
.cdTimerDigit {
  color: #cc6600;
  font-family: digital-7, arial;
  font-size: 21px;
  }
.cdTimerTitle {
  color: #ffffff;
  font-family: Calibri;
  font-size: 14px;
  padding:0 4px;
  }
.cdTimerVLine {
  border-right:1px solid #808080;
  }

You can change the colors, transitions, etc. to whatever you want. You may need to download and install the digital font or just use a standard font.

It is simple to add additional countdowns. Near the bottom, simply use .add() to add more dates to your countdown. Where the first parameter is the date in the correct format (you can use the generator to create and format additional dates) and the second parameter is the id="" of the additional div where you will display the countdown.

So with the original and two additional countdowns, the very end of the script looks something like:
window.onload=function(){
	var cdown = new CDown();

	cdown.add(new Date(2015,1,18,18,54,36), "countbox1");
	cdown.add(new Date(2014,11,25,18,54,36), "countbox2");
	cdown.add(new Date(2013,11,31,18,54,36), "maple_syrup");
};
</script>
<div id="countbox1"></div>
<div id="countbox2"></div>
<div id="maple_syrup"></div>

If you have another (separate) script that uses an onload event, you'll need to combine them otherwise they'll overwrite each other. It will look something like:
window.onload=function(){ var cdown = new CDown(); cdown.add(new Date(2014,10,20,11,45,46), "countbox1"); startImagePreload(); };
where startImagePreload() is removed from the competing <body onload="startImagePreload();"> onload (or however it was previously inserted into the page).

How would I be able to use this to create two set times everyday for a given calendar of set dates.
So each day the countdown is set and the same times. It would go from Opens in xxxx to Closes in xxx
Also using multiple countdowns for different sessions.

Yes, something like that could be done. If it opens and closes the same time every day, it sounds like you might want something like the HOWTO: Auto countdown daily comment.

[edit] Consolidated answers for automatically resetting the countdown over 'x' intervals. See specific replies for interval.

Replace the original add: function(date,id) with this one:
add: function(date,id){
var nowd=new Date();

//set day of month
if(date.getHours()<nowd.getHours() || (date.getHours()==nowd.getHours()&&date.getMinutes()<=nowd.getMinutes())) date.setDate(nowd.getDate()+1);
else date.setDate(nowd.getDate());

date.setFullYear(nowd.getFullYear());//set year (four digits)
date.setMonth(nowd.getMonth());//set month (from 0-11)

this.counts.push({d:date,id:id});
this.tick();
if(this.state==0) this.init();
},
If the time has passed for today, that will automatically set the countdown day to "tomorrow" at whatever time you originally specified.

Replace the original add: function(date,id) with this one:
add: function(date,id){
var day_of_week = 1;//0=sunday, 6=saturday
var nowd=new Date();

if(nowd.getDay()>day_of_week)day_of_week+=7;
date.setDate(nowd.getDate()+(day_of_week-nowd.getDay()));//sets day of month
date.setFullYear(nowd.getFullYear());//Sets year (four digits)
date.setMonth(nowd.getMonth());//sets month (from 0-11)

this.counts.push({d:date,id:id});
this.tick();
if(this.state==0) this.init();
},
Where day_of_week is the day of the week you want it to count down to (0=Sunday, 3=Wednesday, 6=Saturday). It will automatically reset the countdown each week. If the current day is the same day the countdown will expire and it is AFTER the countdown hour is past, it will show "Now!" until midnight when it rolls over and restarts the countdown.

Replace the original add: function(date,id) with this one:
add: function(date,id){
var day_of_month = 21;// what day of the calendar month to countdown to
var nowd=new Date();

date.setDate(day_of_month);
date.setFullYear(nowd.getFullYear());

if(nowd.getDate()>day_of_month){//if past day of the month, set month+1
date.setMonth(nowd.getMonth()+1);
}
else{//month is current month
date.setMonth(nowd.getMonth());
}

this.counts.push({d:date,id:id});
this.tick();
if(this.state==0) this.init();
},
Where day_of_month is set to the calendar day of the month you want to count down to. That will automatically reset the countdown each month when you pass that day.

Near the bottom, change your cdown.add line so it looks like:
window.onload=function(){
var cdown = new CDown();

cdown.add(new Date((new Date()).getTime()+(40*60*1000)), "countbox1");//40 mins * 60 secs * 1000ms from now
};
Where (40*60*1000) is your own math for how long in milliseconds after the page has loaded until the timer expires. In this case (40*60*1000) = 2400000 milliseconds = 40 minutes after page load.

Can this be used based on say UTC -5? Or 4:00PM EDT New York time? We are using it to count down every day until a certain cut-off shipping time as in "order in the next 4 hours and 12 minutes to have your order shipped today".

There is no good way to determine DST status with only JavaScript. The timezone offset is easy. Replace the default add: function(date,id) with the one below that will count down daily and handle timezone offset:
add: function(date,id){
var nowd=new Date();

//set this to the number of hours offset from UTC
tzOffset = -4;

dx = date.toGMTString();
dx = dx.substr(0,dx.length -3);
tzCurrent=(date.getTimezoneOffset()/60)*-2;
date.setTime(Date.parse(dx))
date.setHours(date.getHours() + tzCurrent - tzOffset);

//set day of month
if(date.getHours()<nowd.getHours() || (date.getHours()==nowd.getHours()&&date.getMinutes()<=nowd.getMinutes())) date.setDate(nowd.getDate()+1);
else date.setDate(nowd.getDate());

date.setFullYear(nowd.getFullYear());//set year (four digits)
date.setMonth(nowd.getMonth());//set month (from 0-11)

this.counts.push({d:date,id:id});
this.tick();
if(this.state==0) this.init();
},
where tzOffset is the UTC offset. But you're still on the hook for manually dealing with DST changing the offset between -4 and -5 for Eastern. You really need access to the server's time to accurately do what you are asking.

To get the most accurate amount of time left, you should do the initial "time left" calculations server-side. So calculate how many SECONDS are between "Now" and your expiration date using a language like PHP or ASP. Then simply set the JavaScript expiration date that many milliseconds (that's why the *1000 is in there) into the future.

Example: in PHP your cdown.add() line should look something like this (where mktime() is your expiration date): cdown.add( new Date((new Date()).getTime() + <?php echo mktime(0,0,0,10,25,2014) - time(); ?>*1000), "countbox1");
In ASP.NET (not confirmed) it should look something like: cdown.add( new Date((new Date()).getTime() + <%=DateDiff("s", DateTime.Now, timeStampFromDatabase) %>*1000), "countbox1");
Advantages
Since this method uses the server to calculate "expires xx seconds from now" this avoids and prevents any issues with timezone differences, Daylight Savings Time, and any issues with the visitor's clock not being correct.

I have a question:

When countdown date/ time 1 expires, I would like it to go to the 2nd date. For example from:
Date 1: November 13 2015 6:00pm. When date/ time expires, I would like it to countdown to the END of that season:
Date 2: January 3th 2016 10:00pm.

Also, I would like it to show a different message:
Date/ time 1 message (during): Season 2015 start:
Date/ time 2 message (during): Time left:
Message when date/ time 2 expires: (blank)

Replace the add: function with this one:
add: function(date,id,prefix){
this.counts.push({d:date,id:id,p:prefix});
this.tick();
if(this.state==0) this.init();
},
Replace the display: function with this one:
display: function(cnt,msg){
document.getElementById(cnt.id).innerHTML=cnt.p+msg;
}
and near the bottom, add your dates and custom message like:
cdown.add(new Date(2014,11,25,0,0,0), "countbox1", "Christmas Starts: ");
cdown.add(new Date(2015,0,1,0,0,0), "countbox2", "New Years Starts: ");

If you want to have a list of countdowns, but only show the next (unexpired) countdown, in the tick: function() there's a part that looks like:
// if time is already past
if(amount<0){
expired.push(idx);
}
// date is still good
else{
this.display(cnt, this.format(this.math(amount)));
}
replace it with:
// use first time still in the future
if(amount>0){
this.display(cnt, this.format(this.math(amount)));
break;
}
and near the bottom when you add your dates, give them the same box id (the "countbox1" part) like:
cdown.add(new Date(2014,11,25,0,0,0), "countbox1");
cdown.add(new Date(2015,0,1,0,0,0), "countbox1");

I was in need of stopping/removing the CDown after a certain amount of time - let's say 30 seconds. So it counts down to the specified date which is some months away but stops after 30 seconds (as if it broke down). I used the following code to stop the counter
window.setTimeout(function(){window.clearInterval(self.interval)}, 30000);

and stuck it in the init: function(){} right below the existing setInterval() line. Sharing incase anyone else has a similar request.

Can the JS be modified to count the time since a date?

In tick: function(){ there is a couple lines that look like:
// if time is already past
if(amount<0){
expired.push(idx);
}
replace it with
// count up for "expire" date
if(amount<0){
amount = now-cnt.d.getTime();
this.display(cnt, this.format(this.math(amount)));
}