451 votes

Comment comparer des dates en Java ?

Comment comparer des dates intermédiaires en Java ?

Exemple :

date1 est 22-02-2010
date2 est 07-04-2010 aujourd'hui
date3 est 25-12-2010

date3 est toujours supérieure à date1 et date2 est toujours aujourd'hui. Comment puis-je vérifier si la date d'aujourd'hui se situe entre la date 1 et la date 3 ?

691voto

Bart Kiers Points 79069

Date a avant et après et peuvent être comparés les uns aux autres comme suit :

if(todayDate.after(historyDate) && todayDate.before(futureDate)) {
    // In between
}

Pour une comparaison inclusive :

if(!historyDate.after(todayDate) && !futureDate.before(todayDate)) {
    /* historyDate <= todayDate <= futureDate */ 
}

Vous pouvez également donner Joda-Time un aller, mais notez que :

Joda-Time est le de facto Les utilisateurs sont maintenant invités à migrer vers la bibliothèque de date et d'heure standard pour Java avant Java SE 8. java.time ( JSR-310 ).

Des rétro-ports sont disponibles pour Java 6 et 7 ainsi que pour Android.

10 votes

Est-ce inclusif, ou exclusif pour les frontières ?

1 votes

@DanielHári non, ce n'est pas inclusif. Vous pouvez utiliser la solution proposée dans le premier commentaire, ou utiliser CompareTo()>=0 .

0 votes

La norme est généralement "gauche inclusif, droite exclusif", c'est pourquoi je pense que cela devrait être spécifié exactement. Avec les frontières "left inclusive, right exclusive", vous pouvez facilement spécifier fe : un intervalle de mois : [2016/04/01, 2016/05/01], c'est pourquoi c'est la norme et utilisé par défaut dans de nombreux cas d'utilisation.

147voto

Chandru Points 4770

Utilisez compareTo :

date1.compareTo(date2);

0 votes

Fonctionne parfaitement avec Date, Byte, Long, Integer...

1 votes

Parfois, ça ne marche pas. J'ai déclenché plusieurs fois l'utilisation dans une méthode principale pour vérifier l'égalité. La plupart du temps, il y a égalité, mais pas tout le temps.

0 votes

@Syed Pouvez-vous partager votre code ?

133voto

Sunil Kumar Sahoo Points 21032

Voici les méthodes de comparaison les plus courantes dates (ma préférence va à Approche 1 ) :

Approche 1 : utiliser Date.before() , Date.after() et Date.equals( )

if (date1.after(date2)) {
    System.out.println("Date1 is after Date2");
}

if (date1.before(date2)) {
    System.out.println("Date1 is before Date2");
}

if (date1.equals(date2)) {
    System.out.println("Date1 is equal Date2");
}

Approche 2 : Date.compareTo()

if (date1.compareTo(date2) > 0) {
    System.out.println("Date1 is after Date2");
} else if (date1.compareTo(date2) < 0) {
    System.out.println("Date1 is before Date2");
} else {
    System.out.println("Date1 is equal to Date2");
}

Approche 3 : Calender.before() , Calender.after( ) et Calender.equals()

Calendar cal1 = Calendar.getInstance();
Calendar cal2 = Calendar.getInstance();
cal1.setTime(date1);
cal2.setTime(date2);

if (cal1.after(cal2)) {
    System.out.println("Date1 is after Date2");
}

if (cal1.before(cal2)) {
    System.out.println("Date1 is before Date2");
}

if (cal1.equals(cal2)) {
    System.out.println("Date1 is equal Date2");
}

0 votes

Pour votre information, les anciennes classes de date-heure gênantes telles que java.util.Date , java.util.Calendar et java.text.SimpleDateFormat sont maintenant héritage supprimé par le java.time intégrées dans Java 8 et Java 9. Voir Tutoriel par Oracle .

43voto

Basil Bourque Points 8938

Tl;dr

