countdown formatting showing more than 23hs in the hour variable - javascript

I'm having an issue making this countdown, it shows more hours than "23". Any idea how to fix it?
String.prototype.toHHMMSS = function() {
var sec_num = parseInt(this, 10);
var days = Math.floor(sec_num / 86400);
var hours = Math.floor(sec_num / 3600);
var minutes = Math.floor((sec_num - (hours * 3600)) / 60);
var seconds = sec_num - (hours * 3600) - (minutes * 60);
return days + " days" + " : " + hours + " hrs" + " : " + minutes + " min" + " : " + seconds + " sec";
};
let startTime = 1649303300; // database unix-timestamp value
setInterval(() => {
let curTime = (new Date()).getTime() / 1000;
curTime = parseInt(curTime);
if (curTime < startTime){
document.getElementById("timer1").innerText = ("LAUNCHING IN:");
document.getElementById("timer").innerText = (`${startTime-curTime}`).toHHMMSS();
}
else {
document.getElementById("timer1").innerText = ("LAUNCHED");
document.getElementById("timer").innerText = ("");
}
}, 1000);
"
I'm getting more than "23" for the "hours" variable instead of increasing the days every 24 hours.

You're not subtracting the days from the hours variable in the way that you're doing it for minutes and seconds. Try declaring your hours variable like this:
var days = Math.floor(sec_num / 86400);
var hours = Math.floor((sec_num - (days * 86400)) / 3600);
You can also use modular arithmetic to strip the excess values. You can use the modulo operator for this, e.g.
String.prototype.toHHMMSS = function() {
var sec_num = parseInt(this, 10);
var days = Math.floor(sec_num / 86400);
var hours = Math.floor(sec_num / 3600) % 24;
var minutes = Math.floor(sec_num / 60) % 60;
var seconds = sec_num % 60;
return days + " days" + " : " + hours + " hrs" + " : " + minutes + " min" + " : " + seconds + " sec";
};

Related

Converting decimal to hours and minutes - Javascript

