Making a jQuery Countdown Timer

Making a jQuery Countdown Timer

When building a coming soon or event page, you find yourself in search for a good way to display the remaining time. A countdown gives the feel of urgency, and combined with an email field will yield more signups for your newsletter.

Today we are going to build a neat jQuery plugin for displaying a countdown timer. It will show the remaining days, hours, minutes and seconds to your event, as well as an animated updates on every second. Note: the plugin is also available on Github.

Let’s start with the markup!

The HTML

We will give the plugin the creative name of “countdown”. Called on an empty element, it will fill it with the HTML that is needed for the countdown timer. You don’t need to do anything but choose the element in which you want to show it.

Generated markup

<div id="countdown" class="countdownHolder">
	<span class="countDays">
		<span class="position">
			<span class="digit static"></span>
		</span>
		<span class="position">
			<span class="digit static"></span>
		</span>
	</span>

	<span class="countDiv countDiv0"></span>

	<span class="countHours">
		<span class="position">
			<span class="digit static"></span>
		</span>
		<span class="position">
			<span class="digit static"></span>
		</span>
	</span>

	<span class="countDiv countDiv1"></span>

	<span class="countMinutes">
		<span class="position">
			<span class="digit static"></span>
		</span>
		<span class="position">
			<span class="digit static"></span>
		</span>
	</span>

	<span class="countDiv countDiv2"></span>

	<span class="countSeconds">
		<span class="position">
			<span class="digit static"></span>
		</span>
		<span class="position">
			<span class="digit static"></span>
		</span>
	</span>

	<span class="countDiv countDiv3"></span>
</div>

In the above example, the plugin has been originally called on a div with an id of countdown. The plugin has then added a countdownHolder class to it (so a few styles are applied to the element via CSS).

Inside is the markup for the digits. There are two digit spans for every time unit (days, hours, minutes and seconds), which means that you can count down towards a date that is no more than 99 days in the future (for such time frames you should probably not use the timer anyway, it would be discouraging).

The static class of the digits gives them their gradient background and box-shadow. When animated, this class is removed so that these CSS3 touches don’t slow down the animation. The digits are brought together in groups so you can easily style them. Adding a font-size declaration to .countDays, will affect the size of both day digits.

A jQuery Countdown Timer

A jQuery Countdown Timer

The .countDiv spans are the dividers between the units. The colon is formed with :before/:after elements.

But how is this markup generated exactly?

The jQuery

First let’s write two helper functions used by the plugin:

  • init generates the markup you saw above;
  • switchDigit takes a .position span and animates the digits inside it;

Extracting this functionality as separate functions allows us to keep the plugin code clean.

assets/countdown/jquery.countdown.js

	function init(elem, options){
		elem.addClass('countdownHolder');

		// Creating the markup inside the container
		$.each(['Days','Hours','Minutes','Seconds'],function(i){
			$('<span class="count'+this+'">').html(
				'<span class="position">\
					<span class="digit static">0</span>\
				</span>\
				<span class="position">\
					<span class="digit static">0</span>\
				</span>'
			).appendTo(elem);

			if(this!="Seconds"){
				elem.append('<span class="countDiv countDiv'+i+'"></span>');
			}
		});

	}

	// Creates an animated transition between the two numbers
	function switchDigit(position,number){

		var digit = position.find('.digit')

		if(digit.is(':animated')){
			return false;
		}

		if(position.data('digit') == number){
			// We are already showing this number
			return false;
		}

		position.data('digit', number);

		var replacement = $('<div>',{
			'class':'digit',
			css:{
				top:'-2.1em',
				opacity:0
			},
			html:number
		});

		// The .static class is added when the animation
		// completes. This makes it run smoother.

		digit
			.before(replacement)
			.removeClass('static')
			.animate({top:'2.5em',opacity:0},'fast',function(){
				digit.remove();
			})

		replacement
			.delay(100)
			.animate({top:0,opacity:1},'fast',function(){
				replacement.addClass('static');
			});
	}

Great! Now let’s move on with the plugin body. Our plugin must take an object with parameters for better configurability – a timestamp of the period we are counting towards, and a callback function, executed on every tick and passed the remaining time. For brevity, I’ve omitted the functions above from the code.

assets/countdown/jquery.countdown.js

(function($){

	// Number of seconds in every time division
	var days	= 24*60*60,
		hours	= 60*60,
		minutes	= 60;

	// Creating the plugin
	$.fn.countdown = function(prop){

		var options = $.extend({
			callback	: function(){},
			timestamp	: 0
		},prop);

		var left, d, h, m, s, positions;

		// Initialize the plugin
		init(this, options);

		positions = this.find('.position');

		(function tick(){

			// Time left
			left = Math.floor((options.timestamp - (new Date())) / 1000);

			if(left < 0){
				left = 0;
			}

			// Number of days left
			d = Math.floor(left / days);
			updateDuo(0, 1, d);
			left -= d*days;

			// Number of hours left
			h = Math.floor(left / hours);
			updateDuo(2, 3, h);
			left -= h*hours;

			// Number of minutes left
			m = Math.floor(left / minutes);
			updateDuo(4, 5, m);
			left -= m*minutes;

			// Number of seconds left
			s = left;
			updateDuo(6, 7, s);

			// Calling an optional user supplied callback
			options.callback(d, h, m, s);

			// Scheduling another call of this function in 1s
			setTimeout(tick, 1000);
		})();

		// This function updates two digit positions at once
		function updateDuo(minor,major,value){
			switchDigit(positions.eq(minor),Math.floor(value/10)%10);
			switchDigit(positions.eq(major),value%10);
		}

		return this;
	};

	/* The two helper functions go here */
})(jQuery);

