I was trying to round the moment.js time object to next nearest 30 minute interval. But looks my logic us wrong.
Ex:
10:13am -> 10:30am
11:45am -> 12:00pm
Here is my current code
start = moment();
minuteReminder = start.minute() % 30;
start.add(minuteReminder, 'minutes');
start.format("D YYYY, h:mm:ss a");
Edit 2021 : easiest solution
const start = moment('2018-12-08 09:42');
const remainder = 30 - (start.minute() % 30);
const dateTime = moment(start).add(remainder, "minutes").format("DD.MM.YYYY, h:mm:ss a");
console.log(dateTime);
<script src="https://cdnjs.cloudflare.com/ajax/libs/moment.js/2.20.1/moment.min.js"></script>
Million ways to do this. You don't need moment.js really. Anyway, here is one.
Based on #Volune and #Cabloo answers and comments, an updated version can look like:
function round(date, duration, method) {
return moment(Math[method]((+date) / (+duration)) * (+duration));
}
Which then can be used like:
var date = moment();
var roundedDate = round(date, moment.duration(15, "minutes"), "ceil");
A generic solution:
var ROUNDING = 30 * 60 * 1000; /*ms*/
start = moment();
start = moment(Math.ceil((+start) / ROUNDING) * ROUNDING);
start.format("D YYYY, h:mm:ss a");
You can change ROUNDING from 30 minutes to whatever you want, and change Math.ceil by Math.round or Math.floor if you want another way to round the value.
You could do it with two ifs:
// Current date
let now = moment();
// Getting hour and minute
let hour = now.hour();
let minute = now.minute();
// Rounding minute on 30 mins interval
if(minute <= 30) now.set({minute: 30});
if(minute > 30) now.set({hour: hour + 1, minute: 0});
You can do it by a simple if-else clause:
if(moment().minute()> 30){
var myTime = moment().minute(30).second(0);
} else {
var myTime = moment().minute(0).second(0);
}
For my case, I instead wanted something like
04-28-2021 20:00 => 04-28-2021 20:00
04-28-2021 20:30 => 04-28-2021 20:30
04-28-2021 20:11 => 04-28-2021 20:00
04-28-2021 20:35 => 04-28-2021 20:30
so the function below did the trick
function toNearest30Minutes(date) {
const start = moment(date)
let remainder: number
const elapse = start.minute() % 30
if (elapse === 0) {
return moment(date).format()
} else {
remainder = 30 - elapse
return moment(start).add(remainder, "minutes").format()
}
}
The function above is just an adaptation of #jtromans answer higher above
One-line solution
moment().add( moment().minute() > 30 && 1 , 'hours').minutes( moment().minute() <= 30 ? 30 : 0).format("hh:mm a")
Working exemple :
var min = moment().minute()
var dateTime = moment().add(min > 30 && 1 , 'hours').minutes(min <= 30 ? 30 : 0).format("hh:mm a")
console.log(dateTime);
<script src="https://cdnjs.cloudflare.com/ajax/libs/moment.js/2.20.1/moment.min.js"></script>
even though the question has been answered, I'd like to share my solution too.
var moment = require('moment');
const roundToNearestXXMinutes = (start, roundTo) => {
let remainder = roundTo - (start.minute()+ start.second()/60) % roundTo;
remainder = (remainder > roundTo/2) ? remainder = -roundTo + remainder : remainder;
const changedDate = moment(start).add(remainder, "minutes" ).seconds(0).format("DD.MM.YYYY HH:mm:ss");
}
roundToNearestXXMinutes(moment(), 15);
EDIT: Thanks to Ishmael Sibisi for pointing to a flaw in my code! :)
the code below rounds up the current time to the nearest 30 minutes and also flawlessly takes care of any trailing seconds
var moment = require('moment')
var main = Date.now() //2020-03-13T23:17:34+01:00
var mainFormat = moment(main)
var secs = mainFormat.second()
var justMinutes = mainFormat.subtract(secs, 'seconds')
var remainder = 30 - (justMinutes.minute() % 30);
var dateTime = moment(justMinutes).add(remainder, 'minutes')
var final = dateTime.format()
console.log(final)
//2020-03-13T23:20:00+01:00
Related
There is a question that is tricky. Make a function that takes a string argument like 2:00 p.m. or 5:50 a.m.
You must not use momentjs or any other third-party library.
We have three static hours to determine the difference between them and this argument.
7:00 a.m. for breakfast.
12:00 p.m. for lunch.
7:00 p.m. for dinner.
The function should return an array with the first and second elements representing hours and minutes, like below:
eat("2:00 a.m.") // [5, 0];
eat("5:50 p.m.") // [1, 10];
You can start by creating a minutesSinceMidnight() function to get the time since midnight in minutes for a given input string.
We'll then create the timeToEat() function, which will start by finding the next meal time.
Once this is found, we'll get the time to the next meal in minutes, and convert to hours and minutes using
a minutesToHoursAndMinutes() function.
function minutesSinceMidnight(timeStr) {
let rg = /(\d{1,2})\:(\d{1,2})\s+([ap])\.?m/
let [,hour, minute, am] = rg.exec(timeStr);
hour = Number(hour);
if (am === 'a' && hour === 12) hour -= 12;
if (am === 'p' && hour < 12) hour += 12;
return hour * 60 + Number(minute);
}
function minutesToHoursAndMinutes(totalMinutes) {
let hours = Math.floor(totalMinutes / 60);
let minutes = totalMinutes % 60;
return [ hours, minutes]
}
function timeToEat(timeStr) {
let currentTime = minutesSinceMidnight(timeStr);
let mealTimes = ['7:00 a.m', '12:00 p.m.', '7:00 p.m.'].map(minutesSinceMidnight);
let nextMealTime = mealTimes.find(mealTime => mealTime >= currentTime);
// No meal found...
if (nextMealTime === undefined) {
return nextMealTime;
}
let timeToNextMealMinutes = nextMealTime - currentTime;
return minutesToHoursAndMinutes(timeToNextMealMinutes);
}
console.log(timeToEat("2:00 a.m."));
console.log(timeToEat("5:50 p.m."));
console.log(timeToEat("6:30 p.m."));
.as-console-wrapper { max-height: 100% !important; top: 0; }
You need some basic functions to convert the time to some common unit that can be compared with some other time. In this case, minutes will do but seconds or milliseconds could also be used.
You also may need to allow for the case where the time is after the last meal, so the time will be the time to the first meal tomorrow.
The following is a simple implementation with some tests. Ideally the data would not be embedded in the timeToNextMeal function so that it's more easily maintained.
// Convert timestamp in h:mm ap format to minutes,
// E.g. 2:30 p.m. is 870 minutes
function timeToMins(time) {
// Get parts of time
let [h, m, ap] = time.split(/\W/);
// Set hours based on value and am/pm
h = h%12 + (/^a/i.test(ap)? 0 : 12);
// Return minutes
return h*60 + m*1;
}
// Convert minutes to array [hours, minutes]
function minsToHM(mins) {
return [mins/60 | 0, mins % 60];
}
function timeToNextMeal(date = new Date()) {
let data = {
'lunch' : '12:00 p.m.',
'breakfast': '7:00 a.m.',
'dinner' : '7:00 p.m.'
};
let minsToMeal = 0;
// Get meal names, ensure sorted by time
let meals = Object.keys(data).sort((a,b) =>
timeToMins(data[a]) - timeToMins(data[b])
);
// Convert time to minutes
let mins = date.getHours() * 60 + date.getMinutes();
// Get next mealtime
let nextMeal = meals.find(meal => timeToMins(data[meal]) > mins);
// If undefined, next meal is first meal tomorrow
if (!nextMeal) {
minsToMeal += 1440 - mins;
mins = 0;
nextMeal = meals[0];
}
// Get minutes to next meal
minsToMeal += timeToMins(data[nextMeal]) - mins;
// Convert minutes to array [H,m]
return minsToHM(minsToMeal);
}
// Examples
[new Date(2022,0,6, 4), // 4 am
new Date(2022,0,6, 5,58), // 5:58 am
new Date(2022,0,6, 9,30), // 9:30 am
new Date(2022,0,6,17,30), // 5:30 pm
new Date(2022,0,6,20, 0), // 8:00 pm
].forEach(d => console.log(
`${d.toLocaleTimeString('en-NZ')} ${timeToNextMeal(d)}`
));
I'm not including the 12:00 PM - 01:00 PM Time
For example:
8:00 AM - 5:00 PM = 8.00
If I input
8:00 AM - 10:00 PM = 2.00
But the correct output is supposed to be (13.00)
Here is my code:
_formatTime = function(amPmString) {
var d = new Date("03/04/2019 " + amPmString);
return d.getHours() + ':' + d.getMinutes();
}
_getTimeDifference = function(startTime, endTime) {
var start = moment.utc(startTime, "HH:mm");
var end = moment.utc(endTime, "HH:mm");
var t = (end.isBefore(start)) ? end.add(1, 'day') : '';
var diff = (end.diff(start)) / 3600000;
return (t) ? diff - 13 : diff;
};
The correct result that I want is that I have to total the hours of the time-in and time-out and disregard only the lunch break which is 1 hour (12pm-1pm) in the computation of total hours. If the time range that I put is not in the lunch break. It will not deduct 1 hours.
Try this:
_getTimeDifference = function(startTime, endTime) {
var start = moment(startTime, "HH:mm A");
var end = moment(endTime, "HH:mm A");
var t = (end.isBefore(start)) ? end : '';
var diff = (end.diff(start)) / 3600000 -1;
return (t) ? diff - 13 : diff;
};
If your datetime present in Am-Pm format :the TimeSpan class in Datejs might help simplify the problem. It could be exactly your answer, if your problem is just subtract to time in AM-Pm format
I suggest such a code
var date1= Date.parse("6:30 am");
var date2= Date.parse("11:00 pm");
var diff = new TimeSpan(date2- date1);
console.log("Hours: ", diff.hours);
console.log("Minutes: ", diff.minutes);
Solution without Moment.js:
// dt1 and dt2 are assumed to be Date() objects:
function hoursDiff( dt1, dt2 ) {
// Difference in hours:
var diff = Math.abs(Math.round( (dt2.getTime() - dt1.getTime()) / 1000 / (60 * 60) ) );
// If range overlaps 12:00 - 1:00 pm, subtract 1 hour:
if (dt1.getHours() <= 12 && dt2.getHours() >= 13) {
diff--
}
return diff;
}
console.log( hoursDiff( new Date('2020-08-12 8:00:00'), new Date('2020-08-12 17:00:00') ) ) // 8am-5pm = 8
console.log( hoursDiff( new Date('2020-08-12 8:00:00'), new Date('2020-08-12 22:00:00') ) ) // 8am-10pm = 13
This doesn't account for times that begin or end within the 12:00 - 1:00 pm range, just dates that overlap it completely or not at all. It also assumes dates begin and end on hour boundaries, i.e. doesn't account for fractional hours.
I have two inputs of time and I want to get the difference/time-interval between these two using dayjs
fromtime = '13:00'
totime = '17:00'
So the output for the above two should be 4:00 hours
I tried
console.log(
dayjs(fromtime).diff(dayjs(totime), "hours")
);
But am not getting the expected output.
I found the solution to this.
const fromtime = '11:20'
const totime = '12:30'
const ft = dayjs(`2000-01-01 ${fromtime}`);
const tt = dayjs(`2000-01-01 ${totime}`);
const mins = tt.diff(ft, "minutes", true);
const totalHours = parseInt(mins / 60);
const totalMins = dayjs().minute(mins).$m
This will give the output as totalHours = 1 and totalMins = 10.
Hope this help someone.
Dayjs expects a Date in a certain format (dayjs parse string) not just a time. However you can set the hour (dayjs set hour) without setting a certain date (dayjs parse now):
var fromtime = dayjs().hour(13)
var totime = dayjs().hour(17)
console.log(totime.diff(fromtime, "hours"));
<script src="https://cdnjs.cloudflare.com/ajax/libs/dayjs/1.8.20/dayjs.min.js"></script>
EDIT
What if the input contains fromtime = '10.25' and totime = '11.30'. So my output should be '1.05'. But when I follow your method the output is 1. Is there a way to solve this
You can set The minutes also (dayjs set minute). Unfortunately i do not see any formatting options for time-differences in that library. So we will have to calculate that on our own:
function formatInterval(minutes) {
let interval = [
Math.floor(minutes / 60).toString(), //hours ("1" - "12")
(minutes % 60).toString() //minutes ("1" - "59")
];
return interval[0].padStart(2, '0') + ':' + interval[1].padStart(2, '0')
}
let fromtime = dayjs().hour(10).minute(25);
let totime = dayjs().hour(11).minute(30);
let interval = totime.diff(fromtime, "minute");
console.log(formatInterval(interval));
<script src="https://cdnjs.cloudflare.com/ajax/libs/dayjs/1.8.20/dayjs.min.js"></script>
EDIT2
This will fail if the day switches between the two first lines
OK was assuming the fromtime will always be a smaller number than the totime ... if thats not the case we can just substract negative amount of minutes from the total amount of minutes in a day like so:
function formatInterval(minutes) {
let interval = [Math.floor(minutes / 60).toString(), (minutes % 60).toString()];
return interval[0].padStart(2, '0') + ':' + interval[1].padStart(2, '0')
}
function getInterval(from, to) {
let [hoursA, minutesA] = from.split(':');
let [hoursB, minutesB] = to.split(':');
let timeA = dayjs().hour(hoursA).minute(minutesA);
let timeB = dayjs().hour(hoursB).minute(minutesB);
let interval = timeB.diff(timeA, 'minutes');
if(interval < 0) {
return formatInterval(24 * 60 + timeB.diff(timeA, 'minutes'));
}
return formatInterval(interval);
}
console.log(getInterval('23:00', '1:45'));
console.log(getInterval('10:25', '11:30'));
<script src="https://cdnjs.cloudflare.com/ajax/libs/dayjs/1.8.20/dayjs.min.js"></script>
// Addition, Difference between two time zones
import timezone from 'dayjs/plugin/timezone';
dayjs.extend(timezone);
const d1 = dayjs((dayjs().tz('Europe/Kiev').format('YYYY-MM-DDTHH:mm')));
const d2 = dayjs((dayjs().tz('Europe/London').format('YYYY-MM-DDTHH:mm')));
console.log(d1.diff(d2, 'hours', true)); // 2
fromtime = '13:00'
totime = '17:00'
These are currently strings and you need to convert it into integers.
console.log(parseInt(fromtime) - parseInt(totime)) //4
I know I can do anything and some more envolving Dates with momentjs. But embarrassingly, I'm having a hard time trying to do something that seems simple: geting the difference between 2 times.
Example:
var now = "04/09/2013 15:00:00";
var then = "04/09/2013 14:20:30";
//expected result:
"00:39:30"
what I tried:
var now = moment("04/09/2013 15:00:00");
var then = moment("04/09/2013 14:20:30");
console.log(moment(moment.duration(now.diff(then))).format("hh:mm:ss"))
//outputs 10:39:30
I do not understand what is that "10" there. I live in Brazil, so we are utc-0300 if that is relevant.
The result of moment.duration(now.diff(then)) is a duration with the correct internal values:
days: 0
hours: 0
milliseconds: 0
minutes: 39
months: 0
seconds: 30
years: 0
So, I guess my question is: how to convert a momentjs Duration to a time interval? I sure can use
duration.get("hours") +":"+ duration.get("minutes") +:+ duration.get("seconds")
but i feel that there is something more elegant that I am completely missing.
update
looking closer, in the above example now is:
Tue Apr 09 2013 15:00:00 GMT-0300 (E. South America Standard Time)…}
and moment(moment.duration(now.diff(then))) is:
Wed Dec 31 1969 22:39:30 GMT-0200 (E. South America Daylight Time)…}
I am not sure why the second value is in Daylight Time (-0200)... but I am sure that i do not like dates :(
update 2
well, the value is -0200 probably because 31/12/1969 was a date where the daylight time was being used... so thats that.
This approach will work ONLY when the total duration is less than 24 hours:
var now = "04/09/2013 15:00:00";
var then = "04/09/2013 14:20:30";
moment.utc(moment(now,"DD/MM/YYYY HH:mm:ss").diff(moment(then,"DD/MM/YYYY HH:mm:ss"))).format("HH:mm:ss")
// outputs: "00:39:30"
If you have 24 hours or more, the hours will reset to zero with the above approach, so it is not ideal.
If you want to get a valid response for durations of 24 hours or greater, then you'll have to do something like this instead:
var now = "04/09/2013 15:00:00";
var then = "02/09/2013 14:20:30";
var ms = moment(now,"DD/MM/YYYY HH:mm:ss").diff(moment(then,"DD/MM/YYYY HH:mm:ss"));
var d = moment.duration(ms);
var s = Math.floor(d.asHours()) + moment.utc(ms).format(":mm:ss");
// outputs: "48:39:30"
Note that I'm using the utc time as a shortcut. You could pull out d.minutes() and d.seconds() separately, but you would also have to zeropad them.
This is necessary because the ability to format a duration objection is not currently in moment.js. It has been requested here. However, there is a third-party plugin called moment-duration-format that is specifically for this purpose:
var now = "04/09/2013 15:00:00";
var then = "02/09/2013 14:20:30";
var ms = moment(now,"DD/MM/YYYY HH:mm:ss").diff(moment(then,"DD/MM/YYYY HH:mm:ss"));
var d = moment.duration(ms);
var s = d.format("hh:mm:ss");
// outputs: "48:39:30"
Your problem is in passing the result of moment.duration() back into moment() before formatting it; this results in moment() interpreting it as a time relative to the Unix epoch.
It doesn't give you exactly the format you're looking for, but
moment.duration(now.diff(then)).humanize()
would give you a useful format like "40 minutes". If you're really keen on that specific formatting, you'll have to build a new string yourself. A cheap way would be
[diff.asHours(), diff.minutes(), diff.seconds()].join(':')
where var diff = moment.duration(now.diff(then)). This doesn't give you the zero-padding on single digit values. For that, you might want to consider something like underscore.string - although it seems like a long way to go just for a few extra zeroes. :)
var a = moment([2007, 0, 29]);
var b = moment([2007, 0, 28]);
a.diff(b, 'days') //[days, years, months, seconds, ...]
//Result 1
Worked for me
See more in
http://momentjs.com/docs/#/displaying/difference/
If you want difference of two timestamp into total days,hours and minutes only, not in months and years .
var now = "01/08/2016 15:00:00";
var then = "04/02/2016 14:20:30";
var diff = moment.duration(moment(then).diff(moment(now)));
diff contains 2 months,23 days,23 hours and 20 minutes. But we need result only in days,hours and minutes so the simple solution is:
var days = parseInt(diff.asDays()); //84
var hours = parseInt(diff.asHours()); //2039 hours, but it gives total hours in given miliseconds which is not expacted.
hours = hours - days*24; // 23 hours
var minutes = parseInt(diff.asMinutes()); //122360 minutes,but it gives total minutes in given miliseconds which is not expacted.
minutes = minutes - (days*24*60 + hours*60); //20 minutes.
Final result will be : 84 days, 23 hours, 20 minutes.
When you call diff, moment.js calculates the difference in milliseconds.
If the milliseconds is passed to duration, it is used to calculate duration which is correct.
However. when you pass the same milliseconds to the moment(), it calculates the date that is milliseconds from(after) epoch/unix time that is January 1, 1970 (midnight UTC/GMT).
That is why you get 1969 as the year together with wrong hour.
duration.get("hours") +":"+ duration.get("minutes") +":"+ duration.get("seconds")
So, I think this is how you should do it since moment.js does not offer format function for duration. Or you can write a simple wrapper to make it easier/prettier.
This should work fine.
var now = "04/09/2013 15:00:00";
var then = "02/09/2013 14:20:30";
var ms = moment(now,"DD/MM/YYYY HH:mm:ss").diff(moment(then,"DD/MM/YYYY HH:mm:ss"));
var d = moment.duration(ms);
console.log(d.days() + ':' + d.hours() + ':' + d.minutes() + ':' + d.seconds());
If we want only hh:mm:ss, we can use a function like that:
//param: duration in milliseconds
MillisecondsToTime: function(duration) {
var seconds = parseInt((duration/1000)%60)
, minutes = parseInt((duration/(1000*60))%60)
, hours = parseInt((duration/(1000*60*60))%24)
, days = parseInt(duration/(1000*60*60*24));
var hoursDays = parseInt(days*24);
hours += hoursDays;
hours = (hours < 10) ? "0" + hours : hours;
minutes = (minutes < 10) ? "0" + minutes : minutes;
seconds = (seconds < 10) ? "0" + seconds : seconds;
return hours + ":" + minutes + ":" + seconds;
}
Use this:
var duration = moment.duration(endDate.diff(startDate));
var aa = duration.asHours();
Instead of
Math.floor(duration.asHours()) + moment.utc(duration.asMilliseconds()).format(":mm:ss")
It's better to do
moment.utc(total.asMilliseconds()).format("HH:mm:ss");
This will work for any date in the format YYYY-MM-DD HH:mm:ss
const moment=require("moment");
let startDate=moment("2020-09-16 08:39:27");
const endDate=moment();
const duration=moment.duration(endDate.diff(startDate))
console.log(duration.asSeconds());
console.log(duration.asHours());
In ES8 using moment, now and start being moment objects.
const duration = moment.duration(now.diff(start));
const timespan = duration.get("hours").toString().padStart(2, '0') +":"+ duration.get("minutes").toString().padStart(2, '0') +":"+ duration.get("seconds").toString().padStart(2, '0');
Typescript: following should work,
export const getTimeBetweenDates = ({
until,
format
}: {
until: number;
format: 'seconds' | 'minutes' | 'hours' | 'days';
}): number => {
const date = new Date();
const remainingTime = new Date(until * 1000);
const getFrom = moment([date.getUTCFullYear(), date.getUTCMonth(), date.getUTCDate()]);
const getUntil = moment([remainingTime.getUTCFullYear(), remainingTime.getUTCMonth(), remainingTime.getUTCDate()]);
const diff = getUntil.diff(getFrom, format);
return !isNaN(diff) ? diff : null;
};
DATE TIME BASED INPUT
var dt1 = new Date("2019-1-8 11:19:16");
var dt2 = new Date("2019-1-8 11:24:16");
var diff =(dt2.getTime() - dt1.getTime()) ;
var hours = Math.floor(diff / (1000 * 60 * 60));
diff -= hours * (1000 * 60 * 60);
var mins = Math.floor(diff / (1000 * 60));
diff -= mins * (1000 * 60);
var response = {
status : 200,
Hour : hours,
Mins : mins
}
OUTPUT
{
"status": 200,
"Hour": 0,
"Mins": 5
}
The following approach is valid for all cases (difference between dates less than 24 hours and difference greater than 24 hours):
// Defining start and end variables
let start = moment('04/09/2013 15:00:00', 'DD/MM/YYYY hh:mm:ss');
let end = moment('04/09/2013 14:20:30', 'DD/MM/YYYY hh:mm:ss');
// Getting the difference: hours (h), minutes (m) and seconds (s)
let h = end.diff(start, 'hours');
let m = end.diff(start, 'minutes') - (60 * h);
let s = end.diff(start, 'seconds') - (60 * 60 * h) - (60 * m);
// Formating in hh:mm:ss (appends a left zero when num < 10)
let hh = ('0' + h).slice(-2);
let mm = ('0' + m).slice(-2);
let ss = ('0' + s).slice(-2);
console.log(`${hh}:${mm}:${ss}`); // 00:39:30
This will return biggest time period diff like (4 seconds, 2 minutes, 1 hours, 2 days, 3 weeks, 4 months, 5 years).
I use this for notification recent time.
function dateDiff(startDate, endDate) {
let arrDate = ["seconds", "minutes", "hours", "days", "weeks", "months", "years"];
let dateMap = arrDate.map(e => moment(endDate).diff(startDate, e));
let index = 6 - dateMap.filter(e => e == 0).length;
return {
type: arrDate[index] ?? "seconds",
value: dateMap[index] ?? 0
};
}
Example:
dateDiff("2021-06-09 01:00:00", "2021-06-09 04:01:01")
{type: "hours", value: 3}
dateDiff("2021-06-09 01:00:00", "2021-06-12 04:01:01")
{type: "days", value: 3}
dateDiff("2021-06-09 01:00:00", "2021-06-09 01:00:10")
{type: "seconds", value: 10}
I create a simple function with typescript
const diffDuration: moment.Duration = moment.duration(moment('2017-09-04 12:55').diff(moment('2017-09-02 13:26')));
setDiffTimeString(diffDuration);
function setDiffTimeString(diffDuration: moment.Duration) {
const str = [];
diffDuration.years() > 0 ? str.push(`${diffDuration.years()} year(s)`) : null;
diffDuration.months() > 0 ? str.push(`${diffDuration.months()} month(s)`) : null;
diffDuration.days() > 0 ? str.push(`${diffDuration.days()} day(s)`) : null;
diffDuration.hours() > 0 ? str.push(`${diffDuration.hours()} hour(s)`) : null;
diffDuration.minutes() > 0 ? str.push(`${diffDuration.minutes()} minute(s)`) : null;
console.log(str.join(', '));
}
// output: 1 day(s), 23 hour(s), 29 minute(s)
for generate javascript https://www.typescriptlang.org/play/index.html
InTime=06:38,Outtime=15:40
calTimeDifference(){
this.start = dailyattendance.InTime.split(":");
this.end = dailyattendance.OutTime.split(":");
var time1 = ((parseInt(this.start[0]) * 60) + parseInt(this.start[1]))
var time2 = ((parseInt(this.end[0]) * 60) + parseInt(this.end[1]));
var time3 = ((time2 - time1) / 60);
var timeHr = parseInt(""+time3);
var timeMin = ((time2 - time1) % 60);
}
EPOCH TIME DIFFERENCE USING MOMENTJS:
To Get Difference between two epoch times:
Syntax:
moment.duration(moment(moment(date1).diff(moment(date2)))).asHours()
Difference in Hours:
moment.duration(moment(moment(1590597744551).diff(moment(1590597909877)))).asHours()
Difference in minutes:
moment.duration(moment(moment(1590597744551).diff(moment(1590597909877)))).asMinutes().toFixed()
Note: You could remove .toFixed() if you need precise values.
Code:
const moment = require('moment')
console.log('Date 1',moment(1590597909877).toISOString())
console.log('Date 2',moment(1590597744551).toISOString())
console.log('Date1 - Date 2 time diffrence is : ',moment.duration(moment(moment(1590597909877).diff(moment(1590597744551)))).asMinutes().toFixed()+' minutes')
Refer working example here:
https://repl.it/repls/MoccasinDearDimension
To get the difference between two-moment format dates or javascript Date format indifference of minutes the most optimum solution is
const timeDiff = moment.duration((moment(apptDetails.end_date_time).diff(moment(apptDetails.date_time)))).asMinutes()
you can change the difference format as you need by just replacing the asMinutes() function
If you want a localized number of days between two dates (startDate, endDate):
var currentLocaleData = moment.localeData("en");
var duration = moment.duration(endDate.diff(startDate));
var nbDays = Math.floor(duration.asDays()); // complete days
var nbDaysStr = currentLocaleData.relativeTime(returnVal.days, false, "dd", false);
nbDaysStr will contain something like '3 days';
See https://momentjs.com/docs/#/i18n/changing-locale/ for information on how to display the amount of hours or month, for example.
It is very simple with moment
below code will return diffrence in hour from current time:
moment().diff('2021-02-17T14:03:55.811000Z', "h")
const getRemainingTime = (t2) => {
const t1 = new Date().getTime();
let ts = (t1-t2.getTime()) / 1000;
var d = Math.floor(ts / (3600*24));
var h = Math.floor(ts % (3600*24) / 3600);
var m = Math.floor(ts % 3600 / 60);
var s = Math.floor(ts % 60);
console.log(d, h, m, s)
}
SO i have 2 datetime objects .
now = Nov 15 4:00 PM
later = Nov 15 6:00PM
My objective is to get the total hours between (9AM to 5 PM) , given the now and later times.
resulting answer shud be 1 hour. (since im only concerned about time range that falls within 9AM-5PM)
now = Nov 15 6:00 AM
later = Nov 15 8:00 PM
resulting answer should be 8 hours.
is the best way to achieve this using the diff function in moment and stripping the hour out and calculating individual use cases ( when start time less than 9AM/ start time greater than 9AM) . similarly end time (less than 5PM/greater than 5PM) etc?
Also how to tackle this case where,
now = Nov 15 9:00AM
later = Nov 18 2:00PM
resulting answer shud be ,
8(nov 15)+8(nov 16)+8(nov 17)+5(nov 18) = 29hrs
Here's working solution
var now = moment("15 Nov 2016, 9:00:00 am", "DD MMM yyyy, h:mm:ss a").toDate();
var later = moment("18 Nov 2016, 2:00:00 pm", "DD MMM yyyy, h:mm:ss a").toDate();
function getWorkingHours(now, later) {
var hoursToday = 0;
var workingHourStart = 9;
var workingHourEnd = 17;//5pm
var workDuration = workingHourEnd - workingHourStart;
if(workingHourEnd - getHours(now) > 0) {
hoursToday = (workingHourEnd - getHours(now));
hoursToday = (hoursToday > workDuration) ? workDuration : hoursToday;
}
var hoursLater = 0;
if(getHours(later) - workingHourStart > 0) {
hoursLater = (getHours(later) - workingHourStart);
hoursLater = (hoursLater > workDuration) ? workDuration : hoursLater;
}
var actualDiffHours = (later.getTime() - now.getTime()) / (1000 * 60 * 60);
var actualHoursInBetween = actualDiffHours - (24 - getHours(now)) - getHours(later);
var workingHoursInBetween = (actualHoursInBetween / 24) * 8;
return hoursToday + workingHoursInBetween + hoursLater;
}
function getHours(date) {
var hours = date.getHours() + date.getMinutes() / 60 + date.getSeconds() / 3600 + date.getMilliseconds() / 3600/1000;
return hours;
}
console.log(getWorkingHours(now, later));
<script src="http://momentjs.com/downloads/moment.min.js"></script>
This should do the job:
const now = moment(new Date(2016, 11, 15, 9, 0, 0));
const then = moment(new Date(2016, 11, 18, 14, 0, 0));
function calDiff(now, then) {
if (now.hour() < 9) {
now.hour(9);
}
if (then.hour() > 17) {
then.hour(17);
}
const total = then.diff(now, 'hours');
const day = Math.floor(total / 24);
return total - (16 * day);
}
console.log(calDiff(now, then));
<script src="https://cdnjs.cloudflare.com/ajax/libs/moment.js/2.16.0/moment.min.js"></script>
Complicated... Function getActiveHours calculates all active slots between start and finish dates, both inclusive, and then removes the missing hours at the beginning of the start date and at the end of the finish date.
var getDateObject = function (date) {
if (date && date.constructor.name == "Array") {
while (date.length < 7) {date.push(0);}
date = new Date(date[0], date[1], date[2], date[3], date[4], date[5], date[6]);
} else if (typeof date == 'string' || typeof date == 'number') {
date = new Date(date);
}
return date;
};
var trimDate = function (date, period) {
var periods = ['second', 'minute', 'hour', 'day'];
period = periods.indexOf(period);
if (typeof date != 'number') {date = getDateObject(date).getTime();}
date = Math.floor(date/1000);
if (period > 0) {date = Math.floor(date/60);}
if (period > 1) {date = Math.floor(date/60);}
if (period > 2) {date = Math.floor(date/24);}
return new Date(date*24*60*60*1000);
};
var getOffset = function (date) {return getDateObject(date).getTimezoneOffset()*60*1000;};
var addOffset = function (date) {
date = getDateObject(date);
return new Date(date.getTime()+getOffset(date));
};
var getActiveHours = function (iniDateTime, endDateTime, startHour, finishHour) {
var hourMs = 60*60*1000; // Define daily active hours 0-24 (decimal 17.5 = 5:30pm):
if (startHour == null) {startHour = 9;}
if (finishHour == null) {finishHour = 17;}
startHour *= hourMs; finishHour *= hourMs;
iniDateTime = getDateObject(iniDateTime).getTime();
endDateTime = getDateObject(endDateTime).getTime();
var iniDayTime = addOffset(trimDate(iniDateTime, 'day')).getTime();
var endDayTime = addOffset(trimDate(endDateTime, 'day')).getTime();
var totalHoursMs = (endDayTime-iniDayTime+24*hourMs)*(finishHour-startHour)/hourMs/24;
var iniHoursNotInMs = iniDateTime-iniDayTime-startHour;
var endHoursNotInMs = endDayTime+finishHour-endDateTime;
return (totalHoursMs-iniHoursNotInMs-endHoursNotInMs)/hourMs;
};
console.log(Math.round(getActiveHours('2016-09-13 11:45:38', '2016-09-15 15:30:25'))); // 20 // Use Math round or floor
I had started writing this awhile back when I first saw the question, but got caught up. My answer is very similar to Khang's, but we went about a certain section of it a little differently.
The basic idea behind the code is that it takes two moment objects. If the start hours are less than nine, we set them to be nine, and if the end hours are greater than 17 (5pm) we set them to be 17.
Next we get the difference between the two objects in days. For each day we know that there are 8 hours the person can get credit for. I then move the date of the start day to the end day, and take the hours between them.
The idea behind this is that if both times are within the same days, there will be 0 days difference. If it is 1, then we will get a total of 8 hours regardless where we start in the day. the only cases I haven't tested are things where the start time is greater than the end time (I'll test it ASAP and make an edit if there's anything I need to change)
Edit
there was indeed a problem if the start time was after the end time (the hours).
This was fixed by adding in one if statement.
$(function() {
function getActiveHours(start, end) {
if (start.hours() < 9) start.hours(9);
if (end.hours() > 17) end.hours(17);
//These two if's should remove most of the issues when we are doing basic work
var days = end.diff(start, 'days');
if (days == 0 && (end.date() - start.date()) == 1) days = 1;
var hours = (days * 8); //gets the hours
start.date(end.date());
var diff = end.diff(start, 'hours');
return hours + diff;
}
var start = moment([2016, 10, 15, 9, 0, 0]);
var end = moment([2016, 10, 18, 14, 0, 0]);
$('#results').html('Total hours worked from ' + start.format('MM-DD-YYYY # hh:mm:ss') + ' to ' + end.format('MM-DD-YYYY # hh:mm:ss') + ' is ' + getActiveHours(start, end))
});
<div id="results"></div>