Milos Sretin
Milos Sretin

Reputation: 1748

Javascript countdown every day

I need to make countdown timer for every day to 21:00. Counting till live stream. If time is less then 21:00 display the time left and if time is from 21:00-22:00 I would like to display 'streaming right now'. After 22:00 start counting till tomorrow at 21:00.

Any suggestins how to do this?

Here is what I tried so far but it doesn't work well and also if client change the time on his computer the counter will change. I need to fix that on server side so for everyone it will show the same time.

    <script type="text/javascript">
        $(document).ready(function(){
            var curT, tarT, difT;

            curT = new Date().getTime()/1000;
            tarT = new Date('<?php echo (new DateTime('May 05, 2014'))->add(new DateInterval("P1D"))->format('M d, Y');?>, 21:00:00').getTime()/1000;

            init();

            function init(){
                var d,h,m,s;
                difT = tarT - curT;
                function updateT(){
                    s = difT;
                    d = Math.floor(s/86400);
                    s -= d * 86400;
                    h = Math.floor(s/3600);
                    s -= h * 3600;
                    m = Math.floor(s/60);
                    s -= m * 60;
                    s = Math.floor(s);
                }
                function tick(){
                    clearTimeout(timer);
                    updateT();
                    displayT();
                    if(difT>0){
                        difT--;
                        timer = setTimeout(tick,1*1000);
                    } else {
                        $('.timeleft').html('Aukcija u toku...');
                    }
                }
                function displayT(){
                    var out;
                    out = h+":"+m+":"+s;
                    $('.timeleft').html(out);
                }
                var timer = setTimeout(tick,1*1000);
            }
        });
    </script>

Upvotes: 1

Views: 5642

Answers (4)

Hannes Schneidermayer
Hannes Schneidermayer

Reputation: 5785

Since you need a combination of both scripts from above, I combined them for you: http://jsfiddle.net/69TAf/

  • Reads out the real time from GMT Server
  • Clients timezone doesn't matter
  • GMT Server is only pinged once at beginning (for better performance)
  • Added leading zeros so it looks better

Credits to edcs and Miskone!

var date;
var display = document.getElementById('time');

$(document).ready(function() {
    getTime('GMT', function(time){
        date = new Date(time);
    });    
});

setInterval(function() {
    date = new Date(date.getTime() + 1000);

    var currenthours = date.getHours();
    var hours;
    var minutes;
    var seconds;
    if (currenthours != 21){
        if (currenthours < 21) {
            hours = 20 - currenthours;
        } else {
            hours = 21 + (24 - currenthours);
        }
        minutes = 60 - date.getMinutes();
        seconds = 60 - date.getSeconds();

        if (minutes < 10) {
            minutes = '0' + minutes;
        }
        if (seconds < 10) {
            seconds = '0' + seconds;
        }

        display.innerHTML = hours + ':' + minutes + ':' +seconds;
    } else { 
        display.innerHTML = 'LIVE NOW';
    }
}, 1000);

function getTime(zone, success) {
    var url = 'http://json-time.appspot.com/time.json?tz=' + zone,
        ud = 'json' + (+new Date());
    window[ud]= function(o){
        success && success(new Date(o.datetime));
    };
    document.getElementsByTagName('head')[0].appendChild((function(){
        var s = document.createElement('script');
        s.type = 'text/javascript';
        s.src = url + '&callback=' + ud;
        return s;
    })());
}

And html:

<div id='time'></div>

If you don't want to ping an external server for getting the time, you can use this fiddle (not working on jsfiddle, since contains php): http://jsfiddle.net/qQ6V3/ - I think it's even better this way.

Upvotes: 2

RobG
RobG

Reputation: 147523

Lots of answers, one more won't hurt. :-)

I think you are best to pass the start and end of streaming to the client as a UNIX UTC time values in seconds. Then the client can turn that into a local date and count down to that. Using a network time server sounds good, but it means that everyone must use the same time server and you are reliant on the server being available.