LocalDate today = LocalDate.now( ZoneId.of( "America/Montreal" ) ) ;
Boolean isBetween = 
    ( ! today.isBefore( localDate1 ) )  // “not-before” is short for “is-equal-to or later-than”.
    &&
    today.isBefore( localDate3 ) ; 

Ou, mieux, si vous ajoutez le Trois-Dix-Extra à votre projet.

LocalDateRange.of(
    LocalDate.of( … ) ,
    LocalDate.of( … )
).contains(
    LocalDate.now()
)

Approche semi-ouverte, où le début est inclusivement alors que la fin est exclusif .

Mauvais choix de format

À propos, c'est un mauvais choix de format pour la représentation textuelle d'une valeur de date ou d'heure. Dans la mesure du possible, utilisez le format standard ISO 8601 les formats. Les formats ISO 8601 sont sans ambiguïté, compréhensibles par toutes les cultures humaines et faciles à analyser par une machine.

Pour une valeur de type date uniquement, le format standard est YYYY-MM-DD. Notez que ce format a l'avantage d'être chronologique lorsqu'il est trié par ordre alphabétique.

LocalDate

Le site LocalDate représente une valeur de date uniquement, sans heure du jour et sans fuseau horaire.

Le fuseau horaire est crucial pour déterminer une date. Pour un moment donné, la date varie selon les zones du globe. Par exemple, quelques minutes après minuit en France, le jour de la fête du travail est le jour de la fête du travail. Paris France est un nouveau jour alors qu'il est encore "hier" dans le monde. Montréal Québec .

ZoneId z = ZoneId.of( "America/Montreal" );
LocalDate today = LocalDate.now( z );

Table of all date-time types in Java, both modern and legacy

DateTimeFormatter

Comme vos chaînes d'entrée ont un format non standard, nous devons définir un modèle de formatage à faire correspondre.

DateTimeFormatter f = DateTimeFormatter.ofPattern( "dd-MM-uuuu" );

Utilisez-le pour analyser les chaînes d'entrée.

LocalDate start = LocalDate.parse( "22-02-2010" , f );
LocalDate stop = LocalDate.parse( "25-12-2010" , f );

Dans le cadre d'un travail sur la date et l'heure, il est généralement préférable de définir une période de temps par l'approche de la demi-ouverture, où le début est le suivant inclusivement alors que la fin est exclusif . Nous voulons donc savoir si aujourd'hui est identique ou postérieur au début et aussi avant l'arrêt. Une façon plus brève de dire "est le même ou plus tard que le début" est "pas avant le début".

Boolean intervalContainsToday = ( ! today.isBefore( start ) ) && today.isBefore( stop ) ;

Voir la réponse de gstackoverflow montrant la liste des méthodes de comparaison que vous pouvez appeler.


À propos de java.time

Le site java.time est intégré à Java 8 et aux versions ultérieures. Ces classes remplacent les anciennes classes héritage les classes de date et d'heure telles que java.util.Date , Calendar , & SimpleDateFormat .

Pour en savoir plus, consultez le Tutoriel Oracle . Et recherchez sur Stack Overflow de nombreux exemples et explications. La spécification est JSR 310 .

Le site Joda-Time Le projet, actuellement en mode de maintenance conseille la migration vers le java.time classes.

Vous pouvez échanger java.time directement avec votre base de données. Utilisez un Pilote JDBC conforme à JDBC 4.2 ou plus tard. Pas besoin de ficelles, pas besoin de java.sql.* classes. Support de Hibernate 5 et JPA 2.2 java.time .

Où obtenir les classes java.time ?

Le site Trois-Dix-Extra Le projet étend java.time avec des classes supplémentaires. Ce projet est un terrain d'essai pour d'éventuels ajouts futurs à java.time. Vous pouvez y trouver des classes utiles telles que Interval , YearWeek , YearQuarter et plus .


UPDATE : Cette section "Joda-Time" ci-dessous est laissée intacte en tant qu'histoire. Le site Joda-Time Le projet, actuellement en mode de maintenance conseille la migration vers le java.time classes.

Joda-Time

