Calculate total duration out of specified time duration Node Js - javascript

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

Related

Find if the given time between two times

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

How to restrict time options exact hour value, should be restrict after the time passed

I need time options only 11 AM to 1 PM (1:00:00 PM only) and If system time is 1:00:01 PM also should not be allowed. if time passed after 1 PM I need to get the option availability as false.As of now till 1:59:59 PM I'm getting value as true. If my system time moved to 2 PM only getting false.
Suggest me how to get the solution for this. I should allow only 1:00:00 PM and should not be allowed any other options.
public timeOptions = ['11 AM', '12 PM', '1 PM'];
private currentTime: string[] = new Date()
.toLocaleTimeString('en-US')
.split(' ');
private formattedTime: string = `${this.currentTime[0].split(':')[0]} ${
this.currentTime[1]
}`;
private timeIndexOnOptions: number = this.timeOptions.indexOf(
this.formattedTime
);
public timeOptionAvaialable(): void {
let isOptionAvailable = this.timeIndexOnOptions != -1 ? true : false;
console.log(isOptionAvailable);
Stackblitz
here is some piece of code
const timeOptions = ['11 AM', '12 PM', '1 PM'];
const today = new Date().toLocaleTimeString('en-US').split(' ')
const timeSplit = today[0].split(':')
const index = timeOptions.indexOf(timeSplit[0] + ' ' + today[1])
// it will not wait for 1:00:00 it return false when 12:59:59 hit
if (index > -1 && index !== (timeOptions.length - 1)) {
console.log(true);
} else {
console.log(false);
}
It look like you want to decide if currentTime is in an interval. May I then suggest an alternate approach? Create a date object that represents the beginning of the interval and a date object that represents the end of the interval and check whether current time is in that interval.
const startHours = 11;
const endHours = 13;
// create a Date object for 11 AM today
const startTime = new Date();
startTime.setHours(startHours, 0, 0, 0);
// create a Date object for 1 PM today
const endTime = new Date();
endTime.setHours(endHours, 0, 0, 0);
// check if current time is in the interval
const currentTime = new Date();
const isOptionAvailable = currentTime > startTime && currentTime < endTime

Calculating time with momentjs

I'm having start_time which is in string and AM/PM format, with a time interval, now my idea is to put start _time in while loop where it is being added with time interval and be in the loop until it becomes greater than current_time, I want to pull out next current time within this interval.
Let's suppose
start_time => 10:00 AM
current_time => moment()
time_interval => 15 mins
So if any user calls this function at 10:05 AM then I want output to be 10:15 AM, or any user calls this function at 12:33 PM so my output will be 12:45 PM and so on.
To achieve this I'm trying something like this:
nextDrawTime() {
let moment = require('moment');
let now = moment();
let set_time = moment(now.get('date') + ' ' + this.start_time).get('time');
while(set_time > moment) {
set_time.add(this.time_interval, 'm');
}
return set_time.format('LT');
}
But somehow this is not working out. Help me out with it. Thanks.
You forgot to call moment.
while(set_time > moment())
<script src="https://cdnjs.cloudflare.com/ajax/libs/moment.js/2.20.1/moment.min.js"></script>
<script>
function nextDrawTime() {
let now = moment();
start_time = '10:00 AM';
let set_time = moment( now.format("YYYY-MM-DD") + ' ' + start_time).get('time');
while( set_time < moment() ) {
set_time.add(15, 'm');
}
return set_time.format('LT');
}
console.log(nextDrawTime());
</script>
now.get('date') just returns the int 11 - you need to create today as a full string then compare, also you need to check less than <
In this case it's far more effective working with the Unix Timestamp.
var interval = 15 * 60; // interval in seconds = 15 minutes
var next15 = moment(((Math.floor(moment().unix() / interval) * interval) + interval) * 1000)
console.log(next15.format("YYYY-MM-DD HH:mm:ss"))
function nextDrawTime(time, format = "LT", interval = 15) {
const next = moment(time, format);
const roundedMinute = Math.ceil(next.minute() / interval) * interval;
return next
.minutes(0)
.seconds(0)
.add(roundedMinute, "minutes")
.format(format);
}
nextDrawTime(moment().format("LT"))
console.log("10:05 AM =>", nextDrawTime("10:05 AM"));
console.log("12:33 PM =>", nextDrawTime("12:33 PM"));
console.log("11:59 AM =>", nextDrawTime("11:59 AM"));
console.log("11:59 PM =>", nextDrawTime("11:59 PM"));
<script src="https://cdnjs.cloudflare.com/ajax/libs/moment.js/2.24.0/moment.min.js"></script>
Works for different time formats and intervals
nextDrawTime(
"Tuesday, December 31th 2019, 11:59:59 pm", // Time
"dddd, MMMM Do YYYY, h:mm:ss a" // Format
60, // Interval
)
// Wednesday, January 1st 2020, 12:00:00 am

Check if date is less than 1 hour ago?

Is there a way to check if a date is less than 1 hour ago like this?
// old date
var olddate = new Date("February 9, 2012, 12:15");
// current date
var currentdate = new Date();
if (olddate >= currentdate - 1 hour) {
alert("newer than 1 hour");
else {
alert("older than 1 hour");
}
Also, different question - is there a way to add hours to a date like this?
var olddate = new Date("February 9, 2012, 12:15") + 15 HOURS; // output: February 10, 2012, 3:15
Define
var ONE_HOUR = 60 * 60 * 1000; /* ms */
then you can do
((new Date) - myDate) < ONE_HOUR
To get one hour from a date, try
new Date(myDate.getTime() + ONE_HOUR)
Using some ES6 syntax:
const lessThanOneHourAgo = (date) => {
const HOUR = 1000 * 60 * 60;
const anHourAgo = Date.now() - HOUR;
return date > anHourAgo;
}
Using the Moment library:
const lessThanOneHourAgo = (date) => {
return moment(date).isAfter(moment().subtract(1, 'hours'));
}
Shorthand syntax with Moment:
const lessThanOneHourAgo = (date) => moment(date).isAfter(moment().subtract(1, 'hours'));
the moment library can really help express this. The trick is to take the date, add time, and see if it's before or after now:
lastSeenAgoLabel: function() {
var d = this.lastLogin();
if (! moment(d).isValid()) return 'danger'; // danger if not a date.
if (moment(d).add(10, 'minutes').isBefore(/*now*/)) return 'danger'; // danger if older than 10 mins
if (moment(d).add(5, 'minutes').isBefore(/*now*/)) return 'warning'; // warning if older than 5mins
return 'success'; // Looks good!
},
Using moment will be much easier in this case, You could try this:
let hours = moment().diff(moment(yourDateString), 'hours');
It will give you integer value like 1,2,5,0etc so you can easily use condition check like:
if(hours < 1) {
Also, one more thing is you can get more accurate result of the time difference (in decimals like 1.2,1.5,0.7etc) to get this kind of result use this syntax:
let hours = moment().diff(moment(yourDateString), 'hours', true);
Let me know if you have any further query
//for adding hours to a date
Date.prototype.addHours= function(hrs){
this.setHours(this.getHours()+hrs);
return this;
}
Call function like this:
//test alert(new Date().addHours(4));
You can do it as follows:
First find difference of two dates i-e in milliseconds
Convert milliseconds into minutes
If minutes are less than 60, then it means date is within hour else not within hour.
var date = new Date("2020-07-12 11:30:10");
var now = new Date();
var diffInMS = now - date;
var msInHour = Math.floor(diffInMS/1000/60);
if (msInHour < 60) {
console.log('Within hour');
} else {
console.log('Not within the hour');
}
Plain JavaScript solution with in 12 days and 12 days ago option
const timeAgo = ( inputDate ) => {
const date = ( inputDate instanceof Date) ? inputDate : new Date(inputDate);
const FORMATTER = new Intl.RelativeTimeFormat('en');
const RANGES = {
years : 3600 * 24 * 365,
months : 3600 * 24 * 30,
weeks : 3600 * 24 * 7,
days : 3600 * 24,
hours : 3600,
minutes : 60,
seconds : 1
};
const secondsElapsed = (date.getTime() - Date.now()) / 1000;
for (let key in RANGES) {
if ( RANGES[key] < Math.abs(secondsElapsed) ) {
const delta = secondsElapsed / RANGES[key];
return FORMATTER.format(Math.round(delta), key);
}
}
}
// OUTPUTS
console.log( timeAgo('2040-12-24') )
console.log( timeAgo('6 Sept, 2012') );
console.log( timeAgo('2022-05-27T17:45:01+0000') );
let d = new Date()
console.log( "Date will change: ", timeAgo( d.setHours(24,0,0,0) ) );
// d.setDate( d.getDate() - 0 );
d.setHours(-24,0,0,0); // (H,M,S,MS) | 24 hours format
console.log("Day started: " , timeAgo( d ) );
//try this:
// to compare two date's:
<Script Language=Javascript>
function CompareDates()
{
var str1 = document.getElementById("Fromdate").value;
var str2 = document.getElementById("Todate").value;
var dt1 = parseInt(str1.substring(0,2),10);
var mon1 = parseInt(str1.substring(3,5),10);
var yr1 = parseInt(str1.substring(6,10),10);
var dt2 = parseInt(str2.substring(0,2),10);
var mon2 = parseInt(str2.substring(3,5),10);
var yr2 = parseInt(str2.substring(6,10),10);
var date1 = new Date(yr1, mon1, dt1);
var date2 = new Date(yr2, mon2, dt2);
if(date2 < date1)
{
alert("To date cannot be greater than from date");
return false;
}
else
{
alert("Submitting ...");
}
}
</Script>
Hope it will work 4 u...

Difference between dates in JavaScript

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

Categories