JavaScript countdown until date - javascript

So I'm trying to build a very minimalistic countdown timer until a specific date (2015 July 31, 18:00:00 GMT) including total MS until the date, as well as a D:H:M:S:MS until the date.
What I got so far is at this codepen:
http://codepen.io/svbeon/pen/MwBJNJ
With this JS:
setInterval(times, 1);
function times() {
today = new Date();
July = new Date(Date.UTC(2015,06,31,18,0,0,0));
diffMs = ((July - today) - today.getTimezoneOffset() * 60000); // milliseconds between now & July 31
diffDays = (July.getDate() - today.getDate()); // days
diffHrs = (24 + ((July.getHours() - today.getHours()) + (today.getTimezoneOffset() / 60))); // hours
diffMins = (60 + (July.getMinutes() - today.getMinutes())); // minutes
diffSecs = (60 + (July.getSeconds() - today.getSeconds())); // seconds
diffMis = (1000 + (July.getMilliseconds() - today.getMilliseconds())); //milliseconds
if (diffMs <= 0) {
diffMs = 0;
diffDays = 0;
diffHrs = 0;
diffMins = 0;
diffSecs = 0;
diffMis = 0;
}
document.getElementById("timer").innerHTML = diffMs + " miliseconds";
document.getElementById("timer2").innerHTML = diffDays + " days " + diffHrs + " Hours " + diffMins + " Minutes " + diffSecs + " seconds " + diffMis + " milliseconds";
document.getElementById("date").innerHTML = "until " + July;
}
The problems I get here is that it can echo something like 14 days 24 hours 60 minutes 60 seconds 1000 milliseconds when it in fact should be 14 days 0 hours 0 minutes 0 seconds 0 milliseconds as well as after 18:00 UTC it still says 14 days instead of 13 days until midnight.
I got no real idea of how to simply fix these problems
Adding one less for example:
diffSecs = (59 + (July.getSeconds() - today.getSeconds())); // seconds
Will result in the timer showing 0 instead of 60, but will as well make the timer go 1 second wrong (minute or hour if you have it on their part)
So if you happen to have any idea how to fix this and help a not so skilled developer iIwould be really happy!!

I'd suggest using Moment.js, as it makes date/time manipulation much simpler and will probably help you solve this problem also.
For instance to get a difference between two dates in milliseconds:
var a = moment([2007, 0, 29]);
var b = moment([2007, 0, 28]);
a.diff(b) // 86400000
Then create a duration from the result of the difference in milliseconds and use milliseconds(), seconds(), etc functions to display duration in different units:
moment.duration(1500).milliseconds(); // 500
moment.duration(1500).seconds(); // 1
Partial solution: https://jsfiddle.net/krlkv/xvstvfdb/3/

Just use mod:
day = day%24;
secs = secs%60;
and etc.

Related

Calculating Time Until a Future Date - Trouble With Formatting Date Correctly In Variables

I'm trying to calculate the time between now (any time user runs script) and daylight savings (Nov 03, 2019, 2:00 AM).
I think I'm close but am having trouble getting the date variables to format and interact properly. What would the right definition for the variable dateTime be, or am I messing up with the variable daylightDate?
function daylightTime()
{
var today = new Date();
var date = today.getFullYear()+'-'+(today.getMonth()+1)+'-'+today.getDate();
var time = today.getHours() + ":" + today.getMinutes() + ":" + today.getSeconds();
var dateTime = date+' '+time;
document.getElementById("time1").innerHTML = "Current Date and Time: " +dateTime;
var daylightDate = new Date("November 03, 2019 02:00:00");
var delta = Math.abs(daylightDate - dateTime) / 1000;
// calculate (and subtract) whole days
var days = Math.floor(delta / 86400);
delta -= days * 86400;
// calculate (and subtract) whole hours
var hours = Math.floor(delta / 3600) % 24;
delta -= hours * 3600;
// calculate (and subtract) whole minutes
var minutes = Math.floor(delta / 60) % 60;
delta -= minutes * 60;
// what's left is seconds
var seconds = delta % 60; // in theory the modulus is not required
document.getElementById("time2").innerHTML = days + " " + hours + " " + minutes + " " + seconds;
}

What is the best way to get time backwards in Angular

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);

Javascript multiple work hours calculate from date to now

