I am using moment.js with my node.js project
isWithinTime: function(end) {
var moment = require('moment');
var now = moment(new Date()).format('HH:mm');
var end = moment(new Date(end)).format('HH:mm');
if (now.toString() > end.toString()) {
return false;
}
return true;
}
I want to compare only time in HH:mm format. However it does not work because
'7:00' > '2:00'
returns false. Any ideas how to compare HH:mm?
Usually, if you don't care about the end time's date, it's better to just keep track of the hours and minutes explicitly, but of course I don't know anything about your app. So to answer it directly, define a new function for returning the number of minutes:
var minutesOfDay = function(m){
return m.minutes() + m.hours() * 60;
}
and then check that:
return minutesOfDay(now) > minutesOfDay(end);
As an aside, moment() does the same thing as moment(new Date()), so that should save you some text.
After looking through other MomentJS questions I'm still stumped as to how one would use moment to simply compare two different times
I need (want) the day/date to be ignored.
Use case:
I'm reading a schedule w/ start & end times from a config file. This is done using Node.js
Start time = 6:30 PM
End time = 3:30 AM
var currentTime= moment(); // e.g. 11:00 pm
var startTime = moment('06:30 pm', "HH:mm a");
var endTime = moment('03:30 am', "HH:mm a");
amIBetween = currentTime.isBetween(startTime , endTime);
console.log(amIBetween); // returns false. if date ignored I expect TRUE
My scenario is technically spanning two days and I understand why it's false.
I need (expect) moment to return TRUE - i.e. that currentTime isBeteen startTime and endTime and falls in that range.
I thought I had it solved by checking if endTime hour is > 12 then add a day to make moment understand it's the following day. e.g.
if (startTime.hour() >=12 && endTime.hour() <=12 )
{
endTime.add(1, "days"); // handle spanning days
}
var isBetween = currentTime.isBetween(startTime, endTime); // TRUE
But if currentTime is also after midnight then it breaks - e.g.
01:30am will not be considered between 06:30pm and 03:30am - also because of different days
Any other suggestions for accomplishing this and simply ignoring the day/date?
I'm finding it hard to believe that it's this complex, but maybe it is :
Here's further clarification that issue arises with spanning days, even when trying to be more explicit:
var currentTime= moment('11:00p', "HH:mm a");
var startTime = moment('06:00p', "HH:mm a");
var endTime = moment('03:30a', "HH:mm a");
currentTime.toString(); //"Fri Oct 28 2016 23:00:00 GMT-0400"
startTime.toString(); // "Fri Oct 28 2016 18:00:00 GMT-0400"
endTime.toString(); // "Fri Oct 28 2016 03:30:00 GMT-0400"
currentTime.isBetween(startTime, endTime); // false
currentTime.isAfter(endTime) && currentTime.isBefore(startTime); //false
currentTime.isAfter(startTime) && currentTime.isBefore(endTime); //false
Seems kind of obvious that they'd be false since the _day/date_ is considered by moment. This is what I'm trying to get around.
The following would work:
endTime.add(1, "days");
currentTime.isBetween(startTime, endTime); // TRUE
This would mean however, that I'd need to check if the START TIME was before 12AM && the ENDTIME as after 12AM then add 1 day to ENDTIME.
I guess I don't quite understand what you mean by "ignoring the day". If you're comparing these two times
var startTime = moment('06:00p', "HH:mm a");
var endTime = moment('03:30a', "HH:mm a");
somehow the system has to know that you mean 3:30 _tomorrow_. I mean, how could it ever work? Surely, you don't think that in the absence of day information that 3:30 AM is after 6:00 PM...The problem is that you have some extra context that Moment doesn't have, which is that the endTime is expected to be after the startTime; that's obvious from your variable names, but Moment doesn't and can't know that. You'll have to tell it.
So how about this:
if (startTime.isAfter(endTime)){
endTime.add(1, 'days');
}
Yeah, I understand the confusion. Without knowing that we mean "3:30am" is the next day it is tricky.
Disregarding the day/date:
_If I ask, "is 11pm between 9pm and 3am" I expect the answer to be true.
If I ask, "is 11pm between 3am and 9pm" I expect the answer to be false._
Since I can't simply ignore the date using moment I started checking for ALL times before/after 12 and ended up with:
if ( (startTime.hour() >=12 && endTime.hour() <=12 ) || endTime.isBefore(startTime) )
{
endTime.add(1, "days"); // handle spanning days endTime
if (currentTime.hour() <=12 )
{
currentTime.add(1, "days"); // handle spanning days currentTime
}
}
The fiddle I have here displays my use case scenarios. Hope it's useful.
https://jsfiddle.net/rfossella/66wjtnvk/1/
Thanks again for your time (no pun intended :-) )
Or just something like this function:
Updated after @Machibuse answer
function getTime(dateTime: Moment): Moment {
return moment({h: dateTime.hours(), m: dateTime.minutes()});
}
/** USAGE EXAMPLE */
const first: Moment = getTime( moment([2018, 5, 1, 17, 0, 0]) ); // 17:00
const second: Moment = getTime( moment([2013, 8, 2, 18, 0, 0]) ); // 18:00
const third: Moment = getTime( moment([2015, 3, 3, 19, 0, 0]) ); // 19:00
second.isAfter(first, 'minutes'); // true
first.isBefore(second, 'minutes'); // true
first.isAfter(second, 'minutes'); // false
second.isBefore(first, 'minutes'); // false
second.isBetween(first, third, 'minutes', '[]'); // true
third.isBetween(first, second, 'minutes', '[]'); // false
// second.diff(first, 'minutes') => 60
// second.diff(third, 'minutes') => -60
// third.diff(first, 'minutes') => 120
So you could the is the MomentJS methods isBetween, isAfter, isBefore only with the time and not the date.
Try
second.isBetween(third, first, 'minutes', '[]'); // true
Its not a bug in Moment, ist a missing information in the documentation that the first parameter must be the earlier date.
Still pretty stumped by this one too. I have spent more on it than I care to admit! @Machibuse or @rfossella what implementation ended up working?
I used to be stucked with same issue, and finally found a way to make it works 馃憤 formatting time in military time, I hope it might help...
const isTimeBetween = function(startTime, endTime, serverTime) {
let start = moment(startTime, "H:mm")
let end = moment(endTime, "H:mm")
let server = moment(serverTime, "H:mm")
if (end < start) {
return server >= start && server<= moment('23:59:59', "h:mm:ss") || server>= moment('0:00:00', "h:mm:ss") && server < end;
}
return server>= start && server< end
}
Then I can use this function like so:
isTimeBetween('22:30', '3:00', '23:50') //return true
isTimeBetween('22:30', '3:00', '1:50') //return true
isTimeBetween('22:30', '3:00', '4:50') //return false
@kdavong It's works very well, thank you!
Hi,
I rechecked the fiddle I posted years ago and it is still active and still works. FYI: My example does not introduce military time, in case you do need that.
The fiddle I have here displays my use case scenarios. Hope it's useful.
https://jsfiddle.net/rfossella/66wjtnvk/1/
Rob
Most helpful comment
After looking through other MomentJS questions I'm still stumped as to how one would use moment to simply compare two different times
I need (want) the day/date to be ignored.
Use case:
I'm reading a schedule w/ start & end times from a config file. This is done using Node.js
My scenario is technically spanning two days and I understand why it's false.
I need (expect) moment to return TRUE - i.e. that currentTime isBeteen startTime and endTime and falls in that range.
I thought I had it solved by checking if endTime hour is > 12 then add a day to make moment understand it's the following day. e.g.
But if currentTime is also after midnight then it breaks - e.g.
01:30am will not be considered between 06:30pm and 03:30am - also because of different days
Any other suggestions for accomplishing this and simply ignoring the day/date?
I'm finding it hard to believe that it's this complex, but maybe it is :
Here's further clarification that issue arises with spanning days, even when trying to be more explicit:
Seems kind of obvious that they'd be false since the _day/date_ is considered by moment. This is what I'm trying to get around.
The following would work:
This would mean however, that I'd need to check if the START TIME was before 12AM && the ENDTIME as after 12AM then add 1 day to ENDTIME.