0

I'm struggling to figure out how Date() works, I found this on the web and wanted to make a countdown that stops at 21:57 UTC Time. It currently displays the message at 21:00 and apears until 22:00.

I tried to add if(currenthours != 21 && currentminutes >= 57){ and always broke it and got the message. I want it to stop 3 minutes before 22:00 and display the message. After it gets to 22:00 restart the countdown for the next day at 21:57.

Any help will be greatly appreciated !

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

setInterval(function(){ 
  date = new Date( );
  var currenthours = date.getUTCHours();
  // alert(currenthours);
  var currentminutes = date.getUTCMinutes();
  // alert(currentminutes);
  var hours;
  var minutes;
  var secondes;
  
  if (currenthours != 21) {

    if (currenthours < 21) {
      hours = 20 - currenthours;
    } else {
      hours = 21 + (24 - currenthours);
    }
    minutes = 60 - date.getUTCMinutes();
    secondes = 60 - date.getUTCSeconds();
    display.innerHTML = ('00' + hours).slice(-2) + ' HOURS ' + '<p>' + 
                        ('00' + minutes).slice(-2) + ' MINUTES ' + '</p>' +
                        ('00' + secondes).slice(-2) + ' SECONDS';
  } else {
    display.innerHTML =  "IT'S 21:57";
  }
},1000);
<div id='time'></div>

Made a fiddle https://jsfiddle.net/5qrs0tcp/1/

This is what I ended up with :

    /*
    |================================|
    |         COUNTDOWN TIMER        |
    |================================|
    */

    // Return the UTC time component of a date in h:mm:ss.sss format
    if (!Date.prototype.toISOTime) {
      Date.prototype.toISOTime = function() {
        return this.getUTCHours() + ':' + 
               ('0' + this.getUTCMinutes()).slice(-2) + ':' +
               ('0' + this.getUTCSeconds()).slice(-2);
      }
    }

    // Return the difference in time between two dates
    // in h:mm:ss.sss format
    if (!Date.prototype.timeDiff) {
      Date.prototype.timeDiff = function(date2) {
        var diff = Math.abs(this - date2);
        return timeobj = {
              hours   : (diff/3.6e6|0),                                    // hours
              minutes : ('0' + ((diff%3.6e6)/6e4|0)).slice(-2),            // minutes
              seconds : ('0' + ((diff%6e4)/1e3|0)).slice(-2)               // seconds
          }
      }
    }

    function countDown() {
      var now = new Date();
      var limitHr  = 19;
      var limitMin = 55;
      var limitDate = new Date(+now);
      // Set limitDate to next limit time
      limitDate.setUTCHours(limitHr, limitMin, 0, 0);

      // var msg = ['Currently: ' + now.toISOTime() + '<br>' + 'Limit: ' + limitDate.toISOTime()];
      var msg = [];
      var diff;

      // If outside limitHr:limitMin to (limitHr + 1):00
      if (now.getUTCHours() == limitHr && now.getUTCMinutes() >= limitMin) {
         msg.push('Countdown stopped'); 

       setTimeout(function(){
        msg = ['Wait for it'];

        var jsonCounter = {
            stats          : msg
        }

        jsonfile.writeFileSync(DailyGamePath, jsonCounter, {spaces: 3});
       },5000);


         var jsonCounter = {
             stats          : msg
         }

         jsonfile.writeFileSync(DailyGamePath, jsonCounter, {spaces: 3});

      } else {

        if (now > limitDate) limitDate.setDate(limitDate.getDate() + 1);

        var jsonCounter = {
            hours      : now.timeDiff(limitDate).hours,
            minutes    : now.timeDiff(limitDate).minutes,
            seconds    : now.timeDiff(limitDate).seconds,
            validating : msg
        }
        jsonfile.writeFileSync(DailyGamePath, jsonCounter, {spaces: 3});

      }
    }

     setInterval(countDown, 1000);

    var daily_status;
    setTimeout( function(){
    setInterval( function() {
    jsonfile.readFile(DailyGamePath, (err, obj) => {
        daily_status={
          hours: obj.hours,
          minutes: obj.minutes,
          seconds: obj.seconds,
          stats: obj.stats,
          validating: obj.validating
        };
        return daily_status;
      });
    }, 1000);
    }, 3000);

    setTimeout( function(){
    io.sockets.on('connection', (socket) => {
       setInterval( function() {
          // var GameStatus=DailyGameStatus();
          socket.broadcast.emit('stream', {hours:daily_status.hours, minutes:daily_status.minutes, seconds:daily_status.seconds, stats:daily_status.stats, validating:daily_status.validating});
       }, 1000);
    });
    }, 3000);
Octavian Lojnita
  • 339
  • 4
  • 15

1 Answers1

1

Date objects are very simple, they're just a time value and some handy methods.

I think your logic just needs to be:

if (currenthours != 21 && currentminutes < 57) {
  // set the out of hours message
} else {
  // time is from 21:57 to 21:59 inclusive
}

The countdown doesn't quite work because you're counting to 00 not to 57, but otherwise there doesn't seem to be an issue.

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

setInterval(function(){
  date = new Date( );
  var currenthours = date.getUTCHours();
  var currentminutes = date.getUTCMinutes();
  var hours;
  var minutes;
  var secondes;
  var limitHr = 5;    // Change these to required values 
  var limitMin = 02;  // Using 5:12 for convenience
  var message  = 'Currently: ' + date.toISOString() + '<p>';

  // Create new message if outside limitHr:limitMin to limitHr:59 inclusive
  if (currenthours != limitHr || currentminutes < limitMin) {

    if (currenthours <= limitHr) {
      hours = limitHr - currenthours;
    } else {
      hours = limitHr + (24 - currenthours);
    }
    
    minutes  = limitMin - date.getUTCMinutes();
    minutes += minutes < 0? 60 : 0; 
    secondes = 60 - date.getUTCSeconds();
    message += ('00' + hours).slice(-2) + ' HOURS ' + '<p>' + 
               ('00' + minutes).slice(-2) + ' MINUTES ' + '</p>' +
               ('00' + secondes).slice(-2) + ' SECONDS';
  } else {
    message += 'It\'s on or after ' + limitHr + ':' + 
                ('0'+limitMin).slice(-2) + ' GMT';
  }
  // Display the message
  display.innerHTML =  message;
},1000);
<div id="time"></div>

Yes, the timer has issues but that wasn't part of the question. For a counter, it's simpler to just work in time differences, so I've added some methods to Date.prototype for ISO time (to be consistent with ISO Date) and time difference, then use those functions.

The function builds a Date for the end time so that calculations can use Date methods.

// Return the UTC time component of a date in h:mm:ss.sss format
if (!Date.prototype.toISOTime) {
  Date.prototype.toISOTime = function() {
    return this.getUTCHours() + ':' + 
           ('0' + this.getUTCMinutes()).slice(-2) + ':' +
           ('0' + this.getUTCSeconds()).slice(-2) + '.' +
           ('00' + this.getUTCMilliseconds()).slice(-3) + 'Z';
  }
}

// Return the difference in time between two dates
// in h:mm:ss.sss format
if (!Date.prototype.timeDiff) {
  Date.prototype.timeDiff = function(date2) {
    var diff = Math.abs(this - date2);
    var sign = this > date2? '+' : '-';
    return sign + (diff/3.6e6|0) + ':' +                   // hours
           ('0' + ((diff%3.6e6)/6e4|0)).slice(-2) + ':' +  // minutes
           ('0' + ((diff%6e4)/1e3|0)).slice(-2) + '.' +    // seconds
           ('00' + (diff%1e3)).slice(-3);                  // milliseconds
  }
}

function countDown() {
  var now = new Date();
  var limitHr  = 1;
  var limitMin = 10;
  var limitDate = new Date(+now);
  // Set limitDate to next limit time
  limitDate.setUTCHours(limitHr, limitMin, 0, 0);
  var msg = ['Currently: ' + now.toISOTime() + '<br>' + 'Limit: ' + limitDate.toISOTime()];
  var diff;

  // If outside limitHr:limitMin to (limitHr + 1):00
  if (now.getUTCHours() != limitHr || now.getUTCMinutes() != limitMin) {
    if (now > limitDate) limitDate.setDate(limitDate.getDate() + 1);
    msg.push(now.timeDiff(limitDate));
  } else {
    msg.push('It\'s after ' + limitHr + ':' + ('0'+limitMin).slice(-2));
  }
  document.getElementById('msgDiv2').innerHTML = msg.join('<br>');
}

window.onload = function() {
 setInterval(countDown, 1000);
}
<div id="msgDiv2"></div>>

I've left the milliseconds in, round to seconds if you wish.

I've left the timer using setInterval, though I'd prefer to use setTimeout and manually calculate the time to just after the next full second so that it never skips. Most browsers using setTimeout will slowly drift so that they skip a second every now and then. Not really an issue unless you happen to see it, or compare it to the tick of the system clock.

RobG
  • 142,382
  • 31
  • 172
  • 209
  • https://jsfiddle.net/5qrs0tcp/3/ ... I don't want it to work for one hour, i want it to work 3-5 minutes .... and because we use currentminutes < 57 it's a complete hour .... – Octavian Lojnita May 18 '16 at 17:08
  • The `&&` should have been `||`. Fixed. – RobG May 19 '16 at 05:15
  • After messing around with it a little more, i noticed that hours do not decrement but instead maintain their number... also because of minutes += minutes < 0 ? 60 : 0; , people can actually see 60 minutes || 60 seconds. Another anoying glich is if infact you have 00 minutes and 59 seconds it will display 01 minutes and 59 seconds instead... it will count down to 01 minutes 00 seconds then it displays the message .... – Octavian Lojnita May 21 '16 at 01:08
  • The timer is really great and from what i noticed setInterval skips rarely. I only have one more question, how can i display a message or multiple messages in a 3-5 minutes time frame before the counter resets 24:00:00, It only displays the message for one minute in the else statement. Should i use an else if statement so that before it matches limitHr and limitMin to display my message? – Octavian Lojnita May 23 '16 at 12:38