I need a javascript like this one
// Calculate days since 7st May 2016
var initialDate = new Date(2016, 5, 7);
var now = Date.now();
var difference = now - initialDate;
var millisecondsPerDay = 24 * 60 * 60 * 1000;
var daysSince = Math.floor(difference / millisecondsPerDay);
// Write result to HTML
document.getElementById('days_since').innerHTML = daysSince;
<div id="days_since"></div>
but I would like to display hours and my work is eg. monday-friday from 10am to 6pm and every saturday from 11am to 3pm.
Any advice?
Hi please refer this http://jsfiddle.net/yentup/fKA9X/1/
JS
$(function(){
var calcNewYear = setInterval(function(){
date_future = new Date(new Date().getFullYear() +1, 0, 1);
date_now = new Date();
seconds = Math.floor((date_future - (date_now))/1000);
minutes = Math.floor(seconds/60);
hours = Math.floor(minutes/60);
days = Math.floor(hours/24);
hours = hours-(days*24);
minutes = minutes-(days*24*60)-(hours*60);
seconds = seconds-(days*24*60*60)-(hours*60*60)-(minutes*60);
$("#time").text("Time until new year:\nDays: " + days + " Hours: " + hours + " Minutes: " + minutes + " Seconds: " + seconds);
},1000);
});
and HTML
<div id="time"></div>

String to date conversion not working correctly in Javascript

I need to get time difference in this format: "HH:MM:SS" using a Javascript.
I have tried this:
var diff = Date.parse( time2) - Date.parse( time1 );
var total_time = (diff / 1000 / 60 / 60) + ":" + (diff / 1000 / 60) + ":" + (diff / 1000);
and this:
var diff = new Date( time2) - new Date( time1 );
var total_time = (diff / 1000 / 60 / 60) + ":" + (diff / 1000 / 60) + ":" + (diff / 1000);
These are the values of time2 and time1:
time1: "2012-11-07 15:20:32.161"
time2: "2012-11-07 17:55:41.451"
And result I am getting in both cases is:
total_time= 0.5250819444444444:31.504916666666666:1890.295
Which you can see is not correct
I think you are getting wrong diff value because of the millisecond part in the date delimited by .. Its not being accepted correctly by the data parser.
Try using the date and time part excluding the milliseconds as below:
var diff = Date.parse(time2.split(".")[0]) - Date.parse( time1.split(".")[0]);
Also while you are getting wrong difference diff, your time computation is also wrong.
It should be:
var second = Math.floor(diff /1000);
//convert the seconds into minutes and remainder is updated seconds value
var minute = Math.floor(second /60);
second = second % 60;
//convert the minutes into hours and remainder is updated minutes value
var hour = Math.floor(minute/60);
minute = minute %60;
var total_time= hour+":" minute+":"+second;
You forgot to remove the number of milliseconds you already calculated from diff. Here is a very verbose example on how you do it in a propper way.
var time1 = "2012-11-07 15:20:32.161",
time2 = "2012-11-07 17:55:41.451",
SECOND = 1000,
MINUTE = SECOND* 60,
HOUR = MINUTE* 60;
var diff = new Date(time2) - new Date(time1);
var hours = Math.floor(diff / HOUR); // Calculate how many times a full hour fits into diff
diff = diff - (hours * HOUR); // Remove hours from difference, we already caluclated those
var minutes = Math.floor(diff / MINUTE); // Calculate how many times a full minute fits into diff
diff = diff - (minutes * MINUTE); // Remove minutes from difference
var seconds = Math.floor(diff / SECOND); // As before
diff = diff - (seconds * SECOND);
var rest = diff;
var total_time = hours + ":" + minutes + ":" + seconds + " " + rest ;
DEMO

Javascript fuzzy time (e.g '10 minutes ago') that's in exact seconds