if you're going to pass a time at all, it might as well be the start and end according to your server. You can even pass the current time from the server and calculate a time offset to apply at the client. Anyhow, the code…

<script>

var countDown = (function() {
  var startStream;
  var endStream;
  var streamingText = 'streaming right now';
  var updateElement;

  // Pad single digit numbers
  function pad(n) {
    return (n<10?'0':'') + +n;
  }

  // Format a time difference as hh:mm:ss
  // d0 and d1 are date objects, d0 < d1
  function timeDiff(d0, d1) {
    var diff = d1 - d0;
    return pad(diff/3.6e6|0) + ':' + pad((diff%3.6e6)/6e4|0) + ':' + pad(diff%6e4/1000|0);
  }

  // start, end are UNIX UTC time values in seconds for the start and end of streaming
  return function(elementId, start, end) {
    var now = new Date();
    var returnValue;

    // By default, run again just after next full second
    var delay = 1020 - now.getMilliseconds();

    // turn start and end times into local Date objects
    if (start) startStream = new Date(start*1000);
    if (end) endStream = new Date(end*1000);

      // If now is after endStream, add 1 day,
      // Use UTC to avoid daylight saving adjustments
      if (now > endStream) {
        endStream.setUTCHours(endStream.getUTCHours() + 24);
        startStream.setUTCHours(startStream.getUTCHours() + 24);
      }

    // Store the element to write the text to
    if (elementId) updateElement = document.getElementById(elementId);

    // If it's streaming time, return streaming text
    if (now >= startStream && now < endStream) {
      returnValue = streamingText;

      // Run again after streaming end time
      delay = endStream - now;

    } else {
      // Otherwise, count down to startStream
      returnValue = timeDiff(now, startStream);
    }

    // Write the time left or streaming text
    updateElement.innerHTML = returnValue;

    // Call again when appropriate
    setTimeout(countDown, delay);
  };
}());


// Testing code

// Create dates for a local time of 21:00 today
var myStart = new Date();
myStart.setHours(21,0,0,0);
var myEnd = new Date()
myEnd.setHours(22,0,0,0);

// Create UNIX time values for same time as UTC
var startUTCTimeValue = myStart/1000|0
var endUTCTimeValue   = myEnd/1000|0

// Run when page loads
window.onload = function() {
  countDown('foo', startUTCTimeValue, endUTCTimeValue);
}

</script>

<div id="foo"></div>

Upvotes: 0

ekans
ekans

Reputation: 1724

you can do something like this :

<div id='time'></div>

and the script :

var display = document.getElementById('time'); 
setInterval(function(){ 
    var date = new Date();
    var currenthours = date.getHours();
    var hours;
    var minutes;
    var secondes;
    if (currenthours != 21){
        if (currenthours < 21)
            hours = 20 - currenthours;
        else hours = 21 + (24 - currenthours);
        minutes = 60 - date.getMinutes();
        secondes = 60 - date.getSeconds();
    display.innerHTML = hours + ':' + minutes + ':' +secondes;
    }
    else display.innerHTML = 'LIVE NOW';
},1000);

fiddle: http://jsfiddle.net/KbM8D/

Upvotes: 0

edcs
edcs

Reputation: 3879

If you need everyone to be counting down from the same time, then you'll need to grab it from a centralised time server. This code does exactly that:

function getTime(zone, success) {
    var url = 'http://json-time.appspot.com/time.json?tz=' + zone,
        ud = 'json' + (+new Date());
    window[ud]= function(o){
        success && success(new Date(o.datetime));
    };
    document.getElementsByTagName('head')[0].appendChild((function(){
        var s = document.createElement('script');
        s.type = 'text/javascript';
        s.src = url + '&callback=' + ud;
        return s;
    })());
}

getTime('GMT', function(time){
    // This is where you do whatever you want with the time:
    alert(time);
});

Source

If you use getTime() instead of grabbing the local time from the client then everyone will be in sync.

Upvotes: 1

Related Questions