¿Cómo comparar fechas en Java?

¿Cómo comparo las fechas intermedias en Java?

Ejemplo:

fecha1 es 22-02-2010
date2 es 07-04-2010 hoy
date3 es 25-12-2010

date3 siempre es mayor que date1 y date2 es siempre hoy. ¿Cómo verifico si la fecha de hoy es entre date1 y date 3?

La fecha tiene métodos antes y después y se pueden comparar entre sí de la siguiente manera:

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

Para una comparación inclusiva:

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

También podría darle una oportunidad a Joda-Time , pero tenga en cuenta que:

Joda-Time es la biblioteca de fecha y hora estándar de facto para Java anterior a Java SE 8. Los usuarios ahora deben migrar a java.time ( JSR-310 ).

Los puertos de respaldo están disponibles para Java 6 y 7, así como para Android.

Utilice compareTo :

date1.compareTo(date2);

Los siguientes son la forma más común de comparar fechas. Pero prefiero el primero

Enfoque-1: utilizando Date.before (), Date.after () y 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"); } 

Approach-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"); } 

Approach-3: Calender.before (), Calender.after () y 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"); } 

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

O mejor, si agrega la biblioteca ThreeTen-Extra a su proyecto.

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

Enfoque medio abierto, donde el principio es inclusivo mientras que el final es exclusivo .

Mala elección de formato

Por cierto, esa es una mala elección de formato para una representación de texto de una fecha o valor de fecha y hora. Siempre que sea posible, respete los formatos estándar ISO 8601 . Los formatos ISO 8601 son inequívocos, comprensibles en todas las culturas humanas, y son fáciles de analizar por máquina.

Para un valor de solo fecha, el formato estándar es AAAA-MM-DD. Tenga en cuenta que este formato tiene el beneficio de ser cronológico cuando se ordena alfabéticamente.

LocalDate

La clase LocalDate representa un valor de solo fecha sin hora del día y sin zona horaria.

Un huso horario es crucial para determinar una fecha. Para cualquier momento dado, la fecha varía alrededor del mundo por zona. Por ejemplo, unos minutos después de la medianoche en París, Francia es un nuevo día cuando todavía está “ayer” en Montreal Québec .

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

DateTimeFormatter

Como sus cadenas de entrada son de formato no estándar, debemos definir un patrón de formato para que coincida.

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

Úselo para analizar las cadenas de entrada.

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

En el trabajo de fecha y hora, generalmente es mejor definir un lapso de tiempo por el enfoque de Medio Abierto, donde el comienzo es inclusivo, mientras que el final es exclusivo . Entonces, queremos saber si hoy es igual o más tarde que el comienzo y también antes de la parada. Una forma más breve de decir “es igual o más tarde que el comienzo” es “no antes del inicio”.

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

Consulte la respuesta de gstackoverflow que muestra la lista de métodos de comparación a los que puede llamar.


Acerca de java.time

El marco java.time está integrado en Java 8 y posterior. Estas clases suplantan a las problemáticas antiguas clases heredadas de fecha y hora como java.util.Date , Calendar y SimpleDateFormat .

El proyecto Joda-Time , ahora en modo de mantenimiento , aconseja la migración a las clases java.time .

Para obtener más información, consulte el Tutorial de Oracle . Y busque Stack Overflow para obtener muchos ejemplos y explicaciones. La especificación es JSR 310 .

¿Dónde obtener las clases de java.time?

  • Java SE 8 y SE 9 y posteriores
    • Incorporado.
    • Parte de la API Java estándar con una implementación integrada.
    • Java 9 agrega algunas características y correcciones menores.
  • Java SE 6 y SE 7
    • Gran parte de la funcionalidad de java.time se transfiere a Java 6 y 7 en ThreeTen-Backport .
  • Androide
    • El proyecto ThreeTenABP adapta ThreeTen-Backport (mencionado anteriormente) específicamente para Android.
    • Consulte Cómo utilizar ThreeTenABP ….

El proyecto ThreeTen-Extra amplía java.time con clases adicionales. Este proyecto es un terreno de prueba para posibles adiciones futuras a java.time. Puede encontrar algunas clases útiles aquí, como Interval , YearWeek , YearQuarter y más .


ACTUALIZACIÓN: Esta sección “Joda-Time” a continuación se deja intacta como la historia. El proyecto Joda-Time , ahora en modo de mantenimiento , aconseja la migración a las clases java.time .

Joda-Time