I just can't figure why this doesn't work for some odd values.
For example when trying to convert 22.68 to hours and minutes the output is 22:40.800000000000004 (Seconds shouldn't even appear)
if (str_HR_PER_WEEK.indexOf('.') > -1)
{
var str_HR_PER_WEEK_hrs = str_HR_PER_WEEK.substring(0 , str_HR_PER_WEEK.indexOf('.'));
var str_HR_PER_WEEK_mins = str_HR_PER_WEEK.substring(str_HR_PER_WEEK.indexOf('.') + 1);
var float_HR_PER_WEEK_mins = parseFloat("0." + (str_HR_PER_WEEK_mins), 10);
var float_HR_PER_WEEK_mins_actual = float_HR_PER_WEEK_mins * 60;
float_HR_PER_WEEK_mins_actual = float_HR_PER_WEEK_mins_actual.toString();
tables.CURRENT_EMPLOYEES.HOURS_PER_WEEK.value = getTwoDigitTime(str_HR_PER_WEEK_hrs) + ":" + getTwoDigitTime(float_HR_PER_WEEK_mins_actual);
}
else
{
tables.CURRENT_EMPLOYEES.HOURS_PER_WEEK.value = str_HR_PER_WEEK;
}
You have to ways to achieve that,
one, do the calculations yourself:
var decimalTimeString = "1.6578";
var decimalTime = parseFloat(decimalTimeString);
decimalTime = decimalTime * 60 * 60;
var hours = Math.floor((decimalTime / (60 * 60)));
decimalTime = decimalTime - (hours * 60 * 60);
var minutes = Math.floor((decimalTime / 60));
decimalTime = decimalTime - (minutes * 60);
var seconds = Math.round(decimalTime);
if(hours < 10)
{
hours = "0" + hours;
}
if(minutes < 10)
{
minutes = "0" + minutes;
}
if(seconds < 10)
{
seconds = "0" + seconds;
}
alert("" + hours + ":" + minutes + ":" + seconds);
Two, use built in function to convert to string and then to hh:mm:
var decimalTimeString = "1.6578";
var n = new Date(0,0);
n.setSeconds(+decimalTimeString * 60 * 60);
n.setMinutes(+decimalTimeString * 60);
var result = n.toTimeString().slice(0, 5);
document.write(result);
I've got a neat function to do just that:
function hoursToHHMM(hours) {
var h = String(Math.trunc(hours)).padStart(2, '0');
var m = String(Math.abs(Math.round((hours - h) * 60))).padStart(2, '0');
return h + ':' + m;
}
It handles negative values as a bonus.
Usage is trivial:
var hours = -7.33333;
console.log(hoursToHHMM(hours));
Results in: -07:20
You can play with it here: https://jsfiddle.net/r150c2me/

JavaScript countdown timer recursive call for each day

I am trying to make a countdown timer which displays the amount of time remaining for a customer to purchase in order to receive same day shipping.
For example, if they purchase before 15:30 the timer will say something like order within 30 minutes for shipping today (if it was 15:00).
However, when it reaches 15:30, I want it to say order within 23 hours and 59 minutes to receive shipping tomorrow. Then obviously when it reaches midnight it will turn to today. Alternatively it can just display the day/date so today/tomorrow won't matter.
I know I need to call the function again looking at tomorrows date but I'm not very handy with javascript so cannot figure it out.
Can someone help?
// Set the date we're counting down to
var nowDate = new Date();
var countDownDate = new Date(nowDate.getFullYear(), nowDate.getMonth(), nowDate.getDate(), 15, 30, 0, 0);
// 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 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 in the element with id="demo"
if (hours >= 1) {
document.getElementById("shipping-countdown").innerHTML = "Order within " + hours + "h "
+ minutes + "m " + seconds + "s " + "to have your order shipped on " // date of shipment;
}
else if (hours < 1 && minutes < 1) {
document.getElementById("shipping-countdown").innerHTML = "Order within " + seconds + "s "
+ "to have your order shipped on " // date of shipment;
}
else {
document.getElementById("shipping-countdown").innerHTML = "Order within " + minutes + "m "
+ seconds + "s " + "to have your order shipped on " // date of shipment;
}
// If the count down is finished, write some text
if (distance < 0) {
clearInterval(x);
// Start again but looking at tomorrows date
}
// If the count down is finished, write some text
if (nowDate.getDay() == 0 || nowDate.getDay() == 6) {
clearInterval(x);
document.getElementById("shipping-countdown").innerHTML = "Order within " + days + "d "
+ hours + "h "
+ minutes + "m " + seconds + "s " + "to have your order shipped on " // Start of the week;
}
}, 1000);
<!-- Display the countdown timer in an element -->
<p id="shipping-countdown"></p>
You don't need to clear the setInterval function. Just reset the new target date while keeping it alive. You also had some issues with the countdown going into the negatives which I fixed by moving the distance check and resetting the distance if it is under 1 second.
// Set the date we're counting down to
var nowDate = new Date();
var countDownDate = new Date(nowDate.getFullYear(), nowDate.getMonth(), nowDate.getDate(), 11, 2, 50, 0);
// 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;
if (distance < 1) {
countDownDate = countDownDate.setDate(countDownDate.getDate()+1);
distance = countDownDate - now;
}
// Time calculations for 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 in the element with id="demo"
if (hours >= 1) {
document.getElementById("shipping-countdown").innerHTML = "Order within " + hours + "h "
+ minutes + "m " + seconds + "s " + "to have your order shipped on " // date of shipment;
}
else if (hours < 1 && minutes < 1) {
document.getElementById("shipping-countdown").innerHTML = "Order within " + seconds + "s "
+ "to have your order shipped on " // date of shipment;
}
else {
document.getElementById("shipping-countdown").innerHTML = "Order within " + minutes + "m "
+ seconds + "s " + "to have your order shipped on " // date of shipment;
}
// If the count down is finished, write some text
if (nowDate.getDay() == 0 || nowDate.getDay() == 6) {
clearInterval(x);
document.getElementById("shipping-countdown").innerHTML = "Order within " + days + "d "
+ hours + "h "
+ minutes + "m " + seconds + "s " + "to have your order shipped on " // Start of the week;
}
}, 1000);
<!-- Display the countdown timer in an element -->
<p id="shipping-countdown"></p>
I have managed to achieve this with the following code, figured out I was along the wrong lines and could simply just adjust the countDownDate variable.
// Set the date we're counting down to
var nowDate = new Date();
var countDownDate = new Date(nowDate.getFullYear(), nowDate.getMonth(), nowDate.getDate(), 15, 30, 0, 0);
// 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 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);
// If the count down is finished, write some text
if (countDownDate.getDay() == 6) {
countDownDate.setDate(countDownDate.getDate()+2);
}
if (days >= 1) {
document.getElementById("shipping-countdown").innerHTML = "Order within " + days + "d " + hours + "h "
+ minutes + "m " + seconds + "s " + "to have your order shipped on " + countDownDate;
}
else if (hours >= 1) {
document.getElementById("shipping-countdown").innerHTML = "Order within " + hours + "h "
+ minutes + "m " + seconds + "s " + "to have your order shipped on " + countDownDate.getDate() + "/"
+ (countDownDate.getMonth()+1) + "/" + countDownDate.getFullYear();
}
else if (minutes >= 1) {
document.getElementById("shipping-countdown").innerHTML = "Order within " + minutes + "m " + seconds + "s "
+ "to have your order shipped on " + countDownDate.getDate() + "/"
+ (countDownDate.getMonth()+1) + "/" + countDownDate.getFullYear();
}
else {
document.getElementById("shipping-countdown").innerHTML = "Order within " + seconds + "s "
+ "to have your order shipped on " + countDownDate.getDate() + "/"
+ (countDownDate.getMonth()+1) + "/" + countDownDate.getFullYear();
}
// If the count down is finished
if (distance < 0) {
countDownDate.setDate(countDownDate.getDate()+1);
}
}, 1000);
<!-- Display the countdown timer in an element -->
<p id="shipping-countdown"></p>

