Moment: Comment comparer uniquement HH:mm ?

Créé le 20 oct. 2013  ·  10Commentaires  ·  Source: moment/moment

J'utilise moment.js avec mon projet 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;
}

Je veux comparer uniquement l'heure au format HH: mm. Cependant, cela ne fonctionne pas car

'7:00' > '2:00'

renvoie faux. Des idées sur la façon de comparer HH: mm ?

Commentaire le plus utile

Après avoir examiné d'autres questions MomentJS, je ne sais toujours pas comment utiliser le moment pour comparer simplement deux moments différents.

J'ai besoin (vouloir) que le jour/la date soit ignoré.

Cas d'utilisation:
Je lis un calendrier avec des heures de début et de fin à partir d'un fichier de configuration. Ceci est fait en utilisant Node.js

Heure de début = 18h30
Heure de fin = 3h30

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

Mon scénario s'étend techniquement sur deux jours et je comprends pourquoi c'est faux.

J'ai besoin (d'attendre) un moment pour retourner TRUE - c'est-à-dire que currentTime isBeteen startTime et endTime et tombe dans cette plage.

Je pensais l'avoir résolu en vérifiant si l'heure endTime est> 12, puis ajoutez un jour pour faire comprendre au moment que c'est le jour suivant. par exemple

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

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

Mais si currentTime est également après minuit, il se casse - par exemple

01h30 ne sera pas pris en compte entre 18h30 et 03h30 - également en raison de jours différents

D'autres suggestions pour accomplir ceci et ignorer simplement le jour/la date ?

J'ai du mal à croire que c'est aussi complexe, mais c'est peut-être :

Voici des précisions supplémentaires sur le problème qui se pose avec les jours qui s'étendent, même en essayant d'être plus explicite :

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

Il semble assez évident qu'ils seraient faux puisque le _day/date_ est considéré par moment. C'est ce que j'essaie de contourner.

Ce qui suit fonctionnerait :

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

Cela signifierait cependant que je devrais vérifier si l'HEURE DE DÉBUT était avant 12h00 && l'ENDTIME après 12h00, puis ajouter 1 jour à ENDTIME.

Tous les 10 commentaires

Habituellement, si vous ne vous souciez pas de la date de fin, il est préférable de simplement suivre explicitement les heures et les minutes, mais bien sûr, je ne sais rien de votre application. Donc, pour y répondre directement, définissez une nouvelle fonction pour renvoyer le nombre de minutes :

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

puis vérifie que :

return minutesOfDay(now) > minutesOfDay(end);

Soit dit en passant, moment() fait la même chose que moment(new Date()) , donc cela devrait vous faire économiser du texte.

Après avoir examiné d'autres questions MomentJS, je ne sais toujours pas comment utiliser le moment pour comparer simplement deux moments différents.

J'ai besoin (vouloir) que le jour/la date soit ignoré.

Cas d'utilisation:
Je lis un calendrier avec des heures de début et de fin à partir d'un fichier de configuration. Ceci est fait en utilisant Node.js

Heure de début = 18h30
Heure de fin = 3h30

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

Mon scénario s'étend techniquement sur deux jours et je comprends pourquoi c'est faux.

J'ai besoin (d'attendre) un moment pour retourner TRUE - c'est-à-dire que currentTime isBeteen startTime et endTime et tombe dans cette plage.

Je pensais l'avoir résolu en vérifiant si l'heure endTime est> 12, puis ajoutez un jour pour faire comprendre au moment que c'est le jour suivant. par exemple

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

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

Mais si currentTime est également après minuit, il se casse - par exemple

01h30 ne sera pas pris en compte entre 18h30 et 03h30 - également en raison de jours différents

D'autres suggestions pour accomplir ceci et ignorer simplement le jour/la date ?

J'ai du mal à croire que c'est aussi complexe, mais c'est peut-être :

Voici des précisions supplémentaires sur le problème qui se pose avec les jours qui s'étendent, même en essayant d'être plus explicite :

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

Il semble assez évident qu'ils seraient faux puisque le _day/date_ est considéré par moment. C'est ce que j'essaie de contourner.

Ce qui suit fonctionnerait :

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

Cela signifierait cependant que je devrais vérifier si l'HEURE DE DÉBUT était avant 12h00 && l'ENDTIME après 12h00, puis ajouter 1 jour à ENDTIME.

Je suppose que je ne comprends pas très bien ce que vous entendez par "ignorer le jour". Si vous comparez ces deux temps

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

d'une manière ou d'une autre, le système doit savoir que vous voulez dire 3h30 _demain_. Je veux dire, comment cela pourrait-il fonctionner? Vous ne pensez sûrement pas qu'en l'absence d'informations sur le jour indiquant que 3h30 est après 18h00 ... Le problème est que vous avez un contexte supplémentaire que Moment n'a pas, à savoir que le endTime devrait être après le startTime ; cela ressort clairement de vos noms de variables, mais Moment ne le sait pas et ne peut pas le savoir. Vous devrez le dire.

Alors que diriez-vous de ceci:

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

Oui, je comprends la confusion. Sans savoir qu'on entend par "3h30" c'est le lendemain c'est délicat.

Sans tenir compte du jour/de la date :
_Si je demande, "il est 23h entre 21h et 3h du matin", je m'attends à ce que la réponse soit vraie .
Si je demande, "c'est 23h entre 3h et 21h", je m'attends à ce que la réponse soit fausse ._

Comme je ne peux pas simplement ignorer la date en utilisant le moment, j'ai commencé à vérifier TOUTES les heures avant/après 12 et je me suis retrouvé avec :

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

Le violon que j'ai ici affiche mes scénarios de cas d'utilisation. J'espère que c'est utile.
https://jsfiddle.net/rfossella/66wjtnvk/1/

Merci encore pour votre temps (sans jeu de mots :-) )

Ou juste quelque chose comme cette fonction :

Mis à jour après la réponse 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

Ainsi, vous pouvez utiliser les méthodes MomentJS isBetween, isAfter, isBefore uniquement avec l'heure et non la date.

Essayer

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

Ce n'est pas un bogue dans Moment, c'est une information manquante dans la documentation selon laquelle le premier paramètre doit être la date la plus ancienne.

Toujours assez perplexe par celui-ci aussi. J'ai dépensé plus que je ne veux l'admettre ! @Machibuse ou @rfossella quelle implémentation a fini par fonctionner ?

J'avais l'habitude d'être coincé avec le même problème, et j'ai finalement trouvé un moyen de le faire fonctionner 👍 temps de formatage en temps militaire, j'espère que cela pourra aider...

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
}

Ensuite, je peux utiliser cette fonction comme ceci:

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 Ça marche très bien, merci !

Salut,
J'ai revérifié le violon que j'ai posté il y a des années et il est toujours actif et fonctionne toujours. FYI: Mon exemple n'introduit pas le temps militaire, au cas où vous en auriez besoin.

Le violon que j'ai ici affiche mes scénarios de cas d'utilisation. J'espère que c'est utile.
https://jsfiddle.net/rfossella/66wjtnvk/1/

Rob

Cette page vous a été utile?
0 / 5 - 0 notes