admin管理员组

文章数量:1303638

After looking through some of the other MomentJS Questions and answers I'm still stumped as to how one would use moment to simply pare two different times.

I do not need (want) the day/date to be considered.

My use case is this: I'm reading a schedule (start/end times) from a config file. This is done using Node.js

Starttime = 6:30 PM
Endtime = 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 = currtime.isBetween(starttime , endtime);
console.log(amIBetween);   //  returns false

My scenario is technically spanning two days and I understand why it's false.

I need (expect) moment to return TRUE - i.e. that currtime isBeteen start and endtime and falls in that range.

Would I need to check for a time after 12AM and then add a day to make the check work? Any other suggestions for acplishing this. I looked at moment-range which has 'contains ' function but with similar question for that.

I'm finding it hard to believe that it's this plex, 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. Kludge?

After looking through some of the other MomentJS Questions and answers I'm still stumped as to how one would use moment to simply pare two different times.

I do not need (want) the day/date to be considered.

My use case is this: I'm reading a schedule (start/end times) from a config file. This is done using Node.js

Starttime = 6:30 PM
Endtime = 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 = currtime.isBetween(starttime , endtime);
console.log(amIBetween);   //  returns false

My scenario is technically spanning two days and I understand why it's false.

I need (expect) moment to return TRUE - i.e. that currtime isBeteen start and endtime and falls in that range.

Would I need to check for a time after 12AM and then add a day to make the check work? Any other suggestions for acplishing this. I looked at moment-range which has 'contains ' function but with similar question for that.

I'm finding it hard to believe that it's this plex, 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. Kludge?

Share edited Oct 28, 2016 at 22:36 rfossella asked Oct 28, 2016 at 19:26 rfossellarfossella 1271 gold badge3 silver badges11 bronze badges 0
Add a ment  | 

4 Answers 4

Reset to default 4

After my own testing and looking at other's suggestions it sill appeared that disregarding DAY/DATE and trying to span days was an issue. I came up with this which is now working in my app.

isTimeBetween = function(aStartTime, anEndTime, aCurrTime)
{
    // you may pass in aCurrTime or use the *actual* current time
    var currentTime = !aCurrTime ? moment() : moment(aCurrTime, "HH:mm a");
    var startTime = moment(aStartTime, "HH:mm a");
    var endTime = moment(anEndTime, "HH:mm a");

    if (startTime.hour() >=12 && endTime.hour() <=12 )
    {
        endTime.add(1, "days");       // handle spanning days
    }

    var isBetween = currentTime.isBetween(startTime, endTime);

    /***  testing   
    startTimeString = startTime.toString();
    endTimeString = endTime.toString();
    currentTimeString = currentTime.toString();

    console.log(startTimeString);
    console.log(endTimeString);
    console.log(currentTimeString);
    console.log('\nis '+ currentTimeString  + ' between ' + 
              startTimeString + ' and ' + endTimeString + ' : ' 
              + isBetween);
    ****/
    return isBetween;
    }

isTimeBetween("06:30pm", "03:30am", "11:00pm");     //true      !! this is main use case
isTimeBetween("06:30pm", "10:30pm", "11:00pm");     //false
isTimeBetween("04:00am", "06:00am");                //true (e.g. current time is 5am

I see two issues.

1) Your variable name currtime on line 5 is different than your declaration on line 1 currentTime

2) You could break it up into two checks around midnight like so:

var currentTime = moment();    // e.g. 11:00 pm
var sixThirty = moment('06:30 pm', "HH:mm a");
var midnight = moment('12:00 am', "HH:mm a");
var threeThirty = moment('03:30 am', "HH:mm a");

amIBetween1 = currentTime.isBetween(sixThirty , midnight);
amIBetween2 = currentTime.isBetween(midnight , threeThirty);
console.log(amIBetween1);
console.log(amIBetween2);

dylpickle's answer looks correct to me, but if you decide that the isBetween is easy to fumble, then you may want to take that abstraction away, take a step down into it's functionality.

"explicitness is far cheaper than the wrong abstraction"

That is not to say that isBetween is the wrong abstraction, but it is a tiny bit less explicit in that you could easily feed it the parameters in the wrong answer which would give you the opposite of what you intended.

If you

console.log(currentTime.isBetween)

you get the implementation:

ob(a,b,c,d){return d=d||"()",("("===d[0]?this.isAfter(a,c):!this.isBefore(a,c))&&(")"===d[1]?this.isBefore(b,c):!this.isAfter(b,c))}

Notice that it just uses isAfter() and isBefore(). Sometimes you can simplify things sometimes by being more explicit with your code.

isBetween looks a little uglified and seems to cover all of the edge cases, but don't be afraid to try to improve things either.

Try the following code:

const isBetween = currentTime.isAfter(endtime) && currentTime.isBefore(starttime);

console.log(isBetween)

There is no way to get confused in the implementation or adding changes later. This does not increase cyclomatic plexity or lines of code.

I was facing the same issue and I did a kind of work around as follows:

function fgEsHora1MayorAHora2(hora1, hora2) {

  var f1 = moment('2000-01-01 ' + hora1);
  f1.tz('America/Mexico_City').format('ha z');
  let f1Hora = f1.toObject().hours;
  let f1Minutos = f1.toObject().minutes;

  var f2 = moment('2000-01-01 ' + hora2);
  f2.tz('America/Mexico_City').format('ha z');
  let f2Hora = f2.toObject().hours;
  let f2Minutos = f2.toObject().minutes;

  let minutos1 = parseInt(f1Hora * 100) + parseInt(f1Minutos);
  let minutos2 = parseInt(f2Hora * 100) + parseInt(f2Minutos);

  return minutos1 > minutos2;
}

I separated the hours and multiply it by 100 in order to give it more value... so, I added "hours" plus minutes and then I did the parison..

Remarks: The trick stands on add the date like "2001-01-01", just to be able to get the time and hour...

And it's working fine!!

本文标签: javascriptOnly want to compare TIME values MomentJSStack Overflow