The tick function calls itself every second. Inside it, we calculate the time difference between the given timestamp and the current date. The updateDuo function then updates the digits comprising the time unit.

The plugin is ready! Here is how to use it (as seen in the demo):

assets/js/script.js

$(function(){

	var note = $('#note'),
		ts = new Date(2012, 0, 1),
		newYear = true;

	if((new Date()) > ts){
		// The new year is here! Count towards something else.
		// Notice the *1000 at the end - time must be in milliseconds
		ts = (new Date()).getTime() + 10*24*60*60*1000;
		newYear = false;
	}

	$('#countdown').countdown({
		timestamp	: ts,
		callback	: function(days, hours, minutes, seconds){

			var message = "";

			message += days + " day" + ( days==1 ? '':'s' ) + ", ";
			message += hours + " hour" + ( hours==1 ? '':'s' ) + ", ";
			message += minutes + " minute" + ( minutes==1 ? '':'s' ) + " and ";
			message += seconds + " second" + ( seconds==1 ? '':'s' ) + " <br />";

			if(newYear){
				message += "left until the new year!";
			}
			else {
				message += "left to 10 days from now!";
			}

			note.html(message);
		}
	});

});

Of course, for this to work, you will have to include the css and js file from the countdown folder in your page.

Done!

You can use this script as the perfect addition to every launch page. The best thing about it is that it doesn’t use a single image, everything is done with CSS alone. Increasing or decreasing the font size will result in everything scaling nicely, and you only need a display:none declaration to hide the units you don’t need.

Join our newsletter and get our PSDs!19,413 people learn about HTML5, JS and more. Join them!

by Martin Angelov

Martin is a web developer with an eye for design from Bulgaria. He founded Tutorialzine in 2009 and it still is his favorite side project.