I'm making a javascript counter that counts 'seconds ago'. I have my time in a JS time object, and I found a "time difference" function snippet here on stack overflow, but it displays "2 hours ago". How can I get it to display "5 hours, 10 minutes and 37 seconds ago."
Here's what I'm working with:
This function converts the current time and the timestamp of something into "20 seconds ago" instead of a cryptic date:
function timeDifference(current, previous) {
var msPerMinute = 60 * 1000;
var msPerHour = msPerMinute * 60;
var msPerDay = msPerHour * 24;
var msPerMonth = msPerDay * 30;
var msPerYear = msPerDay * 365;
var elapsed = current - previous;
if (elapsed < msPerMinute) {
return Math.round(elapsed/1000) + ' seconds ago';
} else if (elapsed < msPerHour) {
return Math.round(elapsed/msPerMinute) + ' minutes ago';
} else if (elapsed < msPerDay ) {
return Math.round(elapsed/msPerHour ) + ' hours ago';
} else if (elapsed < msPerMonth) {
return 'approximately ' + Math.round(elapsed/msPerDay) + ' days ago';
} else if (elapsed < msPerYear) {
return 'approximately ' + Math.round(elapsed/msPerMonth) + ' months ago';
} else {
return 'approximately ' + Math.round(elapsed/msPerYear ) + ' years ago';
}
}
And here's what I'm using to "count up" the time each second. I'd like it to say "5 hours, 3 minutes, 10 seconds ago" and then 1 second later, "5 hours, 3 minutes, 11 seconds ago"
var newTime = new Date(data.popular[i].timestamp*1000)
var relTime = timeDifference(new Date(),newTime)
setInterval(function(){
var theTimeEl = $('.timestamp-large').filter(function(){
return $(this).html() == relTime
});
newTime.setSeconds(newTime.getSeconds() + 1);
var relTime = timeDifference(new Date(), newTime);
$(theTimeEl).html(relTime);
console.log(relTime)
}, 1000)
The variable newTime is the time in the UTC javascript date format. relTime is that in "seconds ago" format. The interval loops through a bunch of timestamp elements and picks the right one for each time stamp. Then it adds a second to the time, converts it back into "fuzzy time" (seconds ago), replaces the html with the new time and logs it in the console.
How do I change "5 hours ago" to "5 hours, 37 mintues, 10 seconds ago"? The time difference function needs to be modified.
Here's a function that is close to what you're asking for.
var timeparts = [
{name: 'year', div: 31536000000, mod: 10000},
{name: 'day', div: 86400000, mod: 365},
{name: 'hour', div: 3600000, mod: 24},
{name: 'minute', div: 60000, mod: 60},
{name: 'second', div: 1000, mod: 60}
];
function timeAgoNaive(comparisonDate) {
var
i = 0,
l = timeparts.length,
calc,
values = [],
interval = new Date().getTime() - comparisonDate.getTime();
while (i < l) {
calc = Math.floor(interval / timeparts[i].div) % timeparts[i].mod;
if (calc) {
values.push(calc + ' ' + timeparts[i].name + (calc != 1 ? 's' : ''));
}
i += 1;
}
if (values.length === 0) { values.push('0 seconds'); }
return values.join(', ') + ' ago';
}
console.log(timeAgoNaive(new Date(Date.parse('Jun 12 2006 11:52:33'))));
console.log(timeAgoNaive(new Date(new Date().getTime() - 3600000)));
console.log(timeAgoNaive(new Date()));
Results:
6 years, 33 days, 4 hours, 52 minutes, 22 seconds ago
1 hour ago
0 seconds ago
I called it "naive" because it doesn't really pay attention to the human way that we calculate time. If it is "1/1/2013 12:01:00 am" exactly, comparing to "1/1/2012 12:01:00 am" should yield "1 year, 0 months, 0 days, 0 hours, 0 minutes, 0 seconds ago". But it won't do that by extending the logic in the function you presented, and it won't do that in my function either (plus my function won't use months). A better approximation of years than 365 days is 365.24, but that also is ignored.
I excluded the empty time parts as you requested, leaving "0 seconds" at a minimum when there are no time parts found.
Now, if you want that human-like way of calculating, you have to decide some things. You can't just use boundaries crossed because Feb 28 to Mar 1 is not a whole month. Second, here's a question will expose the real problem:
How many months and days is Feb 2 to Mar 31?
If you calculate Feb 2 to Mar 2 as one month, then it's 1 month 29 days. But what if it were Jan 2 to Mar 1? That's the same number of days elapsed between them. Is that now 1 month (for all of April) + 1 day in March + the 31 days in Jan for 1 month 32 days? Do you want your months to coincide to a physical calendar so a human could back track with his finger and get the correct date out of it? That is much harder than you think.
If you can answer with sensible and complete rules about how you would do "human-like elapsed time figuring" then maybe I can write you another function to do it.
Update
Here's a new function that does months, and has 365.24 days in a year (30.43666666 days in a month):
var timeparts = [
{name: 'millenni', div: 31556736000, p: 'a', s: 'um'},
{name: 'centur', div: 3155673600, p: 'ies', s: 'y'},
{name: 'decade', div: 315567360},
{name: 'year', div: 31556736},
{name: 'month', div: 2629728},
{name: 'day', div: 86400},
{name: 'hour', div: 3600},
{name: 'minute', div: 60},
{name: 'second', div: 1}
];
function timeAgoNaive2(comparisonDate) {
var i = 0,
parts = [],
interval = Math.floor((new Date().getTime() - comparisonDate.getTime()) / 1000);
for ( ; interval > 0; i += 1) {
var value = Math.floor(interval / timeparts[i].div);
interval = interval - (value * timeparts[i].div);
if (value) {
parts.push(value + ' ' + timeparts[i].name + (value !== 1 ? timeparts[i].p || 's' : timeparts[i].s || ''));
}
}
if (parts.length === 0) { return 'now'; }
return parts.join(', ') + ' ago';
}
console.log(timeAgoNaive2(new Date(Date.parse('Jun 12 2006 11:52:33'))));
console.log(timeAgoNaive2(new Date(new Date().getTime() - 3600000)));
console.log(timeAgoNaive2(new Date()));
console.log(timeAgoNaive2(new Date(-92709631247000)));
Output:
6 years, 1 month, 1 day, 10 hours, 53 minutes, 44 seconds ago
1 hour ago
now
2 millennia, 9 centuries, 8 decades, 4 months, 26 days, 22 hours, 41 minutes, 47 seconds ago
It is still naive, but it does a little better job. Plus it will work for REALLY old dates like B.C. ones. :)
Change the logic so that rather than just finding the single greatest unit of measurement it can, it does something with the remainder.
Basically what you'd need to do is start with the greatest increment, find the value, then subtract it from the total to get the remainder. Then repeat.
Something like this maybe, I haven't tested it.
var elapsed = current - previous;
var remainder = elapsed;
int years;
int months;
years = Math.floor(remainder/msPerYear);
remainder = remainder % msPerYear;
months = Math.floor(remainder/msPerMonth);
remainder = remainder % msPerMonth;
// repeat
Then just build your string off the variables.
This should do the trick:
var msPerMinute = 60 * 1000;
var msPerHour = msPerMinute * 60;
var msPerDay = msPerHour * 24;
var msPerMonth = msPerDay * 30;
var msPerYear = msPerDay * 365;
function timeDifference(current, previous) {
var remainder = current - previous;
var message = "";
var sep = "";
var years = Math.floor(remainder/msPerYear);
remainder = remainder - years * msPerYear;
if (years > 0) {
message += years + " years";
sep = ", ";
console.log(message);
}
var months = Math.floor(remainder/msPerMonth);
remainder = remainder - months * msPerMonth;
if (months > 0) {
message += sep + months + " months";
sep = ", ";
console.log(message);
}
var days = Math.floor(remainder/msPerDay);
remainder = remainder - days * msPerDay;
if (days > 0) {
message += sep + days + " days";
sep = ", ";
console.log(message);
}
var hours = Math.floor(remainder/msPerHour);
remainder = remainder - hours * msPerHour;
if (hours > 0) {
message += sep + hours + " hours";
sep = ", ";
console.log(message);
}
var minutes = Math.floor(remainder/msPerMinute);
remainder = remainder - minutes * msPerMinute;
if (months > 0) {
message += sep + minutes + " minutes";
sep = ", ";
console.log(message);
}
var seconds = Math.floor(remainder/1000);
remainder = remainder - seconds * 1000;
if (months > 0) {
message += sep + seconds + " seconds";
sep = ", ";
console.log(message);
}
message += " ago";
var pos = message.lastIndexOf(',');
message = message.substring(0,pos) + ' and' + message.substring(pos+1)
return message;
};
var output = timeDifference(new Date(2012, 10, 20, 12, 0, 59), new Date(2012, 2, 13, 10, 15, 12));
console.log(output);
Output: 8 months, 12 days, 1 hours, 45 minutes and 47 seconds ago
This could of course be refactored to be a bit less repetitive.
​
You can try out this fiddle with it working: http://jsfiddle.net/vawEf/

Categories

Resources