I'm writing a code to check if the given time is between 2 passed in times. If the end time is 23:59 (i.e. 11:59 PM ) this works, but if it is 00:00, my code fails.
Here is my sample code.
const getStatus = (startTime, currentTime, EndTime) => {
var currently = currentTime.split(":")[0] * 60 + currentTime.split(":")[1];
var starting = startTime.split(":")[0] * 60 + startTime.split(":")[1];
var ending = EndTime.split(":")[0] * 60 + EndTime.split(":")[1];
return starting < currently < ending;
}
console.log(getStatus('06:00', "12:00", "18:00"));
console.log(getStatus('06:00', "12:00", "00:00"));
In reality, 12:00 PM falls between 6:00 AM and 12:00AM, but my code returns false, since, 12:00AM is coming as 00:00 as input from my system. Is there a direct way of doing it or should I replace 00:00 with 11:60 and do it?
It's not an elegant solution but if your time end time is 00:00 (midnight) you can replace it with 24:00
const normalizeTime = (time) => {
return (time === '00:00') ?
'24:00' :
time;
}
const getStatus = (startTime, currentTime, EndTime) => {
EndTime = normalizeTime(EndTime);
var currently = currentTime.split(":")[0] * 60 + currentTime.split(":")[1];
var starting = startTime.split(":")[0] * 60 + startTime.split(":")[1];
var ending = EndTime.split(":")[0] * 60 + EndTime.split(":")[1];
return starting < currently < ending;
}
console.log(getStatus('06:00', "12:00", "18:00"));
console.log(getStatus('06:00', "12:00", "00:00"));
Try this!
// 3 statuses here
// 1 -> before
// 2 -> between
// 3 -> after
// I presume you mean all of these are date strings
const getStatus = (startTime, currentTime, endTime) => {
const dateStart = new Date(dateStr1); // Covert to a date
const dateTime = new Date(dateStr1);
const dateEnd = new Date(dateStr1);
const timestampStart = dateStart.getTime(); // Convert to a timestamp
const timestampTime = dateTime.getTime(); // Convert to a timestamp
const timestampEnd = dateEnd.getTime(); // Convert to a timestamp
if (timestampTime < timestampStart) {
return 'before'
}
if (timestampTime > timestampStart && timestampTime < timestampEnd) {
return 'between'
}
return "after"
}
For comparisons you might use the Date object:
// 6 am today
opens = new Date();
opens.setHours(6, 0, 0, 0); // setHours() accepts further arguments for minutes, seconds & milliseconds
// next midnight (00:00 tomorrow)
closes = new Date();
closes.setDate( closes.getDate() + 1 );
closes.setHours(0, 0, 0, 0);
current = new Date();
if(opens < current && current < closes) {
alert("This store is open right now.");
}
Regarding "If the end time is 23:59 (i.e. 11:59 PM ) this works, but if it is 00:00, my code fails.": If the end-time is lower than the start-time, you will have to add a day, since this time refers to somewhen tomorrow (even if it is the first second of the new day like in 00:00).
Related
I am calculating Over Time from work start time & work End time.
We need to calculate Over Time that does not include regular work Timings.
Example: Regular Work Timings is 10:00 AM to 07:00 PM
Over Time need to get from these timings:
Start Work Hour: 13-09-2021 08:00
End Work Hour: 15-09-2021 20:00
We need to calculate total hours outside of 10:00 AM to 07:00 PM from Start Work Hour: 13-09-2021 08:00 & End Work Hour: 15-09-2021 20:00
So, here Total OT would be: 32 Hour
What I have tried?
If work Start time and End time in the same day, OT calculation works fine with the below code.
Start Hour : 15-09-21 08:00
End Hour : 15-09-21 21:00
getWorkHours.forEach((workhourOT) => {
try {
// --------------------------------------
let StartWorkHour = moment(
workhourOT.starttime,
"DD-MM-YYYY hh:mm:ss"
);
let TodayOfficeStartDate =
moment(StartWorkHour).format("DD-MM-YYYY");
let StartOfficeHour = moment(
`${TodayOfficeStartDate}` + ` 10:00:00`,
"DD-MM-YYYY hh:mm:ss"
);
const diffInMillisecondsBeforeOfficeHour = Math.abs(
new Date(StartWorkHour) - new Date(StartOfficeHour)
);
let OTBeforeOffice =
diffInMillisecondsBeforeOfficeHour / 1000 / 3600;
console.log(OTBeforeOffice);
let EndtWorkHour = moment(
workhourOT.endtime,
"DD-MM-YYYY hh:mm:ss"
);
let TodayOfficeEndDate =
moment(EndtWorkHour).format("DD-MM-YYYY");
let EndOfficeHour = moment(
`${TodayOfficeEndDate}` + ` 19:00:00`,
"DD-MM-YYYY hh:mm:ss"
);
const diffInMillisecondsAfterOfficeHour = Math.abs(
new Date(EndtWorkHour) - new Date(EndOfficeHour)
);
let OTAfterOffice =
diffInMillisecondsAfterOfficeHour / 1000 / 3600;
console.log(OTAfterOffice);
let totalWORKOT = OTAfterOffice + OTBeforeOffice;
data["TotalWork_OT"] = totalWORKOT.toFixed(1);
} catch (error) {
console.log(error);
}
});
OutPut is
{
"TotalWork_OT": "4.0",
}
There is a lot of logic missing from the OP to achieve the required result. Consider an approach where a workHours object {startTime, endTime} is enhanced with an overtime property.
For each workHours object the following cases need to be addressed, where nominal start and end are normal hours (10:00 to 19:00):
start and end before nominal start
start and end after nominal start
start before, end during nominal hours
start during and end after nominal hours
start and end during nominal hours
In addition, it needs to account for times going over midnight and likely also skip weekends.
The OP assumes work starts before nominal start and ends after nominal end, so the below example does the same. So it only addresses one of the above cases, and has virtually no error handling, but it should provide an idea of what's required to do the job.
It takes a work hours object and returns a new object augmented with an overtime property and the overtime hours in the range. It only deals with whole hours and where work start and end are before and after nominal start and end respectively.
Each helper function can be extended with required additional functionality to handle the other cases and deal with partial hours (maybe round to 15 minute increments).
// Parse timestamp in DD-MM-YYYY HH:mm format
// Values after day are optional and default to zero (0)
function parseWorkHour(wh) {
let [D, M, Y, H, m, s] = wh.split(/\W/);
return new Date(Y, M-1, D, H||0, m||0, s||0);
}
// Format date as DD-MM-YYYY HH:mm
function formatWorkHour(date) {
let z = n => ('0'+n).slice(-2);
return `${z(date.getDate())}-${z(date.getMonth()+1)}-` +
`${date.getFullYear()} ${z(date.getHours())}:` +
`${z(date.getMinutes())}`;
}
// Return true if date1 and date2 are same day
function areSameDay(d1, d2) {
return !isNaN(d1) && !isNaN(d2) &&
d1.getFullYear() == d2.getFullYear() &&
d1.getMonth() == d2.getMonth() &&
d1.getDate() == d2.getDate();
}
// Given workhours object {startTime, endTime} return
// array of daily workHours objects for input object range
function getDailyWorkHours(who) {
let start = parseWorkHour(who.startTime);
let end = parseWorkHour(who.endTime);
let dailyWorkHours = [];
// No validation (e.g. start > end) so guard against infinite loop
let i = 10;
while (!areSameDay(start, end) && --i) {
let temp = new Date(start);
temp.setHours(23,59,59,999);
dailyWorkHours.push({
startTime: formatWorkHour(start),
endTime: formatWorkHour(temp)
});
temp.setHours(24,0,0,0);
start = temp;
}
dailyWorkHours.push({
startTime: formatWorkHour(start),
endTime: formatWorkHour(end)
});
return dailyWorkHours;
}
// Get overtime from workHours object {startTime, endTime}
// startTime and endTime must be same day.
// Overtime is before 10:00 and after 19:00
function getOvertime(who) {
let workStart = parseWorkHour(who.startTime);
let workEnd = parseWorkHour(who.endTime);
let officeStart = new Date(+workStart);
officeStart.setHours(10,0,0,0);
let officeEnd = new Date(+workEnd);
officeEnd.setHours(19,0,0,0);
let ot = (officeStart - workStart) / 3.6e6 +
(workEnd - officeEnd) / 3.6e6;
// Round to nearest hour
return Math.round(ot);
}
// Given work hours array [{startTime,endTime}], calculate how
// much overtime has been worked,
// i.e. time before officeStart (10:00) and officeEnd (19:00)
function tallyOvertime(workHoursArray) {
let result = [];
workHoursArray.forEach( who => {
let dailyWorkHours = getDailyWorkHours(who);
let overTime = dailyWorkHours.reduce((ot, who) => {
ot += getOvertime(who);
return ot;
}, 0);
result.push({
startTime:who.startTime,
endTime:who.endTime,
overTime:overTime
});
});
return result;
}
let data = [
// Same day - 5 hrs
{startTime:'20-09-2021 06:00', endTime:'20-09-2021 20:00'},
// Over midnight - 20
{startTime:'20-09-2021 06:00', endTime:'21-09-2021 20:00'},
// OP example - 33
{startTime:'13-09-2021 08:00', endTime:'15-09-2021 20:00'}
];
console.log(tallyOvertime(data));
In the OP there is:
We need to calculate total hours outside of 10:00 AM to 07:00 PM from
Start Work Hour: 13-09-2021 08:00 & End Work Hour: 15-09-2021 20:00
So, here Total OT would be: 32 Hour
Which is incorrect. The breakdown is as follows:
13-09-2021 08:00 to 10:00 is 2 hours
13-09-2021 19:00 to 24:00 is 5 hours
14-09-2021 00:00 to 10:00 is 10 hours
14-09-2021 19:00 to 24:00 is 5 hours
15-09-2021 00:00 to 10:00 is 10 hours
15-09-2021 19:00 to 20:00 is 1 hour
which totals 33 hours, not 32.
I have done something like this.
work Start date: 18-09-21 08:00
work End Date: 20-09-21 20:00
get OT for the work start date to midnight the same day. start: 18-09-21 08:00 ---- end: 18-08-21 24:00
get OT starting from the start day of the work end date to work end time. start: 20-09-21 00:00 --- end: 20-09-21 20:00
on every full day of working we get 15 Hour Overtime excluding regular working hours. so we can multiply the total full day OT with 15. and sum all three results.
OT Function
async function calculateWorkOverTime(TimingArr) {
for (OTI = 0; OTI < TimingArr.length; OTI++) {
try {
let StartWorkHour = moment(
TimingArr[OTI].starttime,
"DD-MM-YYYY hh:mm:ss"
);
let TodayOfficeStartDate = moment(StartWorkHour).format("DD-MM-YYYY");
let StartOfficeHour = moment(
`${TodayOfficeStartDate}` + ` 10:00:00`,
"DD-MM-YYYY hh:mm:ss"
);
const diffInMillisecondsBeforeOfficeHour = Math.abs(
new Date(StartWorkHour) - new Date(StartOfficeHour)
);
let OTBeforeOffice = diffInMillisecondsBeforeOfficeHour / 1000 / 3600;
// console.log(OTBeforeOffice);
let EndtWorkHour = moment(TimingArr[OTI].endtime, "DD-MM-YYYY hh:mm:ss");
let TodayOfficeEndDate = moment(EndtWorkHour).format("DD-MM-YYYY");
let EndOfficeHour = moment(
`${TodayOfficeEndDate}` + ` 19:00:00`,
"DD-MM-YYYY hh:mm:ss"
);
const diffInMillisecondsAfterOfficeHour = Math.abs(
new Date(EndtWorkHour) - new Date(EndOfficeHour)
);
let OTAfterOffice = diffInMillisecondsAfterOfficeHour / 1000 / 3600;
let totalWORKOT = OTAfterOffice + OTBeforeOffice;
return totalWORKOT;
} catch (error) {
return error;
}
}
}
var OT = "";
for (OTArr = 0; OTArr < getWorkHours.length; OTArr++) {
let StartTimingWork = moment(
getWorkHours[OTArr].starttime,
"DD-MM-YYYY hh:mm:ss"
);
let TodayStartTiming = moment(StartTimingWork).format("DD-MM-YYYY");
let EndTimingWork = moment(
getWorkHours[OTArr].endtime,
"DD-MM-YYYY hh:mm:ss"
);
console.log(getWorkHours);
let TodayEndTiming = moment(EndTimingWork).format("DD-MM-YYYY");
if (TodayEndTiming === TodayStartTiming) {
let getOTFROMTIMING = await otcontroller.calculateWorkOverTime(
getWorkHours
);
OT = getOTFROMTIMING;
data["WOT"] = OT;
} else {
// var workstartDate = moment(TodayEndTiming, "DD-MM-YYYY");
var workstartDate = StartTimingWork;
let currentDayMidNight = moment(workstartDate).endOf("day");
let ArrOfTiming = [
{
starttime: workstartDate,
endtime: currentDayMidNight,
},
];
let getOTFROMTIMING = await otcontroller.calculateWorkOverTime(
ArrOfTiming
);
console.log(getOTFROMTIMING);
var workendDate = EndTimingWork;
let startOfWorkEndDate = moment(workendDate).startOf("day");
// console.log(workendDate);
// console.log(startOfWorkEndDate);
let ArrOfTimingEnd = [
{
starttime: startOfWorkEndDate,
endtime: workendDate,
},
];
let getOTFROMTIMINGlastDay =
await otcontroller.calculateWorkOverTime(ArrOfTimingEnd);
console.log(getOTFROMTIMINGlastDay);
// var workendDate = EndTimingWork;
// console.log(workstartDate);
console.log("workendDate");
console.log(workendDate);
console.log(workstartDate);
console.log("workstartDate");
var result = workendDate.diff(workstartDate, "days");
console.log(result);
console.log("result");
let wholeDaysOT = (result - 1) * 15;
console.log(
wholeDaysOT + getOTFROMTIMINGlastDay + getOTFROMTIMING
);
let TotalWorkOverTime =
wholeDaysOT + getOTFROMTIMINGlastDay + getOTFROMTIMING;
data["WOT"] = TotalWorkOverTime.toFixed(1);
}
}
I'm new to angular, I would like to know if there is there a way to calculate the difference between a specific date and the current date, and then start counting the time from that difference?
Example: 29/01/2020 21:00:00 - 29/01/2020 21:30:00 gives a difference of 30 minutes ... the count should start from 30 minutes, that is 00:30:00
Demo
Code
startTime(){
this.interval = setInterval(() => {
if (this.time === 0) {
this.time++;
} else {
this.time++;
}
this.display = this.time;
return this.display;
}, 1000);
}
You could compute a difference between the two dates in milliseconds using Date.getTime(). If you create a new Date object from this difference, it will contain a representation of this interval. So you only need to increment the seconds and display the formatted time:
// difference between two dates in milliseconds
const diff = new Date('May 1,2019 11:20:00').getTime() - new Date('May 1,2019 11:00:00').getTime();
// new date object created from this difference
const start = new Date(diff);
const el = document.getElementById('time');
setInterval(() => {
// updating the time every second
start.setSeconds(start.getSeconds() + 1);
el.innerHTML = `${format(start.getUTCHours())}: ${format(start.getUTCMinutes())}: ${format(start.getUTCSeconds())}`;
}, 1000)
function format(n) {
return n < 10 ? '0' + n : '' + n;
}
<div id=time></div>
I would recommend you try moment (https://momentjs.com/docs/#/displaying/difference/).
With that you can easilly get the difference in milliseconds:
const currentTime = moment();
const someTime = moment([2010, 1, 14, 15, 25, 50, 125]) // [year, month, day, hour, minute, second, millisecond]
const millisecondDifference = currentTime.diff(someTime);
and then use that difference to set interval (or use moment/Date to transform it to something)
You don't need to use a counter, and a counter will probably not give you the result you want as setInterval/setTimeout will not fire at exactly 1000ms.
You can subtract the start date from the current date every time setInterval calls your function. then format the result:
var start = new Date('2020-01-29 21:00:00');
startTime(){
this.interval = setInterval(() => {
this.display = new Date() - start;
return this.display;
}, 1000);
}
After subtracting the current date from the given date, in milliseconds, convert it to seconds, minutes , and hours and use setInterval to update the counter.
const date = Date.parse('30 Jan 2020 01:04:56 GMT+0300'); //your given date
const elem = document.getElementById('counter')
function count() {
let countFrom = (Date.now() - date); //get the difference with the current date
//convert to seconds, minutes and hours
seconds = parseInt((countFrom/1000) % 60)
minutes = parseInt((countFrom/(1000*60)) % 60)
hours = parseInt((countFrom/(1000*60*60)) % 24);
//append `0` infront if a single digit
hours = (hours < 10) ? "0" + hours : hours;
minutes = (minutes < 10) ? "0" + minutes : minutes;
seconds = (seconds < 10) ? "0" + seconds : seconds;
let time = `${hours}:${minutes}:${seconds}`;
elem.textContent = time;
}
setInterval(count, 1000);
<div id='counter'>00:00:00</div>
I think this solves your problem
let now = Date.now();
let future = new Date('January 29, 2020 23:59:59').getTime();
let diffInSecond = Math.floor((future - now) / 1000);
var i = diffInSecond;
var interval = setInterval(function(){
if (i == 0) clearInterval(interval);
console.log(i);
i--;
},
1000);
Everything is in second you can format the result to show something like 00:31:29
I'm having to hit an API I have no access to fixing and I need to start a timer showing how long someone has been in a queue for. The date I get back is in this format 1556214336.316. The problem is the year always shows up as 1970, but the time is the correct start time. I need to calculate the difference between the time now, and the time the conversation was created at. I have tried this with little success and was wondering if there is an elegant way to only get the difference in time and not the total amount of seconds.
convertDateToTimerFormat = (time) => {
const now = new Date();
const diff = Math.round((now - parseInt(time.toString().replace('.', ''))) / 1000);
const hours = new Date(diff).getHours();
const minutes = new Date(diff).getMinutes();
const seconds = new Date(diff).getSeconds();
return `${hours}:${minutes}:${seconds}`;
}
The weird parseInt(time.toString().replace('.', ''))) seems to fix the 1970 issue, but I still can't get the data to be manipulated how I need.
I tried the momentjs library, but their diff method only appears to allow for days and hours.
Any help/guidance, would be much appreciated.
Edit with working code:
convertDateToTimerFormat = (time) => {
const now = new Date();
// eslint-disable-next-line radix
const diff = new Date(Number(now - parseInt(time.toString().replace(/\./g, ''))));
const hours = diff.getHours();
const minutes = diff.getMinutes();
const seconds = diff.getSeconds();
return `${hours}:${minutes}:${seconds}`;
}
Unix time values are the number of seconds since the Epoch and won't have a decimal like your 1556214336.316
If I take 1556214336 (without the .316) and put it in a converter I get the output 04/25/2019 # 5:45pm (UTC) which is not 1970 — it seems an accurate time (I haven't independently verified)
It seems, then, your 1556214336.316 is the seconds.milliseconds since the epoch.
Javascript uses the same epoch, but is the number of milliseconds since the epoch, not seconds, so if I'm correct about the time you're getting you should be able to just remove the decimal place and use the resulting number string. Indeed
var d = new Date(1556214336316);
console.log('Date is: ' + d.toUTCString());
produces
Date is: Thu, 25 Apr 2019 17:45:36 GMT
which exactly matches the converter's time of "5:45pm"
var d = new Date(1556214336316);
console.log('Date is: ' + d.toUTCString());
Assuming your value 1556214336.316 is a String coming back from a web API, you can remove the decimal and your conversion can be done like this (note you don't have to keep creating new Date objects):
convertDateToTimerFormat = (time) => {
const d = new Date( Number(time.replace(/\./g, '')) );
return `${d.getHours()}:${d.getMinutes()}:${d.getSeconds()}`;
};
console.log( 'time: ' + convertDateToTimerFormat('1556214336.316') );
Depending on your use, you may want to use getUTCHours() etc. instead.
I don't know about elegant, but this calculates and displays the expired time in h:mm:ss format:
console.log(convertDateToTimerFormat(1556215236.316));
function convertDateToTimerFormat(time){
// Converts `time` to milliseconds to make a JS Date object, then back to seconds
const expiredSeconds = Math.floor(new Date()/1000) - Math.floor(new Date(time * 1000)/1000);
// Calculates component values
const hours = Math.floor(expiredSeconds / 3600), //3600 seconds in an hour
minutes = Math.floor(expiredSeconds % 3600 / 60),
seconds = expiredSeconds % 3600 % 60;
// Adds initial zeroes if needed
if (minutes < 10) { minutes = "0" + minutes; }
if (seconds < 10) { seconds = "0" + seconds; }
// Returns a formatted string
return `${hours}:${minutes}:${seconds}`;
}
I am working on a project that requires a time in the future to be set using the Date object.
For example:
futureTime = new Date();
futureTime.setHours(futureTime.getHours()+2);
My questions is; once the future date is set, how can I round to the closest full hour and then set the futureTime var with it?
For example:
Given 8:55 => var futureTime = 9:00
Given 16:23 => var futureTime = 16:00
Any help would be appreciated!
Round the minutes and then clear the minutes:
var date = new Date(2011,1,1,4,55); // 4:55
roundMinutes(date); // 5:00
function roundMinutes(date) {
date.setHours(date.getHours() + Math.round(date.getMinutes()/60));
date.setMinutes(0, 0, 0); // Resets also seconds and milliseconds
return date;
}
The other answers ignore seconds and milliseconds components of the date.
The accepted answer has been updated to handle milliseconds, but it still does not handle daylight savings time properly.
I would do something like this:
function roundToHour(date) {
p = 60 * 60 * 1000; // milliseconds in an hour
return new Date(Math.round(date.getTime() / p ) * p);
}
var date = new Date(2011,1,1,4,55); // 4:55
roundToHour(date); // 5:00
date = new Date(2011,1,1,4,25); // 4:25
roundToHour(date); // 4:00
A slightly simpler way :
var d = new Date();
d.setMinutes (d.getMinutes() + 30);
d.setMinutes (0);
Another solution, which is no where near as graceful as IAbstractDownvoteFactory's
var d = new Date();
if(d.getMinutes() >= 30) {
d.setHours(d.getHours() + 1);
}
d.setMinutes(0);
Or you could mix the two for optimal size.
http://jsfiddle.net/HkEZ7/
function roundMinutes(date) {
return date.getMinutes() >= 30 ? date.getHours() + 1 : date.getHours();
}
As a matter of fact Javascript does this default which gives wrong time.
let dateutc="2022-02-17T07:20:00.000Z";
let bd = new Date(dateutc);
console.log(bd.getHours()); // gives me 8!!!!!
it is even wrong for my local time because I am GMT+2 so it should say 9.
moment.js also does it wrong so you need to be VERY carefull
Pass any cycle you want in milliseconds to get next cycle example 1 hours
function calculateNextCycle(interval) {
const timeStampCurrentOrOldDate = Date.now();
const timeStampStartOfDay = new Date().setHours(0, 0, 0, 0);
const timeDiff = timeStampCurrentOrOldDate - timeStampStartOfDay;
const mod = Math.ceil(timeDiff / interval);
return new Date(timeStampStartOfDay + (mod * interval));
}
console.log(calculateNextCycle(1 * 60 * 60 * 1000)); // 1 hours in milliseconds
How to find the difference between two dates?
By using the Date object and its milliseconds value, differences can be calculated:
var a = new Date(); // Current date now.
var b = new Date(2010, 0, 1, 0, 0, 0, 0); // Start of 2010.
var d = (b-a); // Difference in milliseconds.
You can get the number of seconds (as a integer/whole number) by dividing the milliseconds by 1000 to convert it to seconds then converting the result to an integer (this removes the fractional part representing the milliseconds):
var seconds = parseInt((b-a)/1000);
You could then get whole minutes by dividing seconds by 60 and converting it to an integer, then hours by dividing minutes by 60 and converting it to an integer, then longer time units in the same way. From this, a function to get the maximum whole amount of a time unit in the value of a lower unit and the remainder lower unit can be created:
function get_whole_values(base_value, time_fractions) {
time_data = [base_value];
for (i = 0; i < time_fractions.length; i++) {
time_data.push(parseInt(time_data[i]/time_fractions[i]));
time_data[i] = time_data[i] % time_fractions[i];
}; return time_data;
};
// Input parameters below: base value of 72000 milliseconds, time fractions are
// 1000 (amount of milliseconds in a second) and 60 (amount of seconds in a minute).
console.log(get_whole_values(72000, [1000, 60]));
// -> [0,12,1] # 0 whole milliseconds, 12 whole seconds, 1 whole minute.
If you're wondering what the input parameters provided above for the second Date object are, see their names below:
new Date(<year>, <month>, <day>, <hours>, <minutes>, <seconds>, <milliseconds>);
As noted in the comments of this solution, you don't necessarily need to provide all these values unless they're necessary for the date you wish to represent.
I have found this and it works fine for me:
Calculating the Difference between Two Known Dates
Unfortunately, calculating a date interval such as days, weeks, or months between two known dates is not as easy because you can't just add Date objects together. In order to use a Date object in any sort of calculation, we must first retrieve the Date's internal millisecond value, which is stored as a large integer. The function to do that is Date.getTime(). Once both Dates have been converted, subtracting the later one from the earlier one returns the difference in milliseconds. The desired interval can then be determined by dividing that number by the corresponding number of milliseconds. For instance, to obtain the number of days for a given number of milliseconds, we would divide by 86,400,000, the number of milliseconds in a day (1000 x 60 seconds x 60 minutes x 24 hours):
Date.daysBetween = function( date1, date2 ) {
//Get 1 day in milliseconds
var one_day=1000*60*60*24;
// Convert both dates to milliseconds
var date1_ms = date1.getTime();
var date2_ms = date2.getTime();
// Calculate the difference in milliseconds
var difference_ms = date2_ms - date1_ms;
// Convert back to days and return
return Math.round(difference_ms/one_day);
}
//Set the two dates
var y2k = new Date(2000, 0, 1);
var Jan1st2010 = new Date(y2k.getFullYear() + 10, y2k.getMonth(), y2k.getDate());
var today= new Date();
//displays 726
console.log( 'Days since '
+ Jan1st2010.toLocaleDateString() + ': '
+ Date.daysBetween(Jan1st2010, today));
The rounding is optional, depending on whether you want partial days or not.
Reference
If you are looking for a difference expressed as a combination of years, months, and days, I would suggest this function:
function interval(date1, date2) {
if (date1 > date2) { // swap
var result = interval(date2, date1);
result.years = -result.years;
result.months = -result.months;
result.days = -result.days;
result.hours = -result.hours;
return result;
}
result = {
years: date2.getYear() - date1.getYear(),
months: date2.getMonth() - date1.getMonth(),
days: date2.getDate() - date1.getDate(),
hours: date2.getHours() - date1.getHours()
};
if (result.hours < 0) {
result.days--;
result.hours += 24;
}
if (result.days < 0) {
result.months--;
// days = days left in date1's month,
// plus days that have passed in date2's month
var copy1 = new Date(date1.getTime());
copy1.setDate(32);
result.days = 32-date1.getDate()-copy1.getDate()+date2.getDate();
}
if (result.months < 0) {
result.years--;
result.months+=12;
}
return result;
}
// Be aware that the month argument is zero-based (January = 0)
var date1 = new Date(2015, 4-1, 6);
var date2 = new Date(2015, 5-1, 9);
document.write(JSON.stringify(interval(date1, date2)));
This solution will treat leap years (29 February) and month length differences in a way we would naturally do (I think).
So for example, the interval between 28 February 2015 and 28 March 2015 will be considered exactly one month, not 28 days. If both those days are in 2016, the difference will still be exactly one month, not 29 days.
Dates with exactly the same month and day, but different year, will always have a difference of an exact number of years. So the difference between 2015-03-01 and 2016-03-01 will be exactly 1 year, not 1 year and 1 day (because of counting 365 days as 1 year).
// This is for first date
first = new Date(2010, 03, 08, 15, 30, 10); // Get the first date epoch object
document.write((first.getTime())/1000); // get the actual epoch values
second = new Date(2012, 03, 08, 15, 30, 10); // Get the second date epoch object
document.write((second.getTime())/1000); // get the actual epoch values
diff= second - first ;
one_day_epoch = 24*60*60 ; // calculating one epoch
if ( diff/ one_day_epoch > 365 ) // check if it is exceeding regular calendar year
{
alert( 'date is exceeding one year');
}
This answer, based on another one (link at end), is about the difference between two dates.
You can see how it works because it's simple, also it includes splitting the difference into
units of time (a function that I made) and converting to UTC to stop time zone problems.
function date_units_diff(a, b, unit_amounts) {
var split_to_whole_units = function (milliseconds, unit_amounts) {
// unit_amounts = list/array of amounts of milliseconds in a
// second, seconds in a minute, etc., for example "[1000, 60]".
time_data = [milliseconds];
for (i = 0; i < unit_amounts.length; i++) {
time_data.push(parseInt(time_data[i] / unit_amounts[i]));
time_data[i] = time_data[i] % unit_amounts[i];
}; return time_data.reverse();
}; if (unit_amounts == undefined) {
unit_amounts = [1000, 60, 60, 24];
};
var utc_a = new Date(a.toUTCString());
var utc_b = new Date(b.toUTCString());
var diff = (utc_b - utc_a);
return split_to_whole_units(diff, unit_amounts);
}
// Example of use:
var d = date_units_diff(new Date(2010, 0, 1, 0, 0, 0, 0), new Date()).slice(0,-2);
document.write("In difference: 0 days, 1 hours, 2 minutes.".replace(
/0|1|2/g, function (x) {return String( d[Number(x)] );} ));
How my code above works
A date/time difference, as milliseconds, can be calculated using the Date object:
var a = new Date(); // Current date now.
var b = new Date(2010, 0, 1, 0, 0, 0, 0); // Start of 2010.
var utc_a = new Date(a.toUTCString());
var utc_b = new Date(b.toUTCString());
var diff = (utc_b - utc_a); // The difference as milliseconds.
Then to work out the number of seconds in that difference, divide it by 1000 to convert
milliseconds to seconds, then change the result to an integer (whole number) to remove
the milliseconds (fraction part of that decimal): var seconds = parseInt(diff/1000).
Also, I could get longer units of time using the same process, for example:
- (whole) minutes, dividing seconds by 60 and changing the result to an integer,
- hours, dividing minutes by 60 and changing the result to an integer.
I created a function for doing that process of splitting the difference into
whole units of time, named split_to_whole_units, with this demo:
console.log(split_to_whole_units(72000, [1000, 60]));
// -> [1,12,0] # 1 (whole) minute, 12 seconds, 0 milliseconds.
This answer is based on this other one.
You can also use it
export function diffDateAndToString(small: Date, big: Date) {
// To calculate the time difference of two dates
const Difference_In_Time = big.getTime() - small.getTime()
// To calculate the no. of days between two dates
const Days = Difference_In_Time / (1000 * 3600 * 24)
const Mins = Difference_In_Time / (60 * 1000)
const Hours = Mins / 60
const diffDate = new Date(Difference_In_Time)
console.log({ date: small, now: big, diffDate, Difference_In_Days: Days, Difference_In_Mins: Mins, Difference_In_Hours: Hours })
var result = ''
if (Mins < 60) {
result = Mins + 'm'
} else if (Hours < 24) result = diffDate.getMinutes() + 'h'
else result = Days + 'd'
return { result, Days, Mins, Hours }
}
results in { result: '30d', Days: 30, Mins: 43200, Hours: 720 }
Date.prototype.addDays = function(days) {
var dat = new Date(this.valueOf())
dat.setDate(dat.getDate() + days);
return dat;
}
function getDates(startDate, stopDate) {
var dateArray = new Array();
var currentDate = startDate;
while (currentDate <= stopDate) {
dateArray.push(currentDate);
currentDate = currentDate.addDays(1);
}
return dateArray;
}
var dateArray = getDates(new Date(), (new Date().addDays(7)));
for (i = 0; i < dateArray.length; i ++ ) {
// alert (dateArray[i]);
date=('0'+dateArray[i].getDate()).slice(-2);
month=('0' +(dateArray[i].getMonth()+1)).slice(-2);
year=dateArray[i].getFullYear();
alert(date+"-"+month+"-"+year );
}
var DateDiff = function(type, start, end) {
let // or var
years = end.getFullYear() - start.getFullYear(),
monthsStart = start.getMonth(),
monthsEnd = end.getMonth()
;
var returns = -1;
switch(type){
case 'm': case 'mm': case 'month': case 'months':
returns = ( ( ( years * 12 ) - ( 12 - monthsEnd ) ) + ( 12 - monthsStart ) );
break;
case 'y': case 'yy': case 'year': case 'years':
returns = years;
break;
case 'd': case 'dd': case 'day': case 'days':
returns = ( ( end - start ) / ( 1000 * 60 * 60 * 24 ) );
break;
}
return returns;
}
Usage
var qtMonths = DateDiff('mm', new Date('2015-05-05'), new Date());
var qtYears = DateDiff('yy', new Date('2015-05-05'), new Date());
var qtDays = DateDiff('dd', new Date('2015-05-05'), new Date());
OR
var qtMonths = DateDiff('m', new Date('2015-05-05'), new Date()); // m || y || d
var qtMonths = DateDiff('month', new Date('2015-05-05'), new Date()); // month || year || day
var qtMonths = DateDiff('months', new Date('2015-05-05'), new Date()); // months || years || days
...
var DateDiff = function (type, start, end) {
let // or var
years = end.getFullYear() - start.getFullYear(),
monthsStart = start.getMonth(),
monthsEnd = end.getMonth()
;
if(['m', 'mm', 'month', 'months'].includes(type)/*ES6*/)
return ( ( ( years * 12 ) - ( 12 - monthsEnd ) ) + ( 12 - monthsStart ) );
else if(['y', 'yy', 'year', 'years'].includes(type))
return years;
else if (['d', 'dd', 'day', 'days'].indexOf(type) !== -1/*EARLIER JAVASCRIPT VERSIONS*/)
return ( ( end - start ) / ( 1000 * 60 * 60 * 24 ) );
else
return -1;
}