Moment: ¿Cómo comparar solo HH: mm?

Creado en 20 oct. 2013  ·  10Comentarios  ·  Fuente: moment/moment

Estoy usando moment.js con mi proyecto node.js

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

Quiero comparar solo el tiempo en formato HH: mm. Sin embargo, no funciona porque

'7:00' > '2:00'

devuelve falso. ¿Alguna idea de cómo comparar HH:mm?

Comentario más útil

Después de revisar otras preguntas de MomentJS, todavía estoy perplejo en cuanto a cómo se usaría el momento para simplemente comparar dos momentos diferentes .

Necesito (quiero) que se ignore el día/fecha.

Caso de uso:
Estoy leyendo un horario con horas de inicio y finalización de un archivo de configuración. Esto se hace usando Node.js

Hora de inicio = 6:30 p. m.
Hora de finalización = 3:30 a. m.

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

Mi escenario técnicamente abarca dos días y entiendo por qué es falso.

Necesito (esperar) un momento para devolver VERDADERO, es decir, que currentTime isBeteen startTime y endTime y cae en ese rango.

Pensé que lo había resuelto al verificar si la hora de finalización es> 12 y luego agregar un día para que el momento entienda que es el día siguiente. p.ej

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

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

Pero si currentTime también es posterior a la medianoche, entonces se rompe, por ejemplo

La 01:30 a. m. no se considerará entre las 06:30 p. m. y las 03:30 a. m., también debido a que los días son diferentes

¿Alguna otra sugerencia para lograr esto y simplemente ignorar el día/fecha?

Me cuesta creer que sea tan complejo, pero tal vez lo sea:

Aquí hay una aclaración adicional de que el problema surge con los días de expansión, incluso cuando se trata de ser más explícito:

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

Parece un poco obvio que serían falsos ya que el _día/fecha_ se considera por momento. Esto es lo que estoy tratando de evitar.

Lo siguiente funcionaría:

endTime.add(1, "days");
currentTime.isBetween(startTime, endTime);  // TRUE

Sin embargo, esto significaría que tendría que verificar si la HORA DE INICIO fue antes de las 12 a. m. y la HORA DE FINALIZACIÓN después de las 12 a. m. y luego agregar 1 día a la HORA DE FINALIZACIÓN.

Todos 10 comentarios

Por lo general, si no le importa la fecha de finalización, es mejor realizar un seguimiento de las horas y los minutos de forma explícita, pero, por supuesto, no sé nada sobre su aplicación. Entonces, para responderla directamente, defina una nueva función para devolver la cantidad de minutos:

var minutesOfDay = function(m){
  return m.minutes() + m.hours() * 60;
}

y luego comprueba que:

return minutesOfDay(now) > minutesOfDay(end);

Aparte, moment() hace lo mismo que moment(new Date()) , por lo que debería ahorrarle algo de texto.

Después de revisar otras preguntas de MomentJS, todavía estoy perplejo en cuanto a cómo se usaría el momento para simplemente comparar dos momentos diferentes .

Necesito (quiero) que se ignore el día/fecha.

Caso de uso:
Estoy leyendo un horario con horas de inicio y finalización de un archivo de configuración. Esto se hace usando Node.js

Hora de inicio = 6:30 p. m.
Hora de finalización = 3:30 a. m.

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

Mi escenario técnicamente abarca dos días y entiendo por qué es falso.

Necesito (esperar) un momento para devolver VERDADERO, es decir, que currentTime isBeteen startTime y endTime y cae en ese rango.

Pensé que lo había resuelto al verificar si la hora de finalización es> 12 y luego agregar un día para que el momento entienda que es el día siguiente. p.ej

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

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

Pero si currentTime también es posterior a la medianoche, entonces se rompe, por ejemplo

La 01:30 a. m. no se considerará entre las 06:30 p. m. y las 03:30 a. m., también debido a que los días son diferentes

¿Alguna otra sugerencia para lograr esto y simplemente ignorar el día/fecha?

Me cuesta creer que sea tan complejo, pero tal vez lo sea:

Aquí hay una aclaración adicional de que el problema surge con los días de expansión, incluso cuando se trata de ser más explícito:

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

Parece un poco obvio que serían falsos ya que el _día/fecha_ se considera por momento. Esto es lo que estoy tratando de evitar.

Lo siguiente funcionaría:

endTime.add(1, "days");
currentTime.isBetween(startTime, endTime);  // TRUE

Sin embargo, esto significaría que tendría que verificar si la HORA DE INICIO fue antes de las 12 a. m. y la HORA DE FINALIZACIÓN después de las 12 a. m. y luego agregar 1 día a la HORA DE FINALIZACIÓN.

Supongo que no entiendo muy bien lo que quieres decir con "ignorar el día". Si estás comparando estos dos tiempos

var startTime = moment('06:00p', "HH:mm a");
var endTime = moment('03:30a', "HH:mm a");

de alguna manera el sistema tiene que saber que te refieres a las 3:30 _mañana_. Quiero decir, ¿cómo podría funcionar? Seguramente, no crees que en ausencia de información del día que las 3:30 AM son después de las 6:00 PM... El problema es que tienes un contexto extra que Moment no tiene, y es que el endTime Se espera que startTime ; eso es obvio a partir de los nombres de las variables, pero Moment no lo sabe ni puede saberlo. Tendrás que contarlo.

Entonces, ¿qué tal esto?

if (startTime.isAfter(endTime)){
  endTime.add(1, 'days');
}

Sí, entiendo la confusión. Sin saber que queremos decir "3:30 am" es el día siguiente, es complicado.

Sin tener en cuenta el día/fecha:
_Si pregunto "son las 23:00 entre las 21:00 y las 03:00" espero que la respuesta sea cierta .
Si pregunto "son las 23:00 entre las 3:00 y las 21:00" espero que la respuesta sea falsa ._

Como no puedo simplemente ignorar la fecha usando el momento, comencé a buscar TODAS las veces antes/después de las 12 y terminé con:

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

El violín que tengo aquí muestra mis escenarios de casos de uso. Espero que sea útil.
https://jsfiddle.net/rfossella/66wjtnvk/1/

Gracias de nuevo por su tiempo (sin juego de palabras :-))

O simplemente algo como esta función:

Actualizado después de la respuesta de @Machibuse

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

Por lo tanto, podría usar los métodos MomentJS isBetween, isAfter, isBefore solo con la hora y no la fecha.

Tratar

second.isBetween(third, first, 'minutes', '[]'); // true

No es un error en Moment, es una información que falta en la documentación de que el primer parámetro debe ser la fecha anterior.

Todavía bastante perplejo por este también. ¡He gastado más en él de lo que me gustaría admitir! @Machibuse o @rfossella, ¿qué implementación terminó funcionando?

Solía ​​​​estar atascado con el mismo problema, y ​​​​finalmente encontré una manera de hacer que funcione 👍 formateando el tiempo en tiempo militar, espero que pueda ayudar...

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
}

Entonces puedo usar esta función así:

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 Funciona muy bien, ¡gracias!

Hola,
Volví a revisar el violín que publiqué hace años y todavía está activo y funciona. FYI: Mi ejemplo no introduce el tiempo militar, en caso de que lo necesite.

El violín que tengo aquí muestra mis escenarios de casos de uso. Espero que sea útil.
https://jsfiddle.net/rfossella/66wjtnvk/1/

Robar

¿Fue útil esta página
0 / 5 - 0 calificaciones