Les autres réponses sont correctes en ce qui concerne les classes groupées java.util.Date et java.util.Calendar. Mais ces classes sont notoirement difficiles à utiliser. Voici donc un exemple de code utilisant la classe Joda-Time 2.3 bibliothèque.

Si vous voulez vraiment une date sans portion de temps et sans fuseau horaire, utilisez alors la fonction LocalDate dans Joda-Time. Cette classe fournit des méthodes de comparaison, notamment compareTo (utilisé avec Comparateurs Java ), isBefore , isAfter et isEqual .

Entrées

String string1 = "22-02-2010";
String string2 = "07-04-2010";
String string3 = "25-12-2010";

Définir un formateur décrivant les chaînes d'entrée

DateTimeFormatter formatter = DateTimeFormat.forPattern( "dd-MM-yyyy" );

Utilisez le formateur pour analyser les chaînes de caractères en objets LocalDate

LocalDate localDate1 = formatter.parseLocalDate( string1 );
LocalDate localDate2 = formatter.parseLocalDate( string2 );
LocalDate localDate3 = formatter.parseLocalDate( string3 );

boolean is1After2 = localDate1.isAfter( localDate2 );
boolean is2Before3 = localDate2.isBefore( localDate3 );

Dump à la console

System.out.println( "Dates: " + localDate1 + " " + localDate2 + " " + localDate3 );
System.out.println( "is1After2 " + is1After2 );
System.out.println( "is2Before3 " + is2Before3 );

Quand on court

Dates: 2010-02-22 2010-04-07 2010-12-25
is1After2 false
is2Before3 true

Alors, voyez si le second se situe entre les deux autres (exclusivement, c'est-à-dire non égal à l'une ou l'autre des extrémités)

boolean is2Between1And3 = ( ( localDate2.isAfter( localDate1 ) ) && ( localDate2.isBefore( localDate3 ) ) );

Travailler avec des périodes de temps

Si vous travaillez avec des périodes de temps, je vous suggère d'explorer les classes de Joda-Time : Durée , Intervalle et Période . Des méthodes telles que overlap et contains faciliter les comparaisons.

Pour les représentations textuelles, regardez celles de la norme ISO 8601 :

  • durée
    Format : PnYnMnDTnHnMnS
    Exemple : P3Y6M4DT12H30M5S
    (Signifie "trois ans, six mois, quatre jours, douze heures, trente minutes et cinq secondes")
  • intervalle
    Format : début/fin
    Example: 2007-03-01T13:00:00Z/2008-05-11T15:30:00Z

Les classes Joda-Time peuvent travailler avec des chaînes de caractères dans ces deux formats, à la fois en entrée (analyse syntaxique) et en sortie (génération de chaînes de caractères).

Joda-Time effectue les comparaisons en utilisant la fonction Demi-ouvert approche où le début de la portée est inclusivement alors que la fin est exclusif . Cette approche est judicieuse pour gérer les périodes de temps. Recherchez StackOverflow pour plus d'informations.

0 votes

Cette réponse doit figurer en tête de toutes les autres réponses.

23voto

sam Points 158

Comparez les deux dates :

  Date today = new Date();                   
  Date myDate = new Date(today.getYear(),today.getMonth()-1,today.getDay());
  System.out.println("My Date is"+myDate);    
  System.out.println("Today Date is"+today);
  if (today.compareTo(myDate)<0)
      System.out.println("Today Date is Lesser than my Date");
  else if (today.compareTo(myDate)>0)
      System.out.println("Today Date is Greater than my date"); 
  else
      System.out.println("Both Dates are equal");

6 votes

Je pense que "new Date(today.getYear(),today.getMonth()-1,today.getDay()) ;" est obsolète. download.oracle.com/javase/6/docs/api/java/util/Date.html

0 votes

@Muath : Bien que je ne sois pas sûr à 100 %, je pense que c'est parce que le composant mois dans Date est indexé à zéro.

0 votes

Je pense que dans cette autre partie ne fonctionne pas :)

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