117 votes

Comment puis-je déterminer si une date est comprise entre deux dates en Java ?

Comment puis-je vérifier si une date est comprise entre deux autres dates, dans le cas où les trois dates sont représentées par des instances de java.util.Date ?

289voto

Nathan Feger Points 7675

Cela pourrait être un peu plus lisible :

Date min, max;   // assume these are set to something
Date d;          // the date in question

return d.after(min) && d.before(max);

3 votes

9 secondes plus vite, monsieur.

78 votes

Entre peut inclure les points d'extrémité, auquel cas vous pourriez utiliser return !d.before(min) && !d.after(max) ;

1 votes

@Tetsujin no Oni désolé mec, c'est une bonne chose que je n'ai pas un gros livrable à rendre dans quelques semaines qui est à la fois aidé et blessé par SO. :)

150voto

Peter Lawrey Points 229686

Si vous ne connaissez pas l'ordre des valeurs min/max

Date a, b;   // assume these are set to something
Date d;      // the date in question

return a.compareTo(d) * d.compareTo(b) > 0;

Si vous voulez que la gamme soit inclusive

return a.compareTo(d) * d.compareTo(b) >= 0;

Vous pouvez traiter null comme non contraint avec

if (a == null) {
    return b == null || d.compareTo(b) < 0;
} else if (b == null) {
    return a.compareTo(d) < 0;
} else {
    return a.compareTo(d) * d.compareTo(b) > 0;
}

40 votes

Fonctionne, mais n'est pas lisible. Merci quand même.

1 votes

@BrunoDeFreitasBarros Que voulez-vous dire par "pas lisible" ?

5 votes

@Peter Lawrey Bruno veut dire qu'il est difficile de comprendre le code sans commentaire.

50voto

Jason Cohen Points 36475

Comme ça :

Date min, max;   // assume these are set to something
Date d;          // the date in question

return d.compareTo(min) >= 0 && d.compareTo(max) <= 0;

Vous pouvez utiliser > au lieu de >= y < au lieu de <= pour exclure les points d'extrémité du sens de "entre".

0 votes

Merci pour votre réponse immédiate.

1 votes

Cela ne fonctionne pas toujours. J'ai eu des problèmes en utilisant compareTo sur des objets Date. Le 1er janvier 2006 était apparemment postérieur au 1er avril 2006 dans un de mes programmes.

0 votes

@KitsuneYMG : J'ai essayé le code suivant et il fonctionne comme prévu : Date date1 = new Date(2006, 1, 1); // Jan 1,2006 Date date2 = new Date(2006, 4, 1); // Apr 1, 2006 System.out.println(date1.compareTo(date2)); // -1 System.out.println(date2.compareTo(date1)); // 1 . Pouvez-vous nous dire ce que c'est ne fonctionne pas pour vous ?

12voto

Basil Bourque Points 8938

Voici quelques façons d'y parvenir en utilisant la fonction Joda-Time 2.3 bibliothèque.

Une façon de procéder est d'utiliser la simple isBefore y isAfter méthodes sur DateTime instances. À propos, le concept de DateTime dans Joda-Time est similaire à celui de java.util.Date (un moment dans le temps sur la ligne de temps de l'Univers) mais inclut un fuseau horaire.

Une autre façon est de construire un intervalle dans Joda-Time. Le site contains teste si une DateTime donnée se produit dans l'intervalle de temps couvert par l'Intervalle. Le début de l'intervalle est inclusif, mais le point final est exclusif. Cette approche est connue sous le nom de "semi-ouvert", symboliquement [) .

Vous pouvez voir les deux façons dans l'exemple de code suivant.

Convertir les instances de java.util.Date en Joda-Time DateTime instances. Il suffit de passer l'instance Date au constructeur de DateTime. En pratique, vous devez également passer une instance DateTimeZone plutôt que de se fier au fuseau horaire par défaut de la JVM.

DateTime dateTime1 = new DateTime( new java.util.Date() ).minusWeeks( 1 );
DateTime dateTime2 = new DateTime( new java.util.Date() );
DateTime dateTime3 = new DateTime( new java.util.Date() ).plusWeeks( 1 );

Comparez en testant avant/après

boolean is1After2 = dateTime1.isAfter( dateTime2 );
boolean is2Before3 = dateTime2.isBefore( dateTime3 );

boolean is2Between1And3 = ( ( dateTime2.isAfter( dateTime1 ) ) && ( dateTime2.isBefore( dateTime3 ) ) );

Utiliser l'approche par intervalles au lieu de isAfter/isBefore

Interval interval = new Interval( dateTime1, dateTime3 );
boolean intervalContainsDateTime2 = interval.contains( dateTime2 );

Dump à la console

System.out.println( "DateTimes: " + dateTime1 + " " + dateTime1 + " " + dateTime1 );
System.out.println( "is1After2 " + is1After2 );
System.out.println( "is2Before3 " + is2Before3 );
System.out.println( "is2Between1And3 " + is2Between1And3 );
System.out.println( "intervalContainsDateTime2 " + intervalContainsDateTime2 );

Quand on court

DateTimes: 2014-01-22T20:26:14.955-08:00 2014-01-22T20:26:14.955-08:00 2014-01-22T20:26:14.955-08:00
is1After2 false
is2Before3 true
is2Between1And3 true
intervalContainsDateTime2 true

10voto

David Points 871

Une autre option

min.getTime() <= d.getTime() && d.getTime() <= max.getTime()

0 votes

C'est la seule solution optimale, les autres semblent trop compliquées pour quelque chose de simple.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X