I want to implement a simple javascript countdown that always counts down to the user's local next Friday, 15:00. I currently use the following code, but I believe that it only displays the countdown to next Friday, 15:00 UTC. Any help would really be appreciated!!
var curday;
var secTime;
var ticker;
function getSeconds() {
var nowDate = new Date();
var dy = 5; //Sunday through Saturday, 0 to 6
var countertime = new Date(nowDate.getFullYear(), nowDate.getMonth(), nowDate.getDate(), 15, 0, 0);
var curtime = nowDate.getTime(); //current time
var atime = countertime.getTime(); //countdown time
var diff = parseInt((atime - curtime) / 1000);
if (diff > 0) {
curday = dy - nowDate.getDay()
} else {
curday = dy - nowDate.getDay() - 1
} //after countdown time
if (curday < 0) {
curday += 7;
} //already after countdown time, switch to next week
if (diff <= 0) {
diff += (86400 * 7)
}
startTimer(diff);
}
function startTimer(secs) {
secTime = parseInt(secs);
ticker = setInterval("tick()", 1000);
tick(); //initial count display
}
function tick() {
var secs = secTime;
if (secs > 0) {
secTime--;
} else {
clearInterval(ticker);
getSeconds(); //start over
}
var days = Math.floor(secs / 86400);
secs %= 86400;
var hours = Math.floor(secs / 3600);
secs %= 3600;
var mins = Math.floor(secs / 60);
secs %= 60;
//update the time display
document.getElementById("days").innerHTML = curday;
document.getElementById("hours").innerHTML = ((hours < 10) ? "0" : "") + hours;
document.getElementById("minutes").innerHTML = ((mins < 10) ? "0" : "") + mins;
document.getElementById("seconds").innerHTML = ((secs < 10) ? "0" : "") + secs;
}
function starter() {
getSeconds();
}
Javascript dates are inherently UTC, however the various non–UTC get and set methods all work on local dates and times based on the host system clock and daylight saving settings.
So if you're not using UTC methods, everything in the OP is "local" by default. The following is a simplistic implementation of your "time until next Friday at 15:00" all as local values:
function timeUntil() {
let now = new Date();
// Create date for 15:00 on coming Friday
let friday = new Date(now);
friday.setHours(15,0,0,0);
let dayNum = friday.getDay();
friday.setDate(friday.getDate() + 5 - (dayNum < 6? dayNum : 5 - dayNum));
// If today is Friday and after 15:00, set to next Friday
if (dayNum == 5 && friday < now) {
friday.setDate(friday.getDate() + 7);
}
// Time remaining
let diff = friday - now;
let days = diff / 8.64e7 |0;
let hrs = (diff % 8.64e7) / 3.6e6 | 0;
let mins = (diff % 3.6e6) / 6e4 | 0;
let secs = (diff % 6e4) / 1e3 | 0;
// Display result
document.getElementById('days').textContent = days;
document.getElementById('hrs').textContent = hrs;
document.getElementById('mins').textContent = mins;
document.getElementById('secs').textContent = secs;
document.getElementById('fullDate').textContent = friday.toLocaleString();
}
setInterval(timeUntil, 1000);
td {
text-align: center;
}
<table>
<tr><th>Days<th>Hrs<th>Mins<th>Secs
<tr><td id="days"><td id="hrs"><td id="mins"><td id="secs">
<tr><td id="fullDate" colspan="4">
</table>
Note that setInterval isn't a good way to run a timer over a long period as it drifts (it doesn't run at exactly the specified interval). The overall time will be OK, it will just seem to skip from time to time and drift within a second with respect to the system displayed clock.
Better to use sequential calls setTimeout, calculating the time until just after the next full second each time so it closely matches the system clock's tick.
Related
I'm want to use a countdown timer to count to 10am every day so I am using this:
setInterval(function time(){
var d = new Date();
var hours = 09 - d.getHours();
var min = 60 - d.getMinutes();
if((min + '').length == 1){
min = '0' + min;
}
var sec = 60 - d.getSeconds();
if((sec + '').length == 1){
sec = '0' + sec;
}
jQuery('#countdown p').html('<span>'+hours+'</span><span class="mins">'+min+'<br></span><span class="secs">'+sec+'</span>')
}, 1000)
However, after 10am it obviously wants to turn negative, so I want to add in something to add 24hr after 10am like:
if(hours >= 10){
d = new Date() + 1;
}
but cannot get it working, any thoughts would be greatly appreciated.
You want to set hours and then use getDate() method.
setInterval(function time(){
var start = new Date;
start.setHours(10, 0, 0); // 10am
var now = new Date;
if (now > start) { // check current time is getter then add one day
start.setDate(start.getDate() + 1);
}
var days = ((start - now) / 1000);
var hours = format((days / 60 / 60) % 60);
var min = format((days / 60) % 60);
var sec = format(days % 60);
jQuery('#countdown p').html('<span>'+hours+'</span><span class="mins">'+min+'<br></span><span class="secs">'+sec+'</span>')
},1000);
// Add before 0 of hour, min, sec
function format(num) {
return ("0" + parseInt(num)).substr(-2);
}
Try Using A library like https://momentjs.com/
it will save you many lines of code.
I have modified this script: https://vincoding.com/weekly-repeating-countdown-timer-javascript/
That script displays a timer until a specific time on a specific day (0-6 = sunday through saturday), and once it reaches zero - it immediately starts counting down to that same day and time next week. There is a problem with it, however. When it reaches 0:00:00:00, instead of showing 6:23:59:59 on the next second, it shows 6:00:00:00. And THEN it shows 6:23:59:59. So, the day switches correctly, but the hour, minute and second are 1 second late.
Here is a live codepen of my modified version of the script:
https://codepen.io/RootB/pen/poePpOx
and the code itself:
timerEndDay = "monday";
timerEndTime = {
"hour": 18,
"minute": 00,
"second": 00
}
timerFrequency = "monthly"; //weekly, biweekly, monthly
var curday;
var secTime;
var ticker;
function getSeconds() {
var nowDate = new Date();
var dy = 0;
switch (timerEndDay) {
case "sunday":
dy = 0;
break;
case "monday":
dy = 1;
break;
case "tuesday":
dy = 2;
break;
case "wednesday":
dy = 3;
break;
case "thursday":
dy = 4;
break;
case "friday":
dy = 5;
break;
case "saturday":
dy = 6;
break;
}
var freq = 0;
switch (timerFrequency) {
case "weekly":
freq = 7;
break;
case "biweekly":
freq = 14;
break;
case "monthly":
freq = 30;
break;
}
var countertime = new Date(nowDate.getFullYear(), nowDate.getMonth(), nowDate.getDate(), timerEndTime.hour, timerEndTime.minute, timerEndTime.second);
var curtime = nowDate.getTime(); //current time
var atime = countertime.getTime(); //countdown time
var diff = parseInt((atime - curtime) / 1000);
if (diff > 0) {
curday = dy - nowDate.getDay()
} else {
curday = dy - nowDate.getDay() - 1;
} //after countdown time
if (curday < 0) {
curday += freq;
} //already after countdown time, switch to next week
if (diff <= 0) {
diff += (86400 * freq)
}
startTimer(diff);
}
function startTimer(secs) {
secTime = parseInt(secs);
ticker = setInterval("tick()", 1000);
tick(); //initial count display
}
function tick() {
var secs = secTime;
if (secs > 0) {
secTime--;
} else {
clearInterval(ticker);
getSeconds(); //start over
}
var days = Math.floor(secs / 86400);
secs %= 86400;
var hours = Math.floor(secs / 3600);
secs %= 3600;
var mins = Math.floor(secs / 60);
secs %= 60;
daysLeft = curday;
hoursLeft = ((hours < 10) ? "0" : "") + hours;
minutesLeft = ((mins < 10) ? "0" : "") + mins;
secondsLeft = ((secs < 10) ? "0" : "") + secs;
document.getElementById("p2").innerText = "Time left: " + daysLeft + ":" + hoursLeft + ":" + minutesLeft + ":" + secondsLeft;
}
getSeconds();
<p id="p2"></p>
This version just makes it easier to set the day and time on top of the script, and has an additional timer frequency option. You can set timerEndTime to any time, like 30 seconds in the future, and you will see the problem once it reaches zero. Both the original script and this one have the same problem, so it's not my modifications.
I have tried overwriting the hours, minutes and seconds to simply show "23:59:59" at this specific moment when it normally shows "00:00:00", and that is slightly better, but...of course, the timer is still late by 1 second, so it will then be stuck at "23:59:59" for an additional second. I can't figure out how to "push" the timer by one second.
My webpage timenite.com/item-shop shows a countdown that resets every day at 5:30 AM IST, I want to make a similar page in the directory timenite.com/xx and set it to reset every week on Thursdays at 8:30 PM IST.
Below is the script of what is being used currently on the item-shop page, there were actually two script files but I have combined them into one, just in case.
Help would be appreciated, thank you.
(function ($) {
$.fn.countdown = function (options, callback) {
var settings = $.extend({
date: null,
offset: null,
day: 'Day',
days: 'Days',
hour: 'Hour',
hours: 'Hours',
minute: 'Minute',
minutes: 'Minutes',
second: 'Second',
seconds: 'Seconds'
}, options);
// Throw error if date is not set
if (!settings.date) {
$.error('Date is not defined.');
}
// Throw error if date is set incorectly
if (!Date.parse(settings.date)) {
$.error('Incorrect date format, it should look like this, 12/24/2012 12:00:00.');
}
// Save container
var container = this;
/**
* Change client's local date to match offset timezone
* #return {Object} Fixed Date object.
*/
var currentDate = function () {
// get client's current date
var date = new Date();
// turn date to utc
var utc = date.getTime() + (date.getTimezoneOffset() * 60000);
// set new Date object
var new_date = new Date(utc + (3600000*settings.offset));
return new_date;
};
/**
* Main countdown function that calculates everything
*/
function countdown () {
var target_date = new Date(settings.date), // set target date
current_date = currentDate(); // get fixed current date
// difference of dates
var difference = target_date - current_date;
// if difference is negative than it's pass the target date
if (difference < 0) {
// stop timer
clearInterval(interval);
if (callback && typeof callback === 'function') callback();
return;
}
// basic math variables
var _second = 1000,
_minute = _second * 60,
_hour = _minute * 60,
_day = _hour * 24;
// calculate dates
var days = Math.floor(difference / _day),
hours = Math.floor((difference % _day) / _hour),
minutes = Math.floor((difference % _hour) / _minute),
seconds = Math.floor((difference % _minute) / _second);
// based on the date change the refrence wording
var text_days = (days === 1) ? settings.day : settings.days,
text_hours = (hours === 1) ? settings.hour : settings.hours,
text_minutes = (minutes === 1) ? settings.minute : settings.minutes,
text_seconds = (seconds === 1) ? settings.second : settings.seconds;
// fix dates so that it will show two digets
days = (String(days).length >= 2) ? days : '0' + days;
hours = (String(hours).length >= 2) ? hours : '0' + hours;
minutes = (String(minutes).length >= 2) ? minutes : '0' + minutes;
seconds = (String(seconds).length >= 2) ? seconds : '0' + seconds;
// set to DOM
container.find('.days').text(days);
container.find('.hours').text(hours);
container.find('.minutes').text(minutes);
container.find('.seconds').text(seconds);
container.find('.days_text').text(text_days);
container.find('.hours_text').text(text_hours);
container.find('.minutes_text').text(text_minutes);
container.find('.seconds_text').text(text_seconds);
}
// start
var interval = setInterval(countdown, 1000);
};
})(jQuery);
$(".openNav").click(function() {
$("body").toggleClass("navOpen");
$("nav").toggleClass("open");
$(".wrapper").toggleClass("open");
$(this).toggleClass("open");
});
// Second File from here
var today = new Date();
var tomorrow = new Date(today);
tomorrow.setDate(today.getDate() + 1);
var day = tomorrow.getDate();
var month = tomorrow.getMonth() + 1;
var year = tomorrow.getFullYear();
var nextday = month + '/' + day + '/' + year + ' 00:00:00';
$('#example').countdown({
date: nextday,
day: 'Day',
days: 'Days'
}, function () {
day++;
});
Update - Figured it out, thanks to a guy I met on Discord.
var curday;
var secTime;
var ticker;
function getSeconds() {
var nowDate = new Date();
var dy = 4 ; //Sunday through Saturday, 0 to 6
var countertime = new Date(nowDate.getFullYear(),nowDate.getMonth(),nowDate.getDate(),20,30,0); //20 out of 24 hours = 8pm
var curtime = nowDate.getTime(); //current time
var atime = countertime.getTime(); //countdown time
var diff = parseInt((atime - curtime)/1000);
if (diff > 0) { curday = dy - nowDate.getDay() }
else { curday = dy - nowDate.getDay() -1 } //after countdown time
if (curday < 0) { curday += 7; } //already after countdown time, switch to next week
if (diff <= 0) { diff += (86400 * 7) }
startTimer (diff);
}
function startTimer(secs) {
secTime = parseInt(secs);
ticker = setInterval("tick()",1000);
tick(); //initial count display
}
function tick() {
var secs = secTime;
if (secs>0) {
secTime--;
}
else {
clearInterval(ticker);
getSeconds(); //start over
}
var days = Math.floor(secs/86400);
secs %= 86400;
var hours= Math.floor(secs/3600);
secs %= 3600;
var mins = Math.floor(secs/60);
secs %= 60;
//update the time display
document.getElementById("days").innerHTML = curday;
document.getElementById("hours").innerHTML = ((hours < 10 ) ? "0" : "" ) + hours;
document.getElementById("minutes").innerHTML = ( (mins < 10) ? "0" : "" ) + mins;
document.getElementById("seconds").innerHTML = ( (secs < 10) ? "0" : "" ) + secs;
if (curday == 1) {
document.getElementById("days_text").innerHTML = "Day"
}
}
I'm trying to create a countdown timer that counts from Monday to Wednesday, Wednesday to Friday and Friday to Monday. Everything seems to be working ok except for the actual day value. That is not calculating correctly.
Before I had it set up to just countdown to Monday and that was working fine for me. This is the code I was following - https://vincoding.com/weekly-repeating-countdown-timer-javascript/
var curday;
var secTime;
var ticker;
function getSeconds() {
var nowDate = new Date();
var destinationDay;
var weekDay = nowDate.getDay();
if (nowDate.getHours() >= 24) {
weekDay++;
}
// in case it is Saturday after 8PM we would have a 7 as week day which should be changed to 0 (sunday).
weekDay = weekDay % 7;
if (weekDay > 1 && weekDay <= 3) {
destinationDay = 3;
} else if (weekDay > 3 && weekDay <= 5) {
destinationDay = 5;
} else {
destinationDay = 1;
}
var counterTime = new Date();
// calculate the date by adding an offset based on current and target date.
counterTime.setDate(counterTime.getDate() + (destinationDay + 7 - weekDay) % 7);
counterTime.setHours(24);
counterTime.setMinutes(0);
counterTime.setSeconds(0);
var currentTime = nowDate.getTime(); //current time
var destinationTime = counterTime.getTime(); //countdown time
var diff = parseInt((destinationTime - currentTime) / 1000);
startTimer(diff);
}
function startTimer(secs) {
secTime = parseInt(secs);
ticker = setInterval("tick()",1000);
tick(); //initial count display
}
function tick() {
var secs = secTime;
if (secs>0) {
secTime--;
}
else {
clearInterval(ticker);
getSeconds(); //start over
}
var days = Math.floor(secs/86400);
secs %= 86400;
var hours= Math.floor(secs/3600);
secs %= 3600;
var mins = Math.floor(secs/60);
secs %= 60;
//update the time display
document.getElementById("days").innerHTML = days;
document.getElementById("hours").innerHTML = ((hours < 10 ) ? "0" : "" ) + hours;
document.getElementById("minutes").innerHTML = ( (mins < 10) ? "0" : "" ) + mins;
document.getElementById("seconds").innerHTML = ( (secs < 10) ? "0" : "" ) + secs;
}
$( document ).ready(function() {
getSeconds();
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div id="countholder">
<div><span class="days" id="days"></span><div class="smalltext">Days</div></div>
<div><span class="hours" id="hours"></span><div class="smalltext">Hours</div></div>
<div><span class="minutes" id="minutes"></span><div class="smalltext">Minutes</div></div>
<div><span class="seconds" id="seconds"></span><div class="smalltext">Seconds</div></div>
</div>
It should countdown to each day and move on to the new day after midnight.
I'm trying to build a countdown of hours/minutes/seconds that is always 6 days in advance.
The trick is, the countdown should reset at 16:00 everyday, not 24:00, and should display the date in 24h format.
The date should be stated below the clock as "Month (September), Day(13)"
This is what I've came-up with:
function ShowTimes() {
var now = new Date();
now.setDate(now.getDate() + 5)
if (now.getHours() > 14) {
var hrs = 39-now.getHours();
} else {
var hrs = 16-now.getHours();
}
var mins = 59-now.getMinutes();
var secs = 59-now.getSeconds();
var str = '';
str = now.toString();
str += '<br>'+hrs+' hours '+mins+' minutes '+secs+' seconds ';
document.getElementById('countdownToFour').innerHTML = str;
if (hrs < 0) {
hrs = 23-now.getHours();
now.setDate(now.getDate() + 6);
}
}
var _cntDown;
function StopTimes() {
clearInterval(_cntDown);
}
The problem is I have no idea how to set it to 24h time and how to make it reset at 16.00 instead of 24.00. I seemed to have managed to set it 6 days in advance but I'm not so sure...
Because it was hard to understand your code, so I created a new counter:
<html>
<head>
<script type="text/javascript">
var counterIntervalVar;
var howManyDaysAhead = 0;
var finishHours = 16;
var finishMinutes = 0;
var finishSeconds = 0;
function ShowTimes()
{
var str = "";
var now = new Date();//Use current time as start time
//Creating the target time
var dayIncreasion = 1000 * 3600 * 24 * howManyDaysAhead;
var targetDateInMilliSeconds = now.getTime();
var targetDate = new Date(targetDateInMilliSeconds + dayIncreasion);
targetDate.setHours(finishHours);
targetDate.setMinutes(finishMinutes);
targetDate.setSeconds(finishSeconds);
targetDateInMilliSeconds = targetDate.getTime();
//Calculate and show the difference between current time and target time
var timeDifference = targetDateInMilliSeconds - now.getTime();
if (timeDifference >= 0)
{
var hrs = Math.floor(timeDifference / 1000 / 3600);
var mins = Math.floor(timeDifference / 1000 / 60) - (hrs * 60);
sec = Math.floor(timeDifference / 1000) - (hrs * 3600) - (mins * 60);
str += '<br>'+hrs+' hours '+mins+' minutes '+sec+' seconds ';
document.getElementById('countdownToFour').innerHTML = str;
} else {
howManyDaysAhead++;
}
//Give the 'if' query a realistic condition
if (str == 'x')
{
//Stop the loop
window.clearInterval(counterIntervalVar);
}
}
function initCountdown()
{
counterIntervalVar = window.setInterval("ShowTimes()",999);
}
</script>
</head>
<body onLoad="initCountdown()">
<div id="countdownToFour"></div>
</body>
</html>
Hopefully this example works for you or at least leads you to the right way.