I am trying to convert a number of weeks, days and hours to seconds and then convert them back again.
When I convert them back, days and hours are not correct:
var weeks = 3,
days = 5,
hours = 1;
//convert to seconds
sec_in_w = weeks * 604800,
sec_in_d = days * 86400,
secs_in_h = hours * 3600,
secs = sec_in_w + sec_in_d + secs_in_h;
//convert back to weeks, days, and hours
new_w = Math.floor(secs / 604800);
secs -= new_w;
new_d = Math.floor(secs / 86400);
secs -= new_d;
new_h = Math.floor(secs / 3600);
console.log('weeks: ' + new_w);
console.log('days: ' + new_d);
console.log('hour: ' + new_h);
DEMO:
http://codepen.io/anon/pen/avZwBp
//convert back to weeks, days, and hours
new_w = Math.floor(secs / 604800);
secs = secs % 604800;
new_d = Math.floor(secs / 86400);
secs = secs % 86400;
new_h = Math.floor(secs / 3600);
Using Modulus gives the remainder.
You are subtracting the number of weeks and days, not the number of seconds in the weeks or days.
secs -= new_w * 604800;
new_d = Math.floor(secs / 86400);
secs -= new_d * 86400;
You have to subtract the number of weeks and days from the seconds
//convert to seconds
sec_in_w = weeks * 604800,
sec_in_d = days * 86400,
secs_in_h = hours * 3600,
secs = sec_in_w + sec_in_d + secs_in_h;
codepen
Lets see whats happening here:
In the line:
secs = sec_in_w + sec_in_d + secs_in_h;
you are adding the value in seconds of 3 weeks + 5 days + 1 hour, or
secs = 2250000;
Then you devide by 604800, and you get 3 as you should, and then you substract this 3 from the big value of secs :). You can do the math yourself:
(2250000 - 3 ) / 86400 = 26
exactly what you got :) The same for the hours.
The solution is to first convert your numbers back to their representation in seconds.
//convert back to weeks, days, and hours
new_w = Math.floor(secs / 604800);
secs -= new_w * 604800;
new_d = Math.floor(secs / 86400);
secs -= new_d * 86400;
new_h = Math.floor(secs / 3600);
By the way, javascript has solutions for handling dates. If you are doing this for the exercise I said nothing of course :)
Related
I want to calculate the difference beetween two dates in Javascript in months, weeks, days, hours, minutes and seconds.
Problem:
Weeks and days aren't calculated properly.
I already tried to change .get...() into .getUTC...() but the difference was calculated wrong either.
var date = new Date("{% if holiday.is_now %}{{ holiday.end_date.isoformat }}{% else %}{{ holiday.end_date.isoformat }}{% endif %}");
function calcDate(a, b) {
var utc1 = Date.UTC(a.getFullYear(), a.getMonth(), a.getDay(), a.getHours(), a.getMinutes(), a.getSeconds());
var utc2 = Date.UTC(b.getFullYear(), b.getMonth(), b.getDay(), b.getHours(), b.getMinutes(), b.getSeconds());
return (utc2 - utc1) / 1000;
}
function convertDate(seconds){
var sec = Math.floor(seconds % 60);
var min = Math.floor(seconds / 60 % 60);
var hour = Math.floor(seconds / 60 / 60 % 24);
var diff = seconds / 60 / 60 / 24;
var months = Math.floor(diff / 30);
var weeks = Math.floor(diff / 7 % (30 / 7));
var days = Math.floor(diff % 7);
console.log(days);
return [months, weeks, days, hour, min, sec]
}
function add_countdown(sec){
$.each(convertDate(sec), function(i, element){
var selected = $("footer .countdown .counter#_counter_date_" + i);
selected.find("h1").text(element);
singular_pluralize(selected.find("p"), element);
})
}
function singular_pluralize(element, integer){
integer > 1 || integer == 0 ? element.text(element.attr("data-word-plural")) : element.text(element.attr("data-word-singular"));
}
var interval;
$("footer table td.a").on("click mouseup", function(){
clearInterval(interval);
date = new Date($(this).attr("data-date"));
$("footer #_foter_big_countdown_to_what").text("zu den " + $(this).attr("data-name").replace(/ /g, ''));
set_interval();
})
function set_interval(){
add_countdown(calcDate(new Date(), date));
interval = window.setInterval(function(){
var calc = calcDate(new Date(), date);
if (calc == 0)
holiday_begin();
else
add_countdown(calc);
}, 900);
}
function holiday_begin(){
$("footer .counter, footer .part#_footer_select_holiday").remove();
$("footer .darken h1._footer_big_countdown").html("Fröhliche Ferien!");
}
set_interval();
EDIT:
I found the solution. I had to use Math.round and I had to change a little bit:
function convertDate(seconds){
var sec = Math.round(seconds % 60);
var min = Math.round(seconds / 60 % 60);
var hour = Math.round(seconds / 60 / 60 % 24);
var diff = seconds / 60 / 60 / 24;
var months = Math.round(diff / 30);
var days = Math.round(diff % 30);
var weeks = Math.round(months / 4.3);
return [months, weeks, days, hour, min, sec]
}
I need to change my return time settings from hours to days.
I've tried to expand the hours but I keep getting errors.
let totalSeconds = (client.uptime / 1000);
let hours = Math.floor(totalSeconds / 3600);
totalSeconds %= 3600;
let minutes = Math.floor(totalSeconds / 60);
let seconds = totalSeconds % 60;
// Then you'll have hours, minutes and seconds ready to use.
let uptime = `${hours} hours, ${minutes} minutes and ${seconds} seconds`;
I just keep getting errors.
Converting hours to days would be extremely simple - you just divide by 24 and floor it:
var days = Math.floor(hours / 24);
Hopefully this helps!
i can image someone had donde this already or it can be considered a duplicated question, i've been searching for weeks and i can't figure out how to accomplish this.
I have a countdown made in js, the problem i'm facing is that when ever i test it in another country the times throw out different hours example.
i'm in centralamerica, end date is apr 16, 2018 23:59:59" if i test this in centralamerica it says 6 days and 10 hours remaining, if i run this in italy for example it says 6 days and 3 hours remaining, i need it to be equal all the time and that the timezone doesn´t affects, is this even possible, and please help on how to get it done.
the script i have is working but not the way i need to, i have a promo that will expire on "apr 16, 2018 23:59:59" so if it only has 5 hours remaining it shout say 5 hours remaining no matter where its been seeing from, but that is not happening.
$("#masterslider").append("<p id='demo'>.</p>")
$("#masterslider").append("<span> remaining time </span>")
//******************************** update date here ************************
var serverDate = new Date("apr 16, 2018 23:59:59");
var offset = serverDate.getTimezoneOffset();
serverDate = addOffset(serverDate, offset);
setInterval(function(){
updateCountdown();
}, 1000);
function addOffset(date, offset) {
var time = date.getTime() ;
return new Date(time + offset * 6000);
}
function updateCountdown() {
var userDate = new Date();
var distance = serverDate.getTime() - userDate.getTime();
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(serverDate.getTime() > userDate.getTime()){
$('#demo').html( days +"day(s)"+ " / " + hours + "hour(s)" + minutes + "minutes(s)");
}
else
{
$("#demo").html(mas);
$("#masterslider span").hide();
}
}
</script>
I've checked and setting correct timezone for "event timestamp" works for me regardless local client timezone I use.
let targetDate = new Date("2018-04-11 23:59:59 GMT-0800");
let refreshDelayMs = 1000;
function updateCounter() {
let distance = (targetDate - new Date()) / 1000;
let seconds = Math.floor(distance % 60).toString().padStart(2, '0');
distance = distance / 60;
let minutes = Math.floor(distance % 60).toString().padStart(2, '0');
distance = distance / 60;
let hours = Math.floor(distance % 24).toString().padStart(2, '0');
let days = Math.floor(distance / 24).toString().padStart(2, '0');
document.querySelector('.counter').innerHTML = `${days} days ${hours}:${minutes}:${seconds}`;
setTimeout(updateCounter, refreshDelayMs);
}
updateCounter();
Remains: <span class="counter"></span>
You can use moment-timezone from CDN or use NPM
repl.it sample
const moment = require("moment-timezone");
function toTimeZone(time, offset) {
var format = 'YYYY/MM/DD HH:mm:ss ZZ';
return moment(time, format).utcOffset(offset).format(format);
}
toTimeZone("2018/04/10 15:37", "+0730")
time -= 50 * 60
I am unsure why time-= is used in the above code snippet? What is the purpose?
Hours is equal to the number of hours in the number of seconds rounded down to a whole number. This difference between hours and the precise number of seconds contains an amount between 0 and just below the maximum number of seconds in 1 hour. To get this, the time in Hours is subtracted from the number of seconds. A similar process follows for the number of minutes.
I will explain line by line to help you get this point:
var seconds = count; //25 * 60 = 1500 (1)
=> just get total seconds before calculating
var hours = Math.floor(seconds / 3600);
=> this is how to calculate hour
seconds -= hours * 3600;
=> this code can be written is easy way seconds = seconds - (hours * 3600);
so the result seconds in this line is the remain second after calculating hours. Now if you get this point the remain code is easily to understand.
var minutes = Math.floor(seconds / 60);
seconds -= minutes * 60
Now, after running this code you can check the result by:
var total_seconds = hours*3600 + minutes*60 + seconds;
The result total_seconds must be equal to value of seconds in the first line of code (1).
This is the basic of programming. If you cannot understand, try to debug it by console.log() to show result. Try yourself is the good way to improve your skill.
var seconds = 7510;
console.log("seconds: "+seconds);
var hours = Math.floor(seconds / 3600);
seconds -= hours * 3600;
console.log("hour: "+hours);
console.log("seconds after calculating hours: "+seconds);
var minutes = Math.floor(seconds / 60);
seconds -= minutes * 60;
console.log("minutes: "+minutes);
console.log("seconds after calculating munites: "+seconds);
var total_seconds = hours*3600 + minutes*60 + seconds;
console.log("total_seconds: "+total_seconds);
Currently I have a script, which has a countdown for a specific date, but I want the countdown to be specific on a timer, so let's say if I start the timer and I have set the timer to run for 30 days, it will then run for 30 days and then reset back to 30 days again and start running. Is it possible to change it to do so?
My code:
<body>
<span id="countdown"></span>
<script LANGUAGE="Javascript">
// set the date we're counting down to
var target_date = new Date("Apr 9, 2015").getTime();
// variables for time units
var days, hours, minutes, seconds;
// get tag element
var countdown = document.getElementById("countdown");
// update the tag with id "countdown" every 1 second
setInterval(function () {
// find the amount of "seconds" between now and target
var current_date = new Date().getTime();
var seconds_left = (target_date - current_date) / 1000;
// do some time calculations
days = parseInt(seconds_left / 86400);
seconds_left = seconds_left % 86400;
hours = parseInt(seconds_left / 3600);
seconds_left = seconds_left % 3600;
minutes = parseInt(seconds_left / 60);
seconds = parseInt(seconds_left % 60);
// format countdown string + set tag value
countdown.innerHTML = days + "d, " + hours + "h, "
+ minutes + "m, " + seconds + "s";
}, 1000);
</script>
</body>
EDIT:
I have now changed the code to look like underneath, but now when I open the website in my browser its blank.
New code:
<span id="countdown"></span>
<script LANGUAGE="Javascript">
// set the date we're counting down to
var target_date = new Date("Apr 9, 2015").getTime();
// variables for time units
var days, hours, minutes, seconds;
// get tag element
var countdown = document.getElementById("countdown");
if (seconds_left <= 0){
target_date = target_date + 30 days;
}
// update the tag with id "countdown" every 1 second
setInterval(function () {
// find the amount of "seconds" between now and target
var current_date = new Date().getTime();
var seconds_left = (target_date - current_date) / 1000;
// do some time calculations
days = parseInt(seconds_left / 86400);
seconds_left = seconds_left % 86400;
hours = parseInt(seconds_left / 3600);
seconds_left = seconds_left % 3600;
minutes = parseInt(seconds_left / 60);
seconds = parseInt(seconds_left % 60);
// format countdown string + set tag value
countdown.innerHTML = days + "d, " + hours + "h, "
+ minutes + "m, " + seconds + "s";
}, 1000);
I really advice you to take advantage of JavaScript libraries , in your case moment JS is the perfect solution, you can check their documentation and see how you can manage time easily. Anyways here is the solution of your question using moment js.
First download moment js and add it to your page.
HTML CODE
<span id="days"> </span>
<span id="hours"></span>
<span id="minutes"></span>
<span id="seconds"></span>
It can not get simple than that :)
JAVASCRIPT
//create two variables for holding the date for 30 back from now using substract
var back30Days = moment().subtract(30, 'days').format('YYYY-MM-DD H:mm:ss');
var countDownSeconds = Math.floor(moment().diff(back30Days, 'seconds'));
//variables holding days, hours , minutes and seconds
var Days, Minutes, Hours, Seconds;
// Set Interval function for performing all calculations and decrementing the countDownSeconds
setInterval(function () {
// Updating Days
Days = pad(Math.floor(countDownSeconds / 86400), 2);
// Updating Hours
Hours = pad(Math.floor((countDownSeconds - (Days * 86400)) / 3600), 2);
// Updating Minutes
Minutes = pad(Math.floor((countDownSeconds - (Days * 86400) - (Hours * 3600)) / 60), 2);
// Updating Seconds
Seconds = pad(Math.floor((countDownSeconds - (Days * 86400) - (Hours * 3600) - (Minutes * 60))), 2);
// Updation our HTML view
document.getElementById("days").innerHTML = Days + ' Days';
document.getElementById("hours").innerHTML = Hours + ' Hours';
document.getElementById("minutes").innerHTML = Minutes + ' Minutes';
document.getElementById("seconds").innerHTML = Seconds + ' Seconds';
// Decrement the countDownSeconds
countDownSeconds--;
// If we reach zero , our chrono should reset to 30 days back again, as you told
if (countDownSeconds === 0) {
countDownSeconds = Math.floor(moment().diff(back30Days, 'seconds'));
}
}, 1000);
// Function for padding the seconds i.e limit it only to 2 digits
function pad(num, size) {
var s = num + "";
while (s.length < size) s = "0" + s;
return s;
}
Here is a jsfiddle