Search code examples
javascripttimercountdown

Countdown timer every hour but on 30 minute marks


I need a simple countdown timer, but it is really bugging me that I can't seem to get it for some reason, and I think it's because of the special way I need it done, it has to adhere to these rules:

  • Must be every hour
  • Must be on the 30 minute mark
  • Must use UTC time

So for instance, it is 07:22 UTC, it would be 8 minutes till the next one.
If it were say, 07:30, it would say 1 hour till the next one.
And last but not least, if it were 07:31, it would say 59 minutes till the next one.

I was able to do this very easily for other countdowns I made, but those were for on the hour type things, it wasn't this complicated... I'm just stumped big time, please help me.

EDIT Added sample code

        var d = new Date();
        var hoursUntil = 2 - d.getUTCHours() % 3;
        var minutesUntil = 60 - d.getUTCMinutes();

        var timestr = "";

        if (minutesUntil === 60) {
            hoursUntil++;
            minutesUntil = 0;
        }

        if (hoursUntil > 0) {
            timestr += hoursUntil + " hour" + (hoursUntil > 1 ? "s" : "");
        }

        if (hoursUntil >= 1 && minutesUntil > 1) {
            timestr += " and " + minutesUntil + " minute" + (minutesUntil > 1 ? "s" : "");
        }

        if (minutesUntil > 1 && hoursUntil < 1) {
            timestr += minutesUntil + " minute" + (minutesUntil > 0 && minutesUntil < 2 ? "" : "s");
        }

        bot.sendMessage(msg, "Next event will be in " + timestr + ".");

Solution

  • Let's do some thoughts. What we want to know is, when the minute hand next time shows 30. If we wanted to know only every half hour, we could just take the rest of division by 30 as you did with d.getUTCHours() % 3.

    However, we want to get every 60 minutes, so we have do do somethingInMinutes % 60. The mark must be on shift from 60 to 0, so just add 30 minutes.

    To have seconds precision, calculate that into seconds, add the current seconds and subtract both from 60 minutes (3600 seconds).

    We want a timer that triggers on every second shift. Calculate the difference of 1000 and milliseconds.

    <div>Seconds remaining until next 30 minutes mark: <span id="min-total"></span></div>
    <div>minutes:seconds remaining: <span id="min-part"></span>:<span id="sec-part"></span></div>
    
    <script>
      var byId = document.getElementById.bind(document);
    
      function updateTime()
      {
        var
          time = new Date(),
          // take 1800 seconds (30 minutes) and substract the remaining minutes and seconds
          // 30 minutes mark is rest of (+30 divided by 60); *60 in seconds; substract both, mins & secs
          secsRemaining = 3600 - (time.getUTCMinutes()+30)%60 * 60 - time.getUTCSeconds(),
          // integer division
          mins = Math.floor(secsRemaining / 60),
          secs = secsRemaining % 60
        ;
        byId('min-total').textContent = secsRemaining;
        byId('min-part').textContent  = mins;
        byId('sec-part').textContent  = secs;
    
        // let's be sophisticated and get a fresh time object
        // to calculate the next seconds shift of the clock
        setTimeout( updateTime, 1000 - (new Date()).getUTCMilliseconds() );
      }
      updateTime();
    </script>