Otras respuestas son correctas con respecto a las clases java.util.Date y java.util.Calendar incluidas. Pero esas clases son notoriamente problemáticas. Así que aquí hay un código de ejemplo usando la biblioteca Joda-Time 2.3.

Si realmente desea una fecha sin una porción de tiempo y sin huso horario, entonces use la clase LocalDate en Joda-Time. Esa clase proporciona métodos de comparación que incluyen compareTo (usado con comparadores Java ), isBefore , isAfter e isEqual .

Entradas …

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

Definir un formateador que describa las cadenas de entrada …

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

Utilice el formateador para analizar las cadenas en objetos 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 ); 

Volcado a la consola …

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

Cuando se ejecuta …

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

Así que vea si el segundo está entre los otros dos (exclusivamente, lo que significa que no es igual a ninguno de los puntos finales) …

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

Trabajando con tramos del tiempo

Si está trabajando con una gran cantidad de tiempo, le sugiero que explore en Joda-Time las clases: Duración , Intervalo y Período . Los métodos como overlap y contains hacen que las comparaciones sean fáciles.

Para las representaciones de texto, observe las normas ISO 8601:

  • duración
    Formato: PnYnMnDTnHnMnS
    Ejemplo: P3Y6M4DT12H30M5S
    (Significa “tres años, seis meses, cuatro días, doce horas, treinta minutos y cinco segundos”)
  • intervalo
    Formato: inicio / fin
    Ejemplo: 2007-03-01T13: 00: 00Z / 2008-05-11T15: 30: 00Z

Las clases Joda-Time pueden funcionar con cadenas en ambos formatos, tanto como entrada (análisis) como salida (generación de cadenas).

Joda-Time realiza comparaciones utilizando el enfoque Half-Open , donde el inicio del tramo es inclusivo, mientras que el final es exclusivo . Este enfoque es acertado para manejar períodos de tiempo. Busque StackOverflow para obtener más información.

Compara las dos fechas:

  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"); 

Actualización para Java 8 y posterior

  • isAfter()
  • isBefore()
  • isEqual()
  • compareTo()

Estos métodos existen en las LocalDate , LocalTime y LocalDateTime .

Esas clases están integradas en Java 8 y posterior. Gran parte de la funcionalidad de java.time se transfiere a Java 6 y 7 en ThreeTen-Backport y se adapta mejor a Android en ThreeTenABP (ver Cómo usar … ).

Puede usar Date.getTime() que:

Devuelve la cantidad de milisegundos desde el 1 de enero de 1970 a las 00:00:00 GMT representada por este objeto Date.

Esto significa que puedes compararlos al igual que los números:

 if (date1.getTime() <= date.getTime() && date.getTime() <= date2.getTime()) { /* * date is between date1 and date2 (both inclusive) */ } /* * when date1 = 2015-01-01 and date2 = 2015-01-10 then * returns true for: * 2015-01-01 * 2015-01-01 00:00:01 * 2015-01-02 * 2015-01-10 * returns false for: * 2014-12-31 23:59:59 * 2015-01-10 00:00:01 * * if one or both dates are exclusive then change <= to < */ 

Use getTime () para obtener el valor numérico de la fecha y luego compare usando los valores devueltos.

Prueba esto

 public static boolean compareDates(String psDate1, String psDate2) throws ParseException{ SimpleDateFormat dateFormat = new SimpleDateFormat ("dd/MM/yyyy"); Date date1 = dateFormat.parse(psDate1); Date date2 = dateFormat.parse(psDate2); if(date2.after(date1)) { return true; } else { return false; } } 

Este código determina hoy está en alguna duración .. basado en la configuración regional de KOREA

  Calendar cstart = Calendar.getInstance(Locale.KOREA); cstart.clear(); cstart.set(startyear, startmonth, startday); Calendar cend = Calendar.getInstance(Locale.KOREA); cend.clear(); cend.set(endyear, endmonth, endday); Calendar c = Calendar.getInstance(Locale.KOREA); if(c.after(cstart) && c.before(cend)) { // today is in startyear/startmonth/startday ~ endyear/endmonth/endday } 

Este método funcionó para mi:

  public static String daysBetween(String day1, String day2) { String daysBetween = ""; SimpleDateFormat myFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); try { Date date1 = myFormat.parse(day1); Date date2 = myFormat.parse(day2); long diff = date2.getTime() - date1.getTime(); daysBetween = ""+(TimeUnit.DAYS.convert(diff, TimeUnit.MILLISECONDS)); } catch (ParseException e) { e.printStackTrace(); } return daysBetween; }