javascript countdown from d:h:m:s

I'm new in javascript.
My PHP script returns a value in this format
d:h:m:s
Now I would like to have a countdown which is able to countdown each second from this.
I modified a countdown. This works once a time, after the countdown "ticks" each second it returns NaN all the time. Any idea what I do wrong?
$(document).ready(function() {
setInterval(function() {
$('.countdown').each(function() {
var time = $(this).data("time").split(':');
var timestamp = time[0] * 86400 + time[1] * 3600 + time[2] * 60 + time[3] * 1;
var days = Math.floor(timestamp / 86400);
console.log(time,timestamp);
var hours = Math.floor((timestamp - days * 86400) / 3600);
var minutes = Math.floor((timestamp - hours * 3600) / 60);
var seconds = timestamp - ((days * 86400) + (hours * 3600) + (minutes * 60))-1;
$(this).data("time",""+days+":"+hours+":"+minutes+":"+seconds);
if (hours < 10) {
hours = '0' + hours;
}
if (minutes < 10) {
minutes = '0' + minutes;
}
if (seconds < 10) {
seconds = '0' + seconds;
}
$(this).text(days + ':' + hours + ':' + minutes + ':' + seconds);
});
}, 1000);
})
</script>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<h1 class="countdown">02:03:05:59</h1>
As far as I can see you have 2 problems here:
after the first execution you change the pattern of the text you display in the h1. First you have 02:03:05:59. Then you want to write 02 days 03:05:58 into the tag. Next time you parse it, you get the error because you split at : and that does not work anymore as you have days instead of : as the seperator for the first part.
When calculating the minutes, you should also substract the days and not just the hours.
When you wan to keep the dd:hh:mm:ss format, you could do it like this:
$(document).ready(function() {
setInterval(function() {
$('.countdown').each(function() {
var time = $(this).text().split(':');
var timestamp = time[0] * 86400 + time[1] * 3600 + time[2] * 60 + time[3] * 1;
timestamp -= timestamp > 0;
var days = Math.floor(timestamp / 86400);
console.log(days);
var hours = Math.floor((timestamp - days * 86400) / 3600);
var minutes = Math.floor((timestamp - days * 86400 - hours * 3600) / 60);
var seconds = timestamp - days * 86400 - hours * 3600 - minutes * 60;
if (days < 10) {
days = '0' + days;
}
if (hours < 10) {
hours = '0' + hours;
}
if (minutes < 10) {
minutes = '0' + minutes;
}
if (seconds < 10) {
seconds = '0' + seconds;
}
$(this).text(days + ':' + hours + ':' + minutes + ':' + seconds);
});
}, 1000);
})
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<h1 class="countdown">02:03:05:59</h1>
Your snippet goes from dd:hh:mm:ss to dd days, hh hours. So second time around, your tag contains non-parsable text.
I have changed it to something more precise. Something even MORE precise would be to give a timestamp in milliseconds in the future instead of something with seconds since it will take several seconds to render the page. If you round on minutes from the server, it would likely be better.
var aDay = 24*60*60*1000, anHour = 60*60*1000, aMin = 60*1000, aSec = 1000;
$(document).ready(function() {
$('.countdown').each(function() {
var time = $(this).data("time").split(':');
var date = new Date();
date.setDate(date.getDate()+parseInt(time[0],10))
date.setHours(date.getHours()+parseInt(time[1],10),date.getMinutes()+parseInt(time[2],10),date.getSeconds()+parseInt(time[3],10),0)
$(this).data("when",date.getTime());
});
setInterval(function() {
$('.countdown').each(function() {
var diff = new Date(+$(this).data("when"))-new Date().getTime();
var seconds, minutes, hours, days, x = diff / 1000;
seconds = Math.floor(x%60); x=(x/60|0); minutes = x % 60; x= (x/60|0); hours = x % 24; x=(x/24|0); days = x;
$(this).text(
days + ' day' +(days==1?", ":"s, ") +
hours + ' hour' +(hours==1?", ":"s, ") +
minutes + ' minute'+(minutes==1?", ":"s, ") +
seconds + ' second'+(seconds==1?".":"s.")
);
});
}, 500);
})
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<h1 class="countdown" data-time="02:03:05:59"></h1>

