I wish to do a countdown to a specific date and hour (January 10, 2018, 19:30). Which in large part I am able to do. Below code shows the remaining days, hours, minutes and seconds.
The tricky bit is to get certain periods of time. The countdown should respond to the following:
1. on the deadline day and hour show the message 'Now going live'. Which is 10 January 2018 19:30.
2. That same day but BEFORE 19:30 it should say 'Going live tonight'
3. The complete day before the deadline day (from 00:00 to 23:59) it should say 'last day'
4. The complete days before that it should say 'many days to go'
Step 1 and 2 I managed, but I'm having trouble getting the complete day before the deadline day and the complete days before that. That's because I'm not able to define the complete day before the deadline day (and the days before that). Because it counts '1 day' as 1 day before 10 January 19:30 (so it also takes those hours/minutes of 19:30 into account).
Step 1 and 2 I managed in the if-loop, but I can't figure out how to do step 3 and 4. Step 3 should say something like 'count one day, but before 10 January 2018 00:00. So it should subtract that 19:30 to get to 9 januari 2018 00:00-23:59. And the same for step 4. Can someone fix my code?
// Get todays date and time
var now = new Date().getTime();
// Set the date we're counting down to
var countDownDate = new Date("Januari 10, 2018 19:30").getTime();
// Find the distance between now an the count down date
var distance = countDownDate - now;
// Time calculations for days, hours, minutes and seconds
var days = Math.floor(distance / (1000 * 60 * 60 * 24));
var hours = Math.floor((distance % (1000 * 60 * 60 * 24)) / (1000 * 60 * 60));
var minutes = Math.floor((distance % (1000 * 60 * 60)) / (1000 * 60));
var seconds = Math.floor((distance % (1000 * 60)) / 1000);
// Display the result
this.timeleft.text = days + "d " + hours + "h " + minutes + "m " + seconds + "s ";
// countdown day 19:30
if ((days == 0) && (hours == 0) && (minutes == 0)) {
this.countdown.text = "NOW GOING LIVE!";
// countday day 00:00 - 19.30
} else if ((days == 0) && (hours <= 19) && (minutes <= 30)) {
this.countdown.text = "GOING LIVE TONIGHT!";
// 9 January 00:00 - 23:59
} else if ((days <= 1) && (hours >= 19) && (minutes >= 30)) {
this.countdown.text = "LAST DAY";
// days before 10 January
} else if (days >= 1) {
this.countdown.text = "MANY DAYS TO GO";
}
Since the "deadline" is hard-coded, you can hard-code everything and end up with something very simple:
var now = new Date().getTime();
var lastDayThreshold = new Date("January 9, 2018 00:00").getTime();
var liveTonightThreshold = new Date("January 10, 2018 00:00").getTime();
var countDownDate = new Date("January 10, 2018 19:30").getTime();
if (now < lastDayThreshold) this.countdown.text = "MANY DAYS TO GO";
else if(now < liveTonightThreshold) this.countdown.text = "LAST DAY";
else if(now < countDownDate) this.countdown.text = "LIVE TONIGHT";
else this.countdown.text = "NOW GOING LIVE";
Alex's answer was indeed what I was after. Those 'treshhold times' did the trick. Was thinking about improving it though as now I have to hard-code three dates/times. Preferably I would like to only specify the countDownDate date/time. And then let both Threshold dates calculate themselves. I tried to do that in a way, but ran into a problem. I know how to specify one day (1000 * 60 * 60 * 24), so I could subtract this 'oneday' value to get to the day before. But I wasn't able to calculate the milliseconds for the specified time 19:30. In order to read the miilliseconds since the beginning of January 10 until January 10 19:30. If I were able to do that it would look something like this (though I know this is incorrect, but you'll get the idea):
var oneday = 1000 * 60 * 60 * 24;
var countDownDate = new Date("January 10, 2018 19:30").getTime();
var lastDayThreshold = new Date(countDownDate - oneday "00:00").getTime();
var liveTonightThreshold = new Date(countDownDate "00:00").getTime();
You'll see my problem: for lastDayTreshold I could subtract one day of the countdowndate but then it would consider that 19:30 the previous day, not 00:00. And for liveTonightThreshold I also couldn't specify that I mean 00:00 of the countdowndate.
Would there be a way of doing that? Then I would just have to specify the countdown day and time and the rest would figure them out themselves.
Related
I have a countdown timer that I'd like to show the exact same amount of remaining hours and minutes for every user regardless of timezone or location (days aren't important).
I'm assuming I need to target and output UTC somehow. Will I have any daylight-saving problems with this? The actual end time is not very important. Everyone seeing the same remaining time is.
I've researched similar posts here but they're a few years old and didn't find answers. Hoping a solution or newer approach is available. All programming languages considered.
// Set the date we're counting down to
var countDownDate = new Date("May 10, 2022 24:00:00").getTime();
// Update the count down every 1 second
var x = setInterval(function() {
// Get today's date and time
var now = new Date().getTime();
// Find the distance between now and the count down date
var distance = countDownDate - now;
// Time calculations for days, hours, minutes and seconds
var days = Math.floor(distance / (1000 * 60 * 60 * 24));
var hours = Math.floor((distance % (1000 * 60 * 60 * 24)) / (1000 * 60 * 60));
var minutes = Math.floor((distance % (1000 * 60 * 60)) / (1000 * 60));
var seconds = Math.floor((distance % (1000 * 60)) / 1000);
// Output the result in an element with id="demo"
document.getElementById("demo").innerHTML = days + "d " + hours + "h " +
minutes + "m " + seconds + "s ";
// If the count down is over, write some text
if (distance < 0) {
clearInterval(x);
document.getElementById("demo").innerHTML = "EXPIRED";
}
}, 1000);
#demo {
font: normal 20px arial
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div id="demo"></div>
https://jsfiddle.net/r64zp93c/
It seems Date.UTC() is what you're looking for. From the docs:
The Date.UTC() method accepts parameters similar to the Date
constructor, but treats them as UTC. It returns the number of
milliseconds since January 1, 1970, 00:00:00 UTC.
So instead of
var countDownDate = new Date("May 10, 2022 24:00:00").getTime();
You should be able to do
var countDownDate = Date.UTC(2022, 4, 10, 24, 0, 0);
(But maybe adjust the hours/day to UTC to match the specific time you need)
hope somebody can help me with this one.
And before this comes up: I did check Google, other questions and a lot of other places, but still couldn't find a solution for me - total coding noob.
That's what I'm struggling with
I have an event series with a few dates.
Now I wanted to display a countdown timer for the first date.
After this countdown reaching 0 I'd like it to start the next countdown for the next date.
Of course there will be future dates as well so I'd like to have a possibility to expand it individually.
I hoped this wouldn't be such a pain in the ... but unfortunately I already spend over 5 hours looking and searching for an already finished solution I could just copy and use. But didn't find anything, that works for me OR that I could understand and use.
So really hoping for help here and please remember - I'm a total noob and have ~ 0.0001% knowledge about coding.
So do you know a solution?
Can you point me to it?
Can you show me how I could do this?
Thanks in advance!
Set an array of dates and loop over the array checking if date is in the future, then update countdown timer and break loop. Example
<!-- HTML element where to show countdown timer -->
<p id="demo"></p>
<script>
// Target dates
let countdown_dates = [
'Jan 5, 2021 15:00:00',
'Apr 1, 2021 15:00:00',
'Jan 5, 2022 15:00:00',
]
// Currency number of milliseconds - Unix
var now = new Date().getTime();
// Loop dates
for (i = 0; i < countdown_dates.length; i++) {
// Target date in Unix
var countDownDate = new Date( countdown_dates[i] ).getTime();
// Check is in the future
if ( countDownDate > now ){
// Update the count down every 1 second
var x = setInterval(function() {
// Find the distance between now and the count down date
var distance = countDownDate - now;
// Time calculations for days, hours, minutes and secondsa
var days = Math.floor(distance / (1000 * 60 * 60 * 24));
var hours = Math.floor((distance % (1000 * 60 * 60 * 24)) / (1000 * 60 * 60));
var minutes = Math.floor((distance % (1000 * 60 * 60)) / (1000 * 60));
var seconds = Math.floor((distance % (1000 * 60)) / 1000);
// Display the result in the element with id="demo"
document.getElementById("demo").innerHTML = days + "d " + hours + "h " + minutes + "m " + seconds + "s ";
}, 1000);
// Exit loop as we only want to target next date.
break;
}
};
</script>
If the user sets a date on the backend (via jQuery DateTimer Picker) the following acf_vars.timer variable would look like this on the frontend:
2021 2 9 13 08 00
I have the following construct as a countdown timer (CODEPEN):
const [y, month, d, h, minute, s] = acf_vars.timer.split(' ');
// monthIndex in Date Object begins with 0, so we subtract 1
const countDownDate = new Date(y, month - 1, d, h, minute, s).getTime();
const updateCountdown = () => {
const now = new Date().getTime(); // Get today's date and time
const distance = countDownDate - now; // Find distance between now and the countdown date
const expiredTimer = distance <= 0;
let days = Math.floor(distance / (1000 * 60 * 60 * 24));
let hours = Math.floor((distance % (1000 * 60 * 60 * 24)) / (1000 * 60 * 60));
let minutes = Math.floor((distance % (1000 * 60 * 60)) / (1000 * 60));
let seconds = Math.floor((distance % (1000 * 60)) / 1000);
if (expiredTimer) {
days = hours = minutes = seconds = 0;
clearInterval(timerInterval);
}
document.querySelectorAll('.ticker').forEach((container) => {
container.children[0].classList.contains('days') &&
(container.children[0].textContent = days);
container.children[2].classList.contains('hours') &&
(container.children[2].textContent = hours);
container.children[4].classList.contains('minutes') &&
(container.children[4].textContent = minutes);
container.children[6].classList.contains('seconds') &&
(container.children[6].textContent = seconds);
});
};
const timerInterval = setInterval(updateCountdown, 1000);
updateCountdown();
If the user doesn't specify a future date on the backend, I'd like to use a fallback which automatically sets the countdown timer to the upcoming Sunday at 9am. To solve this I tried setting a standardized countDownDate variable but I'm having trouble coming up with a way to set the day and time to automatically be the upcoming Sunday at 9am.
It seems you just want a way to set a date to next Sunday at 09:00. In plain JS it might be:
/* Get a date for next occurence of Sunday at 09:00
*
* #param {Date} d - start date, default is current date and time
* #returns {Date} for next Sunday at 09:00 after d
*/
function getNextSunday(d = new Date()) {
// Create date for next Sun at 9
let sun = new Date(d.getFullYear(), d.getMonth(), d.getDate() + (7 - (d.getDay() || 7)), 9, 0, 0, 0);
// If date is same day but later, move to next Sun
sun <= d? sun.setDate(sun.getDate() + 7) : null;
return sun;
}
// Examples
// Next Sunday at 9:00
console.log(getNextSunday().toString());
// Next Sunday after Sun 7 Feb at 8:59:59
console.log(getNextSunday(new Date(2021, 1, 7, 8, 59, 59)).toString());
// Next Sunday after Sun 7 Feb at 9:00
console.log(getNextSunday(new Date(2021, 1, 7, 9)).toString());
Notes:
d.getDay() || 7 is used so that if getDay returns 0 (Sunday), it's replaced with the number 7. That means the expression sets sun to the current day if it's Sunday or the next Sunday if it isn't. Otherwise on Sundays it would create a Date for the previous Sunday.
sun <= d? sun.setDate(sun.getDate() + 7) : null is used so that if the current date is Sunday but the time is after the specified time (in this case 9:00) the date is moved to the following Sunday at 9:00. Using the compound ? : operator this way is just a another way of writing if (sun <= d) sun.setDate(sun.getDate() + 7) on one line. I prefer if statements to be followed by a block and would rather use ? : for simple expressions on single lines.
Moment.js might be what you are looking for.
moment().endOf('week').add(1, 'second').add(9, 'hours').toString()
End of week uses the locale aware week start day, so you might have to configure it if you have users globally.
Edit
Alternatively, if you do not want to use external libraries you can check the current weekday and hour with the JavaScript Date object.
const day = countDownDate.getDay() // weekday sun = 0, sat = 6
const hour = countDownDate.getHours() // 0 - 23
Within your logic, you would want to get the distance between day and 0 (also accounting for countDownDate starting on a Sunday) and hour and 9. However, another way to implement this is to check the current date upon each update which could reduce the error in case the interval gets interrupted.
What is the best way to get time for recent notifications (relative to current time) in an application, which are 5 sec ago, 10 sec ago or 7 hr 32 min ago?
In other words, I have a Date Object (in format 2019-03-12T10:05:32.257) which is for example 3 hr 6 min 9 sec ago from current time, I am wondering if there is a clean way to achieve the magic numbers 3, 6, 9 and display in html.
More cleaner way and generic implementation that I see to approach this problem could be.
Get the difference of date object in seconds converted as a first step
Then check for whether it could be fit into
years(divide by 31536000)
months(divide by 2592000)
days(divide by 86400)
hours(divide by 3600)
minutes(divide by 60)
function timesAgo(date) {
var seconds = Math.floor((new Date() - date) / 1000); // get the diffrence of date object sent with current date time of the system time
var interval = Math.floor(seconds / 31536000); // divide seconds by seconds in avg for a year to get years
//conditioning based on years derived above
if (interval > 1) {
return interval + " years";
}
interval = Math.floor(seconds / 2592000); // months check similar to years
if (interval > 1) {
return interval + " months";
}
interval = Math.floor(seconds / 86400); // days check similar to above
if (interval > 1) {
return interval + " days";
}
interval = Math.floor(seconds / 3600); // hours check
if (interval > 1) {
return interval + " hours";
}
interval = Math.floor(seconds / 60); // minutes check
if (interval > 1) {
return interval + " minutes";
}
return Math.floor(seconds) + " seconds"; // seconds check at the end
}
var withYears = new Date('August 19, 1999 23:15:30');
var withMonths = new Date('March 19, 2019 23:15:30');
var withDays = new Date('May 1, 2019 23:15:30');
var withPreviousDay = new Date('May 5, 2019 23:15:30');
var withHours = new Date('May 6, 2019 10:15:30');
console.log(timesAgo(withYears));
console.log(timesAgo(withMonths));
console.log(timesAgo(withDays));
console.log(timesAgo(withPreviousDay));
console.log(timesAgo(withHours));
Easier way If your using Angular and Moment is to use fromNow() function - Link
console.log(moment([2007, 0, 29]).fromNow(true)); // 12 years
console.log(moment([2007, 0, 29]).fromNow()); // 12 years ago
<script data-require="moment.js#*" data-semver="2.18.0" src="https://cdnjs.cloudflare.com/ajax/libs/moment.js/2.18.0/moment.min.js"></script>
If you need an Angular Pipe check this times-ago-pipe
I guess you are trying to find the difference between two Date objects.
First, you can convert them to Date objects, followed by using getTime() to get it in milliseconds. After which, you subtract both date objects to get the time difference, and then divide it by 1000 to get the results in seconds.
const targetDate = new Date('2019-03-12T10:05:32.257').getTime();
const current = new Date().getTime();
const differenceInSeconds = (current - targetDate) / 1000;
From there, you can convert it to your required format (hours, minutes, and seconds).
And in order to convert them into hours, minutes and seconds,
const hours = Math.floor(differenceInSeconds / 3600);
const minutes = Math.floor(differenceInSeconds % 3600 / 60);
const seconds = Math.floor(differenceInSeconds % 3600 % 60);
This is how the end result will be like:
const targetDate = new Date('2019-03-12T10:05:32.257').getTime();
const current = new Date().getTime();
const differenceInSeconds = (current - targetDate) / 1000;
const hours = Math.floor(differenceInSeconds / 3600);
const minutes = Math.floor(differenceInSeconds % 3600 / 60);
const seconds = Math.floor(differenceInSeconds % 3600 % 60);
const result = `${hours} hr ${minutes} min ${seconds} sec`
console.log(result);
I have a countdown that ends at a specific time and date.
Is it possible to set a starting date for the countdown?
Start: June 14, 2018 15:00:00
End: June 17, 2018 23:59:59
// Set the date we're counting down to
var countDownDate = new Date("June 17, 2018 23:59:59").getTime();
// Update the count down every 1 second
var x = setInterval(function() {
// Get todays date and time
var now = new Date().getTime();
// Find the distance between now an the count down date
var distance = countDownDate - now;
// Time calculations for days, hours, minutes and seconds
var days = Math.floor(distance / (1000 * 60 * 60 * 24));
var hours = Math.floor((distance % (1000 * 60 * 60 * 24)) / (1000 * 60 * 60));
var minutes = Math.floor((distance % (1000 * 60 * 60)) / (1000 * 60));
var seconds = Math.floor((distance % (1000 * 60)) / 1000);
// Output the result in an element with id="demo"
document.getElementById("countdown").innerHTML = "TEXT Countdown" + days + " days, " + hours + " h, "
+ minutes + " min & " + seconds + " sec";
// If the count down is over, write some text
if (distance < 0) {
clearInterval(x);
document.getElementById("countdown").innerHTML = "TEXT after countdown";
}
}, 1000);
<div id="countdown"></div>
Just delay the call to setInterval until the time you want. Your best bet, since timers get throttled on inactive tabs, is to check periodically and then kick things off when the time arrives:
var waitingTimer = setInterval(function() {
if (Date.now() < Date.parse("2018-06-14T15:00:00")) {
return;
}
clearInterval(waitingTimer);
// ...start the countdown
}, 1000);
You might want to express the time in UTC, since unfortunately the spec on what those strings mean without a timezone indicator changed (twice), whereas if you put the time in UTC and add a Z to the string, it's reliable.