I'm using a mysql timestamp to calculate the difference of time through JavaScript as below,
function parseMySQLTimestamp(timestamp) {
var parts = timestamp.match(/^(\d{4})-(\d{2})-(\d{2}) (\d{2}):(\d{2}):(\d{2})$/);
return new Date(+parts[1], (+parts[2] - 1), +parts[3], +parts[4], +parts[5], +parts[6]);
}
var informTime = "2011-11-09 08:00:00";
var diff = (new Date()- parseMySQLTimestamp(informTime));
var months = Math.floor(diff /(60*60*24*30*1000));
diff=Math.abs(diff-(months*60*60*24*30*1000));
var days = Math.floor(diff/(60 * 60 * 24*1000));
diff=Math.abs(diff-(days*60*60*24*1000));
var hour=Math.floor(diff/(60*60*1000));
diff=Math.abs(diff-(hour*60*60*1000));
var minute=Math.floor(diff/(60*1000));
var message=months +" months "+ days + " D " + hour + " Hr " + minute + "min ago ";
alert(message);
it will give the correct result but I'm afraid that it will not be correct in the months which have 31,28 or 29 days other wise in leap years.
How to achieve reliable functionality? I feel it's so complicated. Thank you.
Related
I'll start by saying that i'm a beginner with HTML, Javascript and so on.
I'm building an alarm clock and now trying to add a feature that calculates the time you have to sleep.
I'm using a 24-hour clock format, and at the moment I have these parameters:
let tempWakeUpHour; //stores the 'hours' value that the user chooses in a 00 format. (01 means 01:00, 02 means 02:00, and so on, 23 means 23:00 and 24 means midnight).
let tempWakeUpMin; //stores the 'minutes' value that the user chooses in a 00 format and has only the options of 00, 05, 10, 15, and up to 55.
So the user can choose an 'hour' to wake up (24 options), and 'minutes' (12 options).
The problem i'm having is with calculating the time the user has to sleep from the time 'now' :
let dateNow = new Date();
let hourNow = dateNow.getHours();
let minNow = dateNow.getMinutes();
let tempSleepHours; **// should calculate the hours left to sleep.**
let tempSleepMins; **// should calculate the minutes left to sleep.**
...innerHTML = "you have " + tempSleepHours + " hours and " + tempSleepMins + " minutes to sleep.";
At first I tried
let tempSleepHours = Math.abs(tempWakeUpHour - hourNow);
let tempSleepMins = Math.abs(tempWakeUpMin - minNow);
but that doesn't cover all the options.
I'd appreciate it if anyone has the solution for this.
Thanks!
You need to take into account that the wakeup time will likely be in the morning and the current time could be in the evening, so hours wouldn't be a straightforward calculation (though still doable). What you could do is convert the wakeup time into a date and do a simple date comparison. For example:
let wakeupat = new Date();
wakeupat.setHours(32);
wakeupat.setMinutes(0);
wakeupat.setSeconds(0);
wakeupat.setMilliseconds(0);
function sleepremaining() {
let now = new Date();
let diff = wakeupat - now;
if (diff < 0) {
console.log("Wake up!!!!");
clearInterval(timer);
} else {
let remaining = new Date(diff);
console.log(remaining.getHours() + " hours " + remaining.getMinutes() + " minutes and " + remaining.getSeconds() + " seconds");
}
}
let timer = setInterval(sleepremaining, 1000);
The function is trying to fund the difference between to dates, but I am struggling to not return a negative number if the date is past a certain point. I have tried a few work around like using ABS but it can cause problems in future areas.
var DateCalc = {};
DateCalc.totalDaysLeft = 0;
DateCalc.calculate = function(dateToParse) {
DateCalc.init(dateToParse);
return DateCalc.stringify(DateCalc.years(), DateCalc.months(), DateCalc.days());
};
DateCalc.init = function(dateToParse) {
var date = DateCalc.parseDate(dateToParse);
var today = Date.now();
var oneDay = 24 * 60 * 60 * 1000;
DateCalc.totalDaysLeft = Math.floor((date - today) / oneDay);
};
DateCalc.parseDate = function(dateToParse) {
var dateVars = dateToParse.split(',').map(Number);
return new Date(dateVars[0], dateVars[1] - 1, dateVars[2]);
};
DateCalc.years = function() {
var years = Math.floor(DateCalc.totalDaysLeft / 365);
DateCalc.totalDaysLeft -= Math.floor(years * 365);
return years;
};
DateCalc.months = function() {
var months = Math.floor(DateCalc.totalDaysLeft / 30);
DateCalc.totalDaysLeft -= Math.floor(months * 30);
return months;
};
DateCalc.days = function() {
return Math.floor(DateCalc.totalDaysLeft / 24);
};
DateCalc.stringify = function(years, months, days) {
var dateString = "";
if (years !== 0)
dateString += years + " years, ";
if (months !== 0)
dateString += months + " months, ";
dateString += days + " day(s).";
return dateString;
};
//here is the .abs() code.
function age(year, month, day) {
var yearDifference = Math.abs(new Date().getFullYear() - year);
var monthDifference = Math.abs(new Date().getMonth() - month + 1);
var dayDifference = Math.abs(new Date().getDate() - day);
var differences = {
year: yearDifference,
month: monthDifference,
day: dayDifference
};
var final = [];
for (var time in differences) {
if (differences[time] > 0) {
var addString = differences[time] + " " + time;
if (differences[time] > 1) {
addString += "s"
}
final.push(addString);
}
}
return final.join(" ");
};
console.log(age(2017, 11, 17));
console.log(age(2016, 1, 2));
//if you tried to look up how far away next January is while you're in December, it will tell you it is 1 year 11 months from now instead of 1 month. This is because it adds the 11 months instead of subtracting it.I am trying to find a solution, as this function is more conscise but the other is more versatile. The function above, I replaced .floor() with rounds the value down with .abs() hoping it would just use the absolute value of the given operation, however, this was not the case.
The problem is that you are using the .abs() function in an inappropriate way. Most mathematical functions do no obey the distributive rule, and the .abs() function belongs to these. For an easier understanding, let us forget your current problem for a moment and let us examine a simple, reduced example:
Let's say you want to know the absolute value of -10. Obviously, the correct result is +10.
On the other hand, -10 could be written as (-20 + 10). But nevertheless, you can not compute abs(-10) using that knowledge:
abs(-20 + 10) = 10, but
abs(-20) + abs(+10) = 30
Applying that knowledge to your problem, we see that abs(Y years + M months + D days) is generally NOT equal to (abs(Y years) + abs(M months) + abs(D days)).
Regarding this problem, there is the additional oddity that each of the terms of the result has another unit, and that the terms depend on each other (e.g. there can be no term like "13 months", because that would be "1 year plus 1 month"), but I won't go into further detail here.
There is a simple solution:
1) Determine the desired resolution of your result (i.e. should your result be accurate to seconds, attoseconds, days or something else).
2) Convert the two dates into the unit determined in step 1), using a randomly chosen, yet fixed point in time as the common starting point.
3) Now you can subtract the two (converted) dates and use the .abs() function without problems.
4) Convert the result back into human readable form.
How do you do that in practice? Well, steps 1), 3) and 4) are easy, but what about step 2)?
Nearly every OS I know (and thus, nearly every programming language) does the conversion needed in step 2) for you. More often than not, the fixed point in time is 1970-01-01 00:00:00, and the OS / programming language provides routines to convert any date / time to the number of seconds (or some other unit) which have elapsed since this fixed point.
For example, in JavaScript, the myDate.getTime() function returns the number of milliseconds which have passed since 1970-01-01 up to myDate.
So convert both dates to "milliseconds since 1970-01-01" and subtract them. Use the .abs() function on the result. Then you have the desired time span as a value of positive milliseconds. Convert that back to human readable form, i.e. years, months and days (which is no problem, is it?)
A second simple solution (just for avoiding negative results):
I hope that you agree with me that comparing two dates is much easier than computing the difference between them (first compare the year; if the years differ, you have undoubtedly found the "greater" date; if the years are equal, do the same with the months, and so on). Then exchange the two dates if necessary. That way, you always can make sure that you subtract the "smaller" date from the "greater" date and that the result always will be positive.
But please note that even when doing so there will still be negative results in parts of the calculation when actually subtracting the dates, so you would have exactly the same problems when using the .abs() function.
A more complicated solution:
You could do the subtraction yourself as well, but then the .abs() function won't help you much. One of the algorithms I can think of could work like a subtraction which is done by hand (I mean the subtraction of normal numbers you have learned in school):
Begin with the least significant unit (for example the days). Subtract the days; if the result is negative, then add 28, 29, 30 or 31 (depending on the month) and make a carry to the months, otherwise keep the result; then do the same thing with the months, and so on. But as I already wrote in my comment, there are many pitfalls when doing so (leap years, months have different numbers of days, and so on), and the .abs() function will not help you here.
Conclusion:
Personally, I would prefer the first (simple) solution I have given. It is easy, understandable and future-proof.
//initial variables
var today = new Date();
var day = today.getDate();
var month = today.getMonth() + 1;
var year = today.getFullYear();
var otherDate = new Date();
var day2 = 0;
var month2 = 0;
var year2 = 0;
if (day < 10) {
day = '0' + day;
}
if (month < 10) {
month = '0' + month;
}
function age(day2, month2, year2) {
dayConv = day2;
monthConv = month2;
yearConv = year2;
newDate = day - dayConv;
newMonth = month - monthConv;
newYear = year - yearConv;
}
function mathDate() {
if (newYear >= 1) {
if (newMonth >= 1) {
if (newDate >= 1) {
console.log(newYear + " years and " + newMonth + " months and " + newDate + " days.");
return newYear + " years and " + newMonth + " months and " + newDate + " days.";
} else if (newDate <= 0) {
console.log(newYear + " years and " + newMonth + " months.");
return newYear + " years and " + newMonth + " months.";
}
} else if (newMonth <= 0) {
console.log(newYear + " years and " + newDate + " days.");
return newYear + " years and " + newDate + " days.";
}
} else if (newYear <= 1) {
if (newMonth >= 1) {
console.log(newMonth + " months and " + newDate + " days.");
return newMonth + " months and " + newDate + " days.";
} else if (newDate <= 0) {
console.log(newMonth + " months.");
return newMonth + " months.";
} else if (newMonth <= 0) {
console.log(newDate + " days.");
return newDate + " days.";
}
}
}
age(13, 4, 2016);
mathDate();
Here is the answer I was able to create.
This question already has answers here:
Calculate age given the birth date in the format YYYYMMDD
(45 answers)
Closed 7 years ago.
I want to calculate age of anything.i already wrote the program. I took a date object and assigned value into it $birth_date=new Date('Dec,15,1992'); then i subtract the value with the current data.According to the subtraction it should returns 23 years 0 months 14 days.but it returns 23 years 4 months 14 days.years and days are OK but the month misleads.
would you pls tell me why showing this weird results?
following code is HTML and next to Javascript
$(document).ready(function(){
var birth_date = new Date('Dec, 15, 1992').getTime();
var years,months,days, hours, minutes, seconds;
var ageCount = document.getElementById('counter');
setInterval(function(){
var current_date = new Date().getTime();
var total_sec =(current_date-birth_date) / 1000;
years=parseInt(total_sec/(86400*30*12));
var second_left=total_sec%(86400*30*12);
months=parseInt(second_left/(86400*30));
second_left=second_left%(86400*30);
days=parseInt(second_left/86400);
second_left=second_left%(86400);
hours=parseInt(second_left/3600);
second_left=second_left%3600;
minutes=parseInt(second_left/60);
seconds=parseInt(second_left%60);
ageCount.innerHTML=years+' Years '+months+' Months '+days+' Days '+hours+
' Hours '+minutes+' Minutes '+seconds+' Seconds';
},500);
});
<div id="counter">
</div>
<script src="http://code.jquery.com/jquery-1.11.0.min.js"></script>
I think it would make more sense to just use the basic notations as listed here for getting metrics such as date , hour , minutes, seconds from the date difference
$(document).ready(function(){
var birth_date = new Date('Feb, 15, 1992');
var years,months,days, hours, minutes, seconds;
var ageCount = document.getElementById('counter');
setInterval(function(){
var current_date = new Date();
var YearDiff = (current_date.getYear() - birth_date.getYear());
var monthDiff = (current_date.getMonth() - birth_date.getMonth());
var daysDiff = (current_date.getDate() - birth_date.getDate());
var hoursDiff = (current_date.getHours() - birth_date.getHours());
var minDiff = (current_date.getMinutes() - birth_date.getMinutes());
var secDiff = (current_date.getSeconds() - birth_date.getSeconds());
ageCount.innerHTML=YearDiff+' Years '+monthDiff+' Months '+daysDiff+' Days '+hoursDiff+
' Hours '+minDiff+' Minutes '+secDiff+' Seconds';
},500);
});
https://jsfiddle.net/DinoMyte/138bhovx/2/
You Can simply make this calculation with the following implementation.
https://jsfiddle.net/wqm704xm/1/
var birthday = new Date('Dec,15,1992');
var today;
var $dateEl = document.getElementById('date');
setInterval(writeValue, 100);
function writeValue() {
today = new Date();
var calculatedDate = calculate(normalizeDate(birthday), normalizeDate(today));
$dateEl.innerHTML =
'years: ' + calculatedDate.year + '<br>' +
'months: ' + calculatedDate.month + '<br>' +
'days: ' + calculatedDate.day + '<br>' +
'hours: ' + calculatedDate.hours + '<br>' +
'minutes: ' + calculatedDate.minutes + '<br>' +
'seconds: ' + calculatedDate.seconds + '<br>'
;
}
function calculate(firstDate, currentDate) {
return {
year: currentDate.year - firstDate.year,
month: currentDate.month - firstDate.month,
day: currentDate.day - firstDate.day,
hours: currentDate.hours - firstDate.hours,
minutes: currentDate.minutes - firstDate.minutes,
seconds: currentDate.seconds - firstDate.seconds
}
}
function normalizeDate(date) {
return {
year: date.getFullYear(),
month: date.getMonth() + 1,
day: date.getDate(),
hours: date.getHours(),
minutes: date.getMinutes(),
seconds: date.getSeconds()
};
}
<div id="date"></div>
Months is incorrect because you are assuming that every month is only 30 days long, when months can be 28, 29, 30 or 31 days in length (and in some circumstances, other lengths).
To quickly see where you are going wrong, and ignoring leap years, 30/days a month would mean 30*12 only 360 days per year. That means every year you miss 5 days. So given 23 years, that's roughly 23*5 days difference, or ~4 months.
There were 5 leap years in between your date and now, adding 5 more days to the difference. This completely accounts for your 4 months (120 days).
You need to adjust your algorithm to account for these differences.
Additional info:
If you are using this in production code and require accurate dates - please keep in mind a date is not sufficient information to calculate precise differences in terms of number of days. You'll also need information such as time zone and location and handle all sorts of lovely time discontinuations.
For example: In 2011 Samoa jumped to the other side of the international date line. So 29-Dec-2011 to 1-Jan-2012 is 1 day longer in Australia than it was in Samoa.
(╯°□°)╯︵ ┻━┻
This is an easy thing to do in PHP with code like this;
if (strtotime($given_time) >= time()+300) echo "You are online";
But can't find anything on SO to do exactly this in javascript.
I want to check if the difference between a given time and the current time is less than 45mins
For instance
$scope.given_time = "14:10:00"
$scope.current_time = new Date();
I'm only concerned with the time part. I need to extract time part from new Date(); and then compare.
Then this should be true
How can I achieve this with Javascript:
if ($scope.given_time - $scope.current_time < 45 minutes) {
// do something
}
Javascript uses unix timestamps in milliseconds, so it is similar to the output of strtotime (which uses seconds).
var date = new Date();
Then you'll need to do the calculation from milliseconds. (Minutes * 60 * 1000)
You can also use date.parse() to parse a string to milliseconds, just like strtotime() in PHP does to seconds.
In full:
var date = new Date();
var last = new Date('Previous Date'); // or a previous millisecond timestamp
if ( ( date - last ) > ( 45 * 60 * 1000 ) ) {
// do something
}
You could use a static date to compare just time, this is exactly what strtotime does if you exclude the date:
var last = new Date('1/1/70 14:10:00');
var date = new Date('1/1/70 14:30:00');
However, this approach will fail if you're trying to compare time that cross over day boundaries.
Try this:
function checkTime(time) {
var date = new Date();
var date1 = new Date((date.getMonth() + 1) + "/" + date.getDate() + "/" + date.getFullYear() + " " + time);
var minutes = (date1.getTime() - date.getTime()) / (60 * 1000);
if (minutes > 45 || (minutes < 0 && minutes > -1395)) {
// greater than 45 is todays time is above 45 minutes
// less than 0 means the next available time will be tomorrow and the greater than -1395 means it will be more than 45 minutes from now into tomorrow
document.write(time + ': true<br />');
} else {
document.write(time + ': false<br />');
}
}
checkTime("14:10:00");
checkTime("16:30:00");
checkTime("17:10:00");
There's a JavaScript method called getMinutes(); you can use to get only the minutes and compare.
Your code should look something like:
var received_time = "14:10:00".split(':');
var minute = '';
if(received_time.length === 3) {
minute = parseInt(received_time[1], 10);
}
$scope.given_time = minute;
var the_time = new Date();
$scope.current_time = the_time.getMinutes();
And you now can do your thing:
if ($scope.given_time - $scope.current_time < 45 minutes) {
// do something
}
Using a library like moment.js you can simply diff the two times.
var $log = $("#log");
/* Difference between just times */
$log.append("Difference between times\n");
var givenTime = moment("14:10:00", "HH:mm:ss");
var minutesPassed = moment("14:30:00", "HH:mm:ss").diff(givenTime, "minutes");
$log.append("Minutes passed: " + minutesPassed + "\n");
if (minutesPassed < 45) {
$log.append(minutesPassed + " minutes have elapsed. Event Triggered." + "\n");
}
/* Better: Difference between times that have dates attached to them and cross a day boundary. */
$log.append("\n\nDifference between dates with times\n");
givenTime = moment("2015-12-03 23:33:00");
minutesPassed = moment("2015-12-04 00:14:00").diff(givenTime, "minutes");
$log.append("Minutes passed: " + minutesPassed + "\n");
if (minutesPassed < 45) {
$log.append(minutesPassed + " minutes have elapsed. Event Triggered." + "\n");
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<script src="http://momentjs.com/downloads/moment.js"></script>
<p>Results:</p>
<hr>
<pre id="log"></pre>
<hr>
Caveat: If the given time is yesterday such as 11:30pm and the current time is 12:10am then you will get the wrong result. You'd want to use a date with the time if this type of thing is an issue for your use case.
The moment.js documentation
http://momentjs.com/docs/
Angular directive for moment documentation
https://github.com/urish/angular-moment/blob/master/README.md
I'm trying to calculate remaining time (ex: 10 years, 2 months and 10 days from today(2014/03/02) in JS using this function:
var d2 = new Date(2024, 3, 12);
var d1 = new Date();
var d0 = new Date(1970, 0, 1);
var diff = new Date(d2.getTime() - (d1.getTime() + d0.getTime() ) );
var years = diff.getFullYear();
var months = diff.getMonth();
var days = diff.getDay();
alert("remaining time = " + years + " years, " + months + " months, " + days + " days.");
But instead of get the 10 years difference, I got 1980 years difference (though the days difference I understand that are produced buy the variation of days in months and years):
Is it possible to perform this "remaining time" operation using this strategy? If so, how to get the expected result?
Here the function in a JS shell: jsfiddle.net/3ra6c/
I find here the solution I was looking for:
var date1 = new Date();
var date2 = new Date(2015, 2, 2);
var diff = new Date(date2.getTime() - date1.getTime());
var years = diff.getUTCFullYear() - 1970; // Gives difference as year
var months = diff.getUTCMonth(); // Gives month count of difference
var days = diff.getUTCDate()-1; // Gives day count of difference
alert("remaining time = " + years + " years, " + months + " months, " + days + " days.");
And it seems to work very well!
As I explained, Date is not equipped with such functions and you have to do the math yourself. You can get the milliseconds difference between two dates, but then it's down to doing the math to represent that as you wish.
An example of using moment.js, loaded with require.js, with humanized approximations.
Javascript
require.config({
paths: {
moment: 'http://momentjs.com/downloads/moment.min'
}
});
require(['moment'], function (moment) {
var x = moment(new Date(2024, 3, 12)).from(new Date());
console.log(x);
});
Output
in 10 years
On jsFiddle
Look at their docs to see how you can humanize the output, you may want a little more detail.
var diff = new Date(d2.getTime() - (d1.getTime() + d0.getTime() ) )
Why do you add d0? Try to remove it.