How to make a function affect everything with a class but also take into account a data attribute

I am making a comments system for my site and want to have the time since posted update at a set interval. Currently my javascript only takes into account one data-time attribute for every class but I want it to use each classes data-time attribute.
My html looks something a little like this
<div class="commentTime noSelect" data-time="1424867042">0 days and 0 hours and 5 minutes and 40 seconds</div>
<div class="commentTime noSelect" data-time="1424863061">0 days and 0 hours and 5 minutes and 40 seconds</div>
<div class="commentTime noSelect" data-time="1424861992">0 days and 0 hours and 5 minutes and 40 seconds</div>
etc...
data-time is the time in seconds since 1970. Now here's my javascript.
//Time Update Function
function time_elapsed() {
time = $(".commentTime").attr("data-time");
currentTime = new Date().getTime() / 1000;
time = currentTime - time;
var days = Math.floor(time / 86400);
var hours = Math.floor((time - (days * 86400 ))/3600);
var minutes = Math.floor((time - (days * 86400 ) - (hours *3600 ))/60);
var seconds = Math.floor((time - (days * 86400 ) - (hours *3600 ) - (minutes*60)));
if ( seconds > 1 ){ updatedTime = seconds + " seconds"; }else{ updatedTime = seconds + " second"; }
if ( minutes > 1 ){ updatedTime = minutes + " minutes and " + updatedTime; }else{ updatedTime = minutes + " minute and " + updatedTime; }
if ( minutes > 1 ){ updatedTime = hours + " hours and " + updatedTime; }else{ updatedTime = hours + " hour and " + updatedTime; }
if ( minutes > 1 ){ updatedTime = days + " days and " + updatedTime; }else{ updatedTime = days + " day and " + updatedTime; }
$(".commentTime").html(updatedTime);
}
setInterval(time_elapsed(),1000);
I'm pretty new to javascript and I just can't seem to make it treat each div uniquely.
Try something like that, see also Fiddle http://jsfiddle.net/ApfJz/37/:
function time_elapsed() {
$(".commentTime").each(function(){
var time = $(this).attr("data-time");
var currentTime = new Date().getTime() / 1000;
var updatedTime;
time = currentTime - time;
var days = Math.floor(time / 86400);
var hours = Math.floor((time - (days * 86400 ))/3600);
var minutes = Math.floor((time - (days * 86400 ) - (hours *3600 ))/60);
var seconds = Math.floor((time - (days * 86400 ) - (hours *3600 ) - (minutes*60)));
if ( seconds > 1 ){ updatedTime = seconds + " seconds"; }else{ updatedTime = seconds + " second"; }
if ( minutes > 1 ){ updatedTime = minutes + " minutes and " + updatedTime; }else{ updatedTime = minutes + " minute and " + updatedTime; }
if ( minutes > 1 ){ updatedTime = hours + " hours and " + updatedTime; }else{ updatedTime = hours + " hour and " + updatedTime; }
if ( minutes > 1 ){ updatedTime = days + " days and " + updatedTime; }else{ updatedTime = days + " day and " + updatedTime; }
$(this).html(updatedTime);
});
}
setInterval(time_elapsed,1000);
What you are doing is when you select the time it takes it from $(".commentTime"); which select more than one element. You have to select them all and loop through - treating each one individually. This could be tidied up further but I think this should work:
function time_elapsed() {
$(".commentTime").each(function(){
time = $(this).attr("data-time");
currentTime = new Date().getTime() / 1000;
time = currentTime - time;
var days = Math.floor(time / 86400);
var hours = Math.floor((time - (days * 86400 ))/3600);
var minutes = Math.floor((time - (days * 86400 ) - (hours *3600 ))/60);
var seconds = Math.floor((time - (days * 86400 ) - (hours *3600 ) - (minutes*60)));
updatedTime = seconds + " second" + (seconds == 1 ? "" : "s");
updatedTime = minutes + " minute" + (minutes == 1 ? "" : "s") + " and " + updatedTime;
updatedTime = hours + " hour" + (hours == 1 ? "" : "s") + " and " + updatedTime;
updatedTime = days + " day" + (days == 1 ? "" : "s") + " and " + updatedTime;
$(this).html(updatedTime);
});
}
setInterval(time_elapsed,1000);

