Marcus
Marcus

Reputation: 15

How can I repeat countdown timer daily and with multiple times per day?

I'm trying to create a countdown timer for the next outgoing ship. The ship leaves multiple times per day and I want the counter to count down to the next outgoing time. When the last time has count down to 0 it should start over with the first time in the next morning.

There are 6 times per day.

Here's what I have so far but it seems like it's not repeating.

(function () {
	var d1 = new Date;
	d1.setHours(6, 20, 0);
	var d2 = new Date;
	d2.setHours(9, 45, 0);
	var d3 = new Date;
	d3.setHours(11, 30, 0);
	var d4 = new Date;
	d4.setHours(15, 0, 0);
	var d5 = new Date;
	d5.setHours(15, 30, 0);
	var d6 = new Date;
	d6.setHours(20, 15, 0);


	function pad(num) {
		return ("0" + parseInt(num)).substr(-2);
	}

	function tick() {
		var now = new Date;
		if (now > d6 || now < 0 && now < d1) {
			var remain = ((d1 - now) / 1000);
			var hh = pad((remain / 60 / 60) % 60);
			var mm = pad((remain / 60) % 60);
			var ss = pad(remain % 60);
			document.getElementById('time').innerHTML = hh + ":" + mm + ":" + ss;
			document.getElementById('time').style.color = "Red";
			setTimeout(tick, 1000);
		} else if (now > d1 && now < d2) {
			var remain = ((d2 - now) / 1000);
			var hh = pad((remain / 60 / 60) % 60);
			var mm = pad((remain / 60) % 60);
			var ss = pad(remain % 60);
			document.getElementById('time').innerHTML = hh + ":" + mm + ":" + ss;
			document.getElementById('time').style.color = "Green";
			setTimeout(tick, 1000);
		} else if (now > d2 && now < d3) {
			var remain = ((d3 - now) / 1000);
			var hh = pad((remain / 60 / 60) % 60);
			var mm = pad((remain / 60) % 60);
			var ss = pad(remain % 60);
			document.getElementById('time').innerHTML = hh + ":" + mm + ":" + ss;
			document.getElementById('time').style.color = "Red";
			setTimeout(tick, 1000);
		} else if (now > d3 && now < d4) {
			var remain = ((d4 - now) / 1000);
			var hh = pad((remain / 60 / 60) % 60);
			var mm = pad((remain / 60) % 60);
			var ss = pad(remain % 60);
			document.getElementById('time').innerHTML = hh + ":" + mm + ":" + ss;
			document.getElementById('time').style.color = "Green";
			setTimeout(tick, 1000);
		} else if (now > d4 && now < d5) {
			var remain = ((d5 - now) / 1000);
			var hh = pad((remain / 60 / 60) % 60);
			var mm = pad((remain / 60) % 60);
			var ss = pad(remain % 60);
			document.getElementById('time').innerHTML = hh + ":" + mm + ":" + ss;
			document.getElementById('time').style.color = "Red";
			setTimeout(tick, 1000);
		} else if (now > d5 && now < d6) {
			var remain = ((d6 - now) / 1000);
			var hh = pad((remain / 60 / 60) % 60);
			var mm = pad((remain / 60) % 60);
			var ss = pad(remain % 60);
			document.getElementById('time').innerHTML = hh + ":" + mm + ":" + ss;
			document.getElementById('time').style.color = "Red";
			setTimeout(tick, 1000);
		}
	}
	document.addEventListener('DOMContentLoaded', tick);
})();
<p>Next outgoing ship:&nbsp;<span id="time">&nbsp;</span></p>

Thankful for any help or guidance!

Upvotes: 0

Views: 366

Answers (1)

Jonas Wilms
Jonas Wilms

Reputation: 138257

You create d1, d2 once, when the script starts, for the current day. To make them repeat you have to recreate the dates whenever the day changes. To simplify that you could just move them into tick(). Then they will be recreated every second, most of the time the dates will be the same, but at midnight they'll change.

I'd write the whole thing as:

  const times = [
    [6, 20, "green"], [9, 45, "red"], [11, 30, "green"], [15, 0, "red"], [15, 30, "green"], [20, 15, "red"]
  ]

  const timer = document.getElementById('time');


  setInterval(function tick() {
     const now = new Date();
     const nextShip = times.find(it => it[0] > now.getHours() || it[0] == now.getHours() &&  it[1] >= now.getMinutes()) || times[0];

    let hours = nextShip[0] - now.getHours();
    let minutes = nextShip[1] - now.getMinutes();

    if(minutes < 0) { minutes += 60; hours -= 1 }
    if(hours < 0) { hours += 24; }

    const seconds = 60 - now.getSeconds();

    timer.innerHTML = `${hours}:${minutes}:${seconds}`;
    timer.style.color = nextShip[2];

  }, 1000);

Upvotes: 2

Related Questions