138 Comments

  1. Sanchit says:

    Nice Countdown tutorial.I like your site because of clean code.Thanks

  2. Zap! Media says:

    Very nice. Great tutorial.

  3. BaghdadRaza(SMBR) says:

    Nice

  4. Mohamed Tair says:

    Thanks!
    Great tutorial.

  5. Sheets says:

    I am wondering how you could make this a count down to open hours i.e.

    count down to 6am each day Monday-Friday?

    1. Martin Angelov says:

      I won't be able to write the actual code for you, but here are some guidelines.

      To do this consistently across time zones, you will need UTC time. JavaScript provides functions for creating UTC timestamps. The rest would be to check if the current day is Monday-Friday, and if it is, check if it is working hours. If the previous checks fail, you will show the countdown. To calculate how much time there is left, you can use Date()'s arguments and build the timestamp for 6am of the current day; if it is larger than the current timestamp, use it, otherwise add 24*60*60*1000. You will need a special case for Friday - Sunday so you show Monday's open hours.

      Hope this helps.

      1. Nabeel says:

        well my question is how to modify the days and minutes left ?? because by default its 9 days 59 minutes 59 seconds on timer when ever i launch your code

        1. Martin Angelov says:

          You will need to pass a different timestamp to the plugin. In the demo it is set to 10 days in the future by default.

        2. Sky says:

          its in "" assets/js/script.js "" line 10.... 10*24*60*60 ......10 is days here 24 is hours then min and sec.. change that part...

        3. I replaced the whole of line 10 with this:

          ts = (new Date(2012,9,27,4,0,0));

          That way I could set an actual date and it worked quite nicely. :-)

          1. Jackleen says:

            I have a problem when the counter should to have 3 digits in Days not 2 digits.
            i changed the date to ts = new Date(2015, 0, 1). the message below the counter is correct "808 days, 10 hours, 21 minutes and 14 seconds "
            but the first "8" digit not created in the counter. I got 2 digits ONLY 08.

            is there a solution for that?

          2. sam says:

            thanks you richard..

  6. phA says:

    Thanks for great tutorial. Its awesome!

  7. Krzyho says:

    Beautiful! Thanks!

  8. shumail says:

    Nice tutorial. But can you please make a admin panel for ease ? Just type values and select Time Zone, it gets generated automatically ...

  9. Jonathan [JCM] says:

    Poor IE. haha

  10. Vix says:

    Hi,
    I love your timer, and I would love to implement it in a personal project I'm working on.
    Due to my lack of knowledge I can not modify it the way I need it - It has to countdown 10 seconds, from 10 to 0, every time a visitor lands on the page. After that it should redirect to another page. Could you point me towards how it should be done?
    Thanks!

    1. Ethan says:

      Vix this is probably over kill for what you need. If its a standard 10 seconds then you could try and extract just the animation and animate it from 10 to 0 in 10 seconds. You wouldn't need all the math, calculations etc.

  11. Ethan says:

    This is great but the last time I used a countdown timer it was pulling the date from the users computer rather than from the server or somewhere standard.

    We were going to launch the site at a certain time but our friends in Cali informed us that our counter was three hours behind.

    I read through the code but I wasn't sure buy looking at it whether it would count down universally or individually.

    Does it count down universally or individually?

    1. Martin Angelov says:

      The example counts down depending on the users' clock. This can be solved easily - find out what is the UTC time of your event, and use the setUTC functions when building the timestamp that is passed to the plugin. This will show the correct count down across different time zones.

  12. Regnareb says:

    It's not really good, the markup is horrible and you forgot one thing : what to do when Javascript is disabled.
    It's surely a server side operation, but well... just a little note about it would be great.

    1. Martin Angelov says:

      It doesn't make sense to spend time creating semantic markup if it is only going to be generated on the fly by jQuery. Of course you are free to improve it if you wish.

      The countdown is mainly a neat effect. If the user has JS disabled you can as well not show anything in its place.

  13. Keramoti says:

    Great tutorial! But why is it not possible to display more than two digits?

    1. Yuri says:

      Yes, how i can make this plugin to display more than two digits?

  14. kisin says:

    not working on ie8 & ie7

  15. BiBi says:

    nice tutorial

    I love this site because I can download tutorial and see real demo

  16. Lara says:

    This is a pretty heavy amount of both HTML and jQuery (in addition to needing to load the jQuery library). One other option, if you're able to ignore non-modern browsers, is to do it purely with CSS3: http://dyn.com/how-to-create-a-countdown-clock-with-css3/

  17. zonTonk says:

    If refresh page, the time back to 9 day bla bla 59sc, How to make time continuously?

    1. Martin Angelov says:

      This is done on purpose, the demo always shows a date ten days in the future. You can pass an absolute timestamp to the plugin - build a new Date() with the year, month, date, hour, minute and second of your event. This way the script will always be counting down towards the same moment in time.

  18. Sigurd says:

    Nice countdown timer there, just one little thing.
    Is there a way to show 3 digits for days when the countdown is 100 days+ ?

    1. Martin Angelov says:

      It is possible, but the code will need to be reworked. I wanted to keep it simple and have every unit have two digits. I mentioned in the article that if you want to count towards a date that is more than two digits away you probably shouldn't use this script anyway.

      1. Jez says:

        Damn. Shame, especially if you've added a feature for counting down to a new year, which now is over 100 days. Oh well, still looks tidy though

      2. tib says:

        I am newbie, can you give me hints for 3 digits for days?

  19. Thanks Martin! I'd like to use this stuff in my e-wedding project.

  20. 0v3rrid3 says:

    Hi, nice one. Btw I just want to make countdown of hours (not days). I tried to make it count hours, minutes and seconds excluding days but couldn't. Can you provide me the guide?

    Thanks

    1. 0v3rrid3 says:

      Btw I don't want to do this by just hiding the element with css. I am asking from js perspective.
      Thanks :)

  21. can i use this script for a new template and i sell it in theme forest?
    of course i insert author from this site?

  22. Johnny says:

    For a moment I thought that said 'Making a jQuery' and I was like "What?!". :3 Nice tutorial though, once I had figured it out.

  23. Roman says:

    Unfortunately, this doesn't work in IE 9 when it's running in compatibility mode.

  24. ysnbulut says:

    How Make this Count Up ??????????

    1. Emile says:

      Change the if left <0 ...code to

      if(left < 0){
      left = -left;
      }

      Then it continues up after the dead line

  25. dan says:

    hi... i would like to ask you...how to make this countdown for multiple dates

  26. Tommy says:

    I modified the script (More like added onto it... so it is not optimized by any means) to allow so that if there are more than 99 days left. http://pastie.org/3337735

    If someone could optimize this a little ($.each() though there's only one item, update functions consolidated, etc.), feel free to reply to this comment.

    1. Webmaster says:

      useful reply, thanks man :)

    2. Syed Kamran says:

      Hey..

      Tommy Rocks.. !
      love u bro..

      thanks a lot..

    3. Check This Out .....

      $.each(['Days','Hours','Minutes','Seconds'],function(i){
      			
      	if(this == "Days") {
      		$('<span class="count'+this+'">').html(
      		'<span class="position">\
      			<span class="digit static">0</span>\
      		</span>\
      		<span class="position">\
      			<span class="digit static">0</span>\
      		</span>\
      		<span class="position">\
      			<span class="digit static">0</span>\
      		</span>'
      		).appendTo(elem);
      	}else{
      		$('<span class="count'+this+'">').html(
      			'<span class="position">\
      				<span class="digit static">0</span>\
      			</span>\
      			<span class="position">\
      				<span class="digit static">0</span>\
      			</span>'
      		).appendTo(elem);
      		
      	}
      	if(this!="Seconds"){
      		elem.append('<span class="countDiv countDiv'+i+'"></span>');
      	}
      }
      
      1. Integrasolutions says:

        Thank you so much! total life saver!

  27. Webmaster says:

    Very nice tutorial, good job ;)

  28. Joe says:

    This is a fantastic bit of work!

    I'm really new to JavaScript, and I don't know how to set a new timestamp. What file do edit and what line of code?

    Many thanks,

    J.

    1. Martin Angelov says:

      You will have to use the JavaScript date function. An example date would be:

      var ts = new Date(2012,3,21); // 21 April 2012 (months are 0 based)
      

      You then only need to pass the ts variable to the plugin in the js file where it is called.

      1. Quirin says:

        Nice one, Martin. Thank you so much for this. Looks great, works great. And now with correct timing. Just what i needed.

      2. Mohamed says:

        That's what I was looking for :) Thanks a lot

  29. Barry says:

    Really nice, however what is the score about this not working in IE?

  30. Barry says:

    In IE, all the JS seems to be working fine, seems to be an issue in someway with the CSS?

    Anyone else found or have a resolve for this?

  31. Parag says:

    the countdown does not work in IE.

  32. Bayilikler says:

    Beautiful Tutorial...

  33. Lau says:

    how to set the time for the page, means that, this time user login left 8 days, next time the same user login, the time will be auto calculate. in simple word, how to save the countdown time will auto calculate, even the user is logged out

  34. Looks beautiful and exactly what I needed for one of my projects, will give it a spin. Thanks

  35. souvi says:

    superb site for HTML, css tutorial :)

  36. bbbbbbbb says:

    Hi i’ve got this all working fine but am struggling to figure out how to get it to work in ie7 and ie8 – can you please post an update that fixes this? thanks very much

  37. Mohammad says:

    sorry.. it does not work on IE..

  38. Dyzk says:

    Beautiful countdown , thanks for sharing

  39. Felix says:

    IE does not understand the code that appends the digits.

    Line 81:

    $('<span class="count'+this+'">').html(
    	'<span class="position">\
    		<span class="digit static">0</span>\
    	</span>\
    	<span class="position">\
    		<span class="digit static">0</span>\
    	</span>'
    ).appendTo(elem);
    

    I changed it To:

    
    $('<span class="count'+this+'">' +
    	'<span class="position">' +
    		'<span class="digit static">0</span>' +
    	'</span>' +
    	'<span class="position">' +
    		'<span class="digit static">0</span>' +
    	'</span>' +
    '</span>').appendTo(elem);
    

    Looks ugly but works :-)

    1. VC says:

      It worked like a charm.

    2. Mancho says:

      Great, worked perfectly in IE!!
      Good tutorial ;)

  40. Sigurd says:

    Modified the version Tommy upped, so it now displays colons in the right places: http://pastie.org/3547258

    You have to edit the jquery.countdown.css file also, to get the whole countdown on one line:

    .countdownHolder{
    width:500px;

  41. Dhaval says:

    Hi,

    First of all thx for such a nice plugin.
    I've set this for 10 seconds only and after 10 seconds i m sending data by ajax
    and inserting record, now problem is that when it reaches at 0 it continually sends data. Is there any way to stop the process when it reaches at 0 so that i can send data once only.

    Thanks,
    Dhaval

  42. Lbuddha says:

    This is brilliant....thanks so much for this....and thanks for the IE 8 fix, looks fine!

  43. Arthur says:

    How can I set up countdown for every month, hours, minutes and sec works, but days always on 06,

    var note = $('#note'),
    ts = new Date(2012, 12, 31),
    newYear = true;

    if((new Date()) > ts){
    // The new year is here! Count towards something else.
    // Notice the *1000 at the end - time must be in milliseconds
    ts = (new Date()).getTime() +1*24*60*60*1000;
    newYear = false;
    }

  44. Anli says:

    Hi, thanks for this tutorial. I used your plugin for creating another CSS3 countdown timer.

    It's available for download on my site here:
    link

  45. Hugues Joyal says:

    To get the 3 digits working I've update with the following code...

    (function($){
    	
    	// Number of seconds in every time division
    	var days	= 24*60*60,
    		hours	= 60*60,
    		minutes	= 60;
    	
    	// Creating the plugin
    	$.fn.countdown = function(prop){
    		
    		var options = $.extend({
    			callback	: function(){},
    			timestamp	: 0
    		},prop);
    		
    		var left, d, h, m, s, positions;
    
    		// Initialize the plugin
    		init(this, options);
    		
    		positions = this.find('.position');
    		
    		(function tick(){
    			
    			// Time left
    			left = Math.floor((options.timestamp - (new Date())) / 1000);
    			
    			if(left < 0){
    				left = 0;
    			}
    			
    			// Number of days left
    			d = Math.floor(left / days);
    			updateDuo(0, 2, d);
    			left -= d*days;
    			//console.log(d);
    			
    			// Number of hours left
    			h = Math.floor(left / hours);
    			updateDuo(3, 4, h);
    			left -= h*hours;
    			
    			// Number of minutes left
    			m = Math.floor(left / minutes);
    			updateDuo(5, 6, m);
    			left -= m*minutes;
    			
    			// Number of seconds left
    			s = left;
    			updateDuo(7, 8, s);
    			
    			// Calling an optional user supplied callback
    			options.callback(d, h, m, s);
    			
    			// Scheduling another call of this function in 1s
    			setTimeout(tick, 1000);
    		})();
    		
    		// This function updates two digit positions at once
    		function updateDuo(minor,major,value){
    			
    			if(major - minor == 2) {
    				switchDigit(positions.eq(0),Math.floor(value/10/10)%10);
    				switchDigit(positions.eq(1),Math.floor(value/10)%10);
    				switchDigit(positions.eq(2),value%10);
    			}
    			else {
    				switchDigit(positions.eq(minor),Math.floor(value/10)%10);
    				switchDigit(positions.eq(major),value%10);
    			}
    		}
    		
    		return this;
    	};
    
    
    	function init(elem, options){
    		elem.addClass('countdownHolder');
    
    		// Creating the markup inside the container
    		$('<span class="countDays">').html(
    				'<span class="position">\
    				<span class="digit static">0</span>\
    			</span>\
    			<span class="position">\
    				<span class="digit static">0</span>\
    			</span>\
    			<span class="position">\
    				<span class="digit static">0</span>\
    			</span>\
    			<span class="countDiv countDiv0"></span>'
    		).appendTo(elem);
    		
    		$.each(['Hours','Minutes','Seconds'],function(i){
    			$('<span class="count'+this+'">').html(
    				'<span class="position">\
    					<span class="digit static">0</span>\
    				</span>\
    				<span class="position">\
    					<span class="digit static">0</span>\
    				</span>'
    			).appendTo(elem);
    			
    			if(this!="Seconds"){
    				elem.append('<span class="countDiv countDiv'+(i+1)+'"></span>');
    			}
    		});
    
    	}
    
    	// Creates an animated transition between the two numbers
    	function switchDigit(position,number){
    		
    		var digit = position.find('.digit')
    		
    		if(digit.is(':animated')){
    			return false;
    		}
    		
    		if(position.data('digit') == number){
    			// We are already showing this number
    			return false;
    		}
    		
    		position.data('digit', number);
    		
    		var replacement = $('<span>',{
    			'class':'digit',
    			css:{
    				top:'-2.1em',
    				opacity:0
    			},
    			html:number
    		});
    		
    		// The .static class is added when the animation
    		// completes. This makes it run smoother.
    		
    		digit
    			.before(replacement)
    			.removeClass('static')
    			.animate({top:'2.5em',opacity:0},'fast',function(){
    				digit.remove();
    			})
    
    		replacement
    			.delay(100)
    			.animate({top:0,opacity:1},'fast',function(){
    				replacement.addClass('static');
    			});
    	}
    })(jQuery);
    
  46. B2Bict says:

    Internet explorer (7 - 8) fix:

    DEMO
    DOWNLOAD .ZIP

    Now like us on facebook :-)
    link

    1. Nathan says:

      Love this IE fix. Thanks

  47. NickPanov says:

    Here's a each Tuesday / Friday 12 o'clock timer :)

    $(function(){
    	
    	var note = $('#note'),
    		ts = new Date(2012, 0, 1),
    		newYear = true;
    		
    	if((new Date()).getDay() == 1){
    			ts = (new Date()).getTime() - (new Date()).getHours()*3600000 - (new Date()).getMinutes()*60000 - (new Date()).getSeconds()*1000 + 3*12*3600000;
    	}
    	
    	else if((new Date()).getDay() == 2){
    			if((new Date()).getHours() < 12){
    				ts = (new Date()).getTime() - (new Date()).getHours()*3600000 - (new Date()).getMinutes()*60000 - (new Date()).getSeconds()*1000 + 12*3600000;
    			}
    			else {
    				ts = (new Date()).getTime() - (new Date()).getHours()*3600000 - (new Date()).getMinutes()*60000 - (new Date()).getSeconds()*1000 + 7*12*3600000;
    			}
    	}
    	else if((new Date()).getDay() == 3){
    			
    				ts = (new Date()).getTime() - (new Date()).getHours()*3600000 - (new Date()).getMinutes()*60000 - (new Date()).getSeconds()*1000 + 5*12*3600000;
    			
    	}
    	else if((new Date()).getDay() == 4){
    			
    				ts = (new Date()).getTime() - (new Date()).getHours()*3600000 - (new Date()).getMinutes()*60000 - (new Date()).getSeconds()*1000 + 3*12*3600000;
    			
    	}
    	else if((new Date()).getDay() == 5){
    			if((new Date()).getHours() < 12){
    				ts = (new Date()).getTime() - (new Date()).getHours()*3600000 - (new Date()).getMinutes()*60000 - (new Date()).getSeconds()*1000 + 12*3600000;
    			}
    			else {
    				ts = (new Date()).getTime() - (new Date()).getHours()*3600000 - (new Date()).getMinutes()*60000 - (new Date()).getSeconds()*1000 + 9*12*3600000;
    			}
    	}
    	else if((new Date()).getDay() == 6){
    			
    				ts = (new Date()).getTime() - (new Date()).getHours()*3600000 - (new Date()).getMinutes()*60000 - (new Date()).getSeconds()*1000 + 7*12*3600000;
    			
    	}
    	else {
    			
    				ts = (new Date()).getTime() - (new Date()).getHours()*3600000 - (new Date()).getMinutes()*60000 - (new Date()).getSeconds()*1000 + 5*12*3600000;
    			
    	}
    	
    	newYear = false;
    	$('#countdown').countdown({
    		timestamp	: ts,
    		callback	: function(days, hours, minutes, seconds){
    			
    			var message = "";
    			
    			message += days + " " + ( days==1 ? 'ден':'дни' ) + ", ";
    			message += hours + " час" + ( hours==1 ? '':'а' ) + ", ";
    			message += minutes + " минут" + ( minutes==1 ? 'а':'и' ) + " and ";
    			message += seconds + " секунд" + ( seconds==1 ? 'а':'и' ) + " ";
    			
    			if(newYear){
    				message += "left until the new year!";
    			}
    			else {
    				message += "до следващата дата.";
    			}
    			
    			note.html(message);
    		}
    	});
    	
    });
    
  48. I can not make the count is for a specific date.
    if i use it as supplied in the download is only for 10 days and subject to refresh the page and begin again after 10 days.
    If I use the variable as indicated in a comment like this:
    var ts = new Date (yyyy, mm, ss);
    the result of the count does not give the expected result.
    I think all we want to use this final count and we have much knowledge of javascript we can not use it and although not mentioned is what many need never be possible to use it.
    Someone who has used it changed the end date of the count could explain what needs to be modified to work as it should.

  49. Anonymous says:

    I've used the countdown timer here:
    http://promotions.vogue.com.au/driving-front-row-fashion/index.html
    that's being passed through an iframe here:
    http://www.vogue.com.au/
    yet it will not display in IE7 !! (Works fine in FF & Chrome). If you view the first link in IE7, it works perfectly!

    Is this a css issue ? Doctype isue ? Can anybody help please ?

  50. Matias says:

    Do you have implemented it with to count up ?! from ZERO to .. what ever... ?! thanks!!!

  51. Joy says:

    Hey :)
    I like your tutorial. But somehow there are two countdowns on my site. The right one and another one looking like 00:00:00:00 below.
    And is there any possibility to change the time the countdown ends?
    Thanks

  52. Luvmex says:

    It's nice tutorial !!
    but I have same problem with zonTonk
    "If refresh page, the time back to 9 day bla bla 59sc, How to make time continuously?"

    I try to build a new Date() but it still can't work,can you teach more detail about that problem?

    thanks a lot.

  53. roman says:

    Great tutorial! Additional thanks to Felix.

  54. e11world says:

    I'm just wondering what happens when the timer is done. I don't think I saw this anywhere here?

    1. chris says:

      Hello.
      How would I edit the note to read just hours minutes seconds like so 00:00:00

      thanks, Chris

    2. Ramjyoti says:

      if you want any type of changes when timer comes down to 00.00.00.00 then
      on script.js page add below Code just before the line : "note.html(message);"

      if(days==0 && hours==0 && minutes==0 && seconds==0)
      {
      	window.location.replace("http://www.tutorialzine.com");  //to redirect another location
              alert("Times up! "); //to show alert box		
      }
      
  55. mac says:

    I set the script for UTC time ,

    var note = $('#note'),
    ts = new Date.UTC(2012, 0, 1),

    but it doesn't work !

    how to change the date format to universal clock

  56. VC says:

    BTW, if you want to hide the seconds, all you have to do is remove it from the each loop on:

    $.each(['Days','Hours','Minutes','Seconds'],function(i)

    and make the .countDiv2 { display: none !important; }

    Peace

  57. sean says:

    Looks good I'm after something like this how can I change it to repeat the countdown for a weekly countdown.

  58. Amit Kakkar says:

    How to start and stop this timer and...How to perform any particular action on timer end...

  59. shobhit says:

    i have used your code but there is a problem with it,the problem is that when ever i refresh my page timer reset itself.....so please guide me to ride of this problem??

    1. Pamela says:

      I think I also have this problem, did you have any luck with it shobhit?

      Thanks,

  60. Kenan çelik says:

    how setup current date is hour AND miutes ?

    -> ts = new Date(2012, 0, 1), //is that current time?

    And how is setup last time minutes and hours?

    -> last time = new date('2012', 'month', 'day' 'hour','mınute','second');

    and finally how is that multiple timers in one page only chanes last times?

  61. Denny says:

    Is the a fix for Internet Explorer 8, because is does not show the CountDIV. 0 1 &2

    Thankx

  62. Excellent post, gonna give the Demo a whirl!! Thanks!

  63. Garry says:

    I just wanted to say thanks for putting up this tutorial it saved me a lot of time and effort.

    I know at the beginning of your post you mentioned that having more than 99 days in your countdown could be discouraging but I am in situation where I need to display more than 99 days.

    So, I've adjusted the jquery.countdown.js file to do so.

    (function ($) {

    // Number of seconds in every time division
    var days = 24 * 60 * 60,
    hours = 60 * 60,
    minutes = 60;

    // Creating the plugin
    $.fn.countdown = function (prop) {

    var options = $.extend({
    callback: function () { },
    timestamp: 0
    }, prop);

    var left, d, h, m, s, positions;
    var onesIndex, tensIndex;
    var lotsOfDays = false;

    var tickCount = 0;

    // Initialize the plugin
    init(this, options);

    positions = this.find('.position');

    (function tick() {
    tickCount++;

    if (tickCount > 5) {
    left = Math.floor((new Date(2012, 7, 1) - (new Date())) / 1000);
    }
    else {
    // Time left
    left = Math.floor((options.timestamp - (new Date())) / 1000);
    }

    if (left < 0) {
    left = 0;
    }

    // Number of days left
    d = Math.floor(left / days);

    //Determine if we have more than 99 hours in the countdown;
    lotsOfDays = ($('.countDays').children().length > 2);

    if (lotsOfDays) {
    onesIndex = 2;
    tensIndex = 1;
    }
    else {
    onesIndex = 1;
    tensIndex = 0;
    }

    updateDisplay(d, true);

    left -= d * days;

    // Number of hours left
    h = Math.floor(left / hours);
    updateDisplay(h);

    left -= h * hours;

    // Number of minutes left
    m = Math.floor(left / minutes);
    updateDisplay(m);

    left -= m * minutes;

    // Number of seconds left
    s = left;
    updateDisplay(s);

    // Calling an optional user supplied callback
    options.callback(d, h, m, s);

    // Scheduling another call of this function in 1s
    setTimeout(tick, 1000);
    })();

    // This function updates two digit positions at once
    function updateDisplay(value, updatingDays) {
    switchDigit(positions.eq(tensIndex), Math.floor(value / 10) % 10);
    switchDigit(positions.eq(onesIndex), value % 10);

    if (updatingDays)
    if (lotsOfDays) {
    switchDigit(positions.eq(0), Math.round(value * 100 / 10000));
    }

    tensIndex += 2;
    onesIndex = tensIndex + 1;
    }

    return this;
    };

    function init(elem, options) {
    elem.addClass('countdownHolder');

    // Time left
    var left = Math.floor((options.timestamp - (new Date())) / 1000);
    // Number of days left
    var d = Math.floor(left / days);

    // Creating the markup inside the container
    $.each(['Days', 'Hours', 'Minutes', 'Seconds'], function (i) {
    if (this == 'Days' && d > 99) {
    $('<span class="count' + this + '">').html(
    '<span class="position">\
    <span class="digit static">0</span>\
    </span>\
    <span class="position">\
    <span class="digit static">0</span>\
    </span>\
    <span class="position">\
    <span class="digit static">0</span>\
    </span>'
    ).appendTo(elem);
    }
    else {
    $('<span class="count' + this + '">').html(
    '<span class="position">\
    <span class="digit static">0</span>\
    </span>\
    <span class="position">\
    <span class="digit static">0</span>\
    </span>'
    ).appendTo(elem);
    }
    if (this != "Seconds") {
    elem.append('<span class="countDiv countDiv' + i + '"></span>');
    }
    });

    }

    // Creates an animated transition between the two numbers
    function switchDigit(position, number) {

    var digit = position.find('.digit');

    if (digit.is(':animated')) {
    return false;
    }

    if (position.data('digit') == number) {
    // We are already showing this number
    return false;
    }

    position.data('digit', number);

    var replacement = $('<span>', {
    'class': 'digit',
    css: {
    top: '-2.1em',
    opacity: 0
    },
    html: number
    });

    // The .static class is added when the animation
    // completes. This makes it run smoother.

    digit
    .before(replacement)
    .removeClass('static')
    .animate({ top: '2.5em', opacity: 0 }, 'fast', function () {
    digit.remove();
    });

    replacement
    .delay(100)
    .animate({ top: 0, opacity: 1 }, 'fast', function () {
    replacement.addClass('static');
    });
    }
    })(jQuery);

  64. saikiran says:

    Its just awesome. I love your work. But one thing..How can I add "Days" "Hours" "Min" "Sec" text below the numbers? Please let me know where to edit?

    Thanks

  65. capri6 says:

    hi
    I got this plugin from codecanyon, but has been removed from there.
    I'm having trouble with setting the time.
    I have tried to add on the UTC in the script.js - but it stopped working.
    Then I've tried what 'SKY' was mentioning above-still change but to the wrong one.
    Could yoy please explain in simple words how to implement what you said above:

    "This is done on purpose, the demo always shows a date ten days in the future. You can pass an absolute timestamp to the plugin - build a new Date() with the year, month, date, hour, minute and second of your event. This way the script will always be counting down towards the same moment in time."

    Is this in the script.js file?

    much appreciated
    thanks

  66. RAHUL DUBEY says:

    Hi i am using your codes but its showing double times, means hr:min:sec and again hr:min:sec. what can be the reason behind the actual problem..???

  67. jhon says:

    As usual, great tutorial..
    Hope you could do some tutorials about parallax ;)

  68. Hi Martin, I really like your plug-in. I used it in one of my Drupal project and released a Drupal 7 module to the Drupal community that includes your code: http://drupal.org/project/jquery_countdown_timer

  69. Mark says:

    Great post and I think JQuery rocks!!! but I feel that Countdowns are very Passé !!!

  70. Pedro says:

    Hi, if I want to set the start time to 20 hours, 10 minutes, 10 seconds, should I do this line 10 of script.js?<br>
    1*20*10*10*1000 ?

  71. Mark says:

    Very Good coding here and looks nice but I seem to have a problem! if i put 60s in i get 60s out instead of 1 minute?

    Have tried to reinstall the code onto the webpage but no joy!

  72. Lancaster says:

    Thank for this and also to Garry for his additions, very helpful.

  73. Pamela says:

    I seem to have a problem whereby the day element is not ticking over? Anyone else had this problem?

  74. Igor says:

    Hey guys!
    This is my working example are for setting to countdown in format 'UTC'
    http://pastie.org/4780156

    P.S. Sorry for my bad english ;)

  75. loukas says:

    We are using this and it is perfect. I was just wondering how can I hide the countdown timer when it reaches the zero point.

    When it reaches zero it just starts over again :)

    Thanks!

    1. Ollie says:

      Did you get anywhere with this?

  76. Simon says:

    Very useful for a client who needs a countdown until the end of a special offer. Works well! Thanks for the time saver! New to this site. Must check it out more often.

  77. hassan says:

    stop counter:

    if (left>0)
    setTimeout(tick, 1000);

  78. Ollie says:

    This is awesome.

    2 things I`d love to be able to do with it :

    1 - hide itself when it reaches zero

    2 - countdown to a time every week automatically (10 am Monday)

    These would be used in different scenarios, but would be ace.

    Thanks,

    Ollie

    1. Kamal says:

      Hi Ollie,
      Can u please tell how you set countdown to a time every week automatically (10 am Monday)...
      thanks in advance...

  79. Ollie says:

    Really struggling to add a callback. How do i edit this to make it do something when it hits zero?

    var options = $.extend({
    callback : function(){},
    timestamp : 0
    },prop);

  80. Sarath says:

    very nice tutos buddy...great fan and follower of yours..

  81. Hi Martin,

    I really like your work. I am having trouble with IE8 though and unfortunately a very large portion of our web traffic is still using it. Do you have any thoughts or suggestions?

    Thanks in advance,
    Robert

  82. ScoopnHeap says:

    Hey,

    Nice one! I like it more for the animated effects..
    One question, I am just using the seconds and hid other units using display:none as you mentioned..I want to know how I can show a message or hide a div on my page when the counter reaches 0 0 ? It will be great if you can help me out!

    regards

  83. ScoopnHeap says:

    Hi,

    I got it working..
    for others, if you want to hide something or show a different message after the seconds reaches zero

    if(seconds ===0){
    $("#divid").fadeOut(1000);
    }

  84. Pete says:

    Thanks for posting this, slowly working out how to make a timer basic app for Android using PhoneGap and this has given me some useful pointers.

  85. Emilio Basa says:

    Hi,
    This looks like a great countdown timer. Does this timer reset it self everytime a visitor comes to the page? I'm looking for a timer like that.

    Thanks,
    Emilio

  86. myhyazid says:

    Thank you for this cool tutorial!!Thumbs Up!

  87. An all round excellent tutorial. Great screenshots and easy to folllow.

  88. Wayne says:

    There seems to be an issue with it.
    OK, setting the timer to:
    ts = new Date(2013, 2, 19),
    Which will be February 19, 2013
    It displays as: 63 Days
    Even though this is January 14, 2013

    Changing it to
    ts = new Date(2013, 1, 19),
    Which will be January 19, 2013
    Will display 35 days from now.

    So, what would be causing this issue?
    It is like it is a month behind of something.

    Quick response would really be helpful on this one.
    You can see it on our site Crysis For Fanes
    Wayne

    1. ann says:

      I had the same problem. I've put this:
      // Number of seconds in every time division
      var days = 72*90*90,
      hours = 60*60,
      minutes = 60;

  89. gmornob says:

    that's very impressive ! countDown really i like it

  90. gmrm says:

    I'm having a lot of trouble trying to get this countdown to work properly. I'm trying to set a date that I know is 53 days into the future, but this counter is saying it's 83 days into the future. What am I doing wrong?

    1. blah says:

      This will work when days are < 99 - ugly but fixed for now. http://pastie.org/7128926

  91. linkingarts says:

    @wayne, @ann, @gmrm the months start at 0, not one, so you can put 07-1 for July as in (2014,07-1,14) for July 14, 2014 (or just put in 6 for July)

  92. marekma1000 says:

    Martin, BIG thanx for this tutorial - I'll use it on my landing page ;)

  93. TheAL says:

    Is it possible to change it so the numbers just fade into one another without the slide up/down animation? Thanks!

    1. TheAL says:

      Figured it out. Not sure if the fix is appropriate, though. I changed 'top' on line 116 and 128 to 0.

    2. TheAL says:

      Apologies for all of the question. My remaining one is, how would one add extra characters for days? The date to which I am counting down is 500+ days away.

  94. Sam says:

    How i can make it responsive ?? So that it can be possible to view in All Mobile Layout Very Perfectly ?? Can anyone Help ?

  95. I actually wanted to have something, where a user can choose a date from jquery datepicker and set the target date for countdown timer.

    I already have edited the code (http://pastebin.com/NHRuJ5mL) and the output you can see (http://goo.gl/OECkt).

    Actually i put all of your code inside datepicker onSelect option. So when i select a date a timestamp is created and countdown timer is initialized. But the problem is when ever i change the date plugin function is called once again and new instance is created with previous one. That mean it shows two countdown timer in my html page. If i do change the date it shows three countdown timer.

    So i need a system where i will change the date and previous instance will be destroyed and new instance will work. The script is actually calling the plugin function by passing parameter. If i can dynamically pass the parameter hope it will solve the problem.

  96. Kyle says:

    Hi,

    I have an issue in Internet Explorer 9 and 10 where the digits appear as NAN, I am passing in the correct format of Y-m-d so I'm not very sure how this can be resolved, can you offer any solutions?

    Thanks

  97. Matt S says:

    To make it work with IE < = 8 replace jquery.countdown.js with this code.

  98. Mr P says:

    Very nice tutorial, great read and many thanks for the share. I going to try and adapt for a mobile site project :)

  99. Emile says:

    I changed the code so that the target date and event name can be passed as URL parameters in the format http://whatever_domain/countdown/index.html?UTC=201311010800&event=1st November 2014 @ 08:00 UTC time.
    The code also compensates time zones so will work anywhere.

    And when the deadline is reached, it will continue counting up.
    (http://pastie.org/8285807)
    I'm a newbie to jquery and javascript, and I enjoyed a lot doing this and learning.
    Thanks a lot for this!

  100. Mihridcan says:

    It is great work Martin and look very nice, clean code. I'm appreciate to use your countdown timer. Thank You

  101. pbdm says:

    for bug with ie8 just need to Close the element span
    change line 81 to
    $('<span class="count'+this+'"/>').html(

Add Comment

Add a Reply

HTML is escaped automatically. Surround code blocks with <pre></pre> for readability.
Perks:   **bold**   __italics__   [some text](http://example.com) for links