How can I calculate a time difference with JavaScript's float-only math?

Goal: Take a Unix-time value from the past, and express its offset from current time in the format "10h 18m 22s".
Current Code:
function humaniseTime(epoch) {
nowtime = (new Date).getTime()/1000; // current ms to s
secs = Math.round(nowtime-epoch);
hours = secs/3600;
secs -= hours*3600;
minutes = secs/60;
secs -= minutes*60;
clockstring = hours + "h " + minutes + "m " + secs + "s";
return clockstring;
}
The problem is that because JavaScript isn't working with integers but with floats, I just wind up getting 0.564166666 hours rather than 0h 17m 22s. Using a rounding function gives me negative times which is no good.
I have written another solution for you which is different from yours but working like a charm, here is the code:
function secondsToString(seconds)
{
var numyears = Math.floor(seconds / 31536000);
var numdays = Math.floor((seconds % 31536000) / 86400);
var numhours = Math.floor(((seconds % 31536000) % 86400) / 3600);
var numminutes = Math.floor((((seconds % 31536000) % 86400) % 3600) / 60);
var numseconds = (((seconds % 31536000) % 86400) % 3600) % 60;
return numyears + " years " + numdays + " days " + numhours + " hours " + numminutes + " minutes " + numseconds + " seconds";
}
var epoch = Math.floor(1294862756114/1000); //in your case this will be function argument, converting it into seconds as well
alert("Epoch: " + epoch)
var time = Math.floor((new Date().getTime())/1000);
alert("Current Time: " + time);
var difference = time-epoch;
alert("Difference: " + secondsToString(difference));
It's fairly straight forward hopefully you won't have a problem understanding it. I have basically added a function which converts seconds to number of years, months, days, hours. You can play around with it now to keep whatever values you need.
See the deamo here

Categories

Resources