103 votos

¿Cómo comparar dos fechas sin la parte del tiempo?

Me gustaría tener un método compareTo que ignore la porción de tiempo de un java.util.Date. Supongo que hay varias maneras de resolver esto. ¿Cuál es la forma más sencilla?

141voto

Jon Skeet Puntos 692016

Mi preferencia es utilizar Tiempo de Joda que hace que esto sea increíblemente fácil:

DateTime first = ...;
DateTime second = ...;

LocalDate firstDate = first.toLocalDate();
LocalDate secondDate = second.toLocalDate();

return firstDate.compareTo(secondDate);

EDIT: Como se ha señalado en los comentarios, si se utiliza DateTimeComparator.getDateOnlyInstance() es aún más sencillo :)

// TODO: consider extracting the comparator to a field.
return DateTimeComparator.getDateOnlyInstance().compare(first, second);

("Usar el tiempo de Joda" es la base de casi todas las preguntas del SO que preguntan por java.util.Date o java.util.Calendar . Es una API completamente superior. Si estás haciendo cualquier cosa significativo con las fechas/horas, realmente deberías usarlo si puedes).

Si estás absolutamente forzado para utilizar la API incorporada, debe crear una instancia de Calendar con la fecha apropiada y utilizando la zona horaria adecuada. A continuación, podría establecer cada campo en cada calendario de la hora, minuto, segundo y milisegundo a 0, y comparar los tiempos resultantes. Sin embargo, es un poco más complicado que la solución de Joda :)

La parte de la zona horaria es importante: java.util.Date es siempre basado en el UTC. En la mayoría de los casos en los que me ha interesado una fecha, ha sido una fecha en una zona horaria específica . Eso por sí solo te obligará a usar Calendar o Joda Time (a menos que quieras tener en cuenta la zona horaria tú mismo, lo que no recomiendo).

64voto

André Puntos 3224

Apache commons-lang es casi omnipresente. ¿Y qué hay de esto?

if (DateUtils.isSameDay(date1, date2)) {
    // it's same
} else if (date1.before(date2)) {
   // it's before
} else {
   // it's after
}

39voto

Jorn Puntos 5202

Si realmente quieres usar el java.util.Date, harías algo así:

public class TimeIgnoringComparator implements Comparator<Date> {
  public int compare(Date d1, Date d2) {
    if (d1.getYear() != d2.getYear()) 
        return d1.getYear() - d2.getYear();
    if (d1.getMonth() != d2.getMonth()) 
        return d1.getMonth() - d2.getMonth();
    return d1.getDate() - d2.getDate();
  }
}

o, utilizando un Calendario en su lugar (preferible, ya que getYear() y similares están obsoletos)

public class TimeIgnoringComparator implements Comparator<Calendar> {
  public int compare(Calendar c1, Calendar c2) {
    if (c1.get(Calendar.YEAR) != c2.get(Calendar.YEAR)) 
        return c1.get(Calendar.YEAR) - c2.get(Calendar.YEAR);
    if (c1.get(Calendar.MONTH) != c2.get(Calendar.MONTH)) 
        return c1.get(Calendar.MONTH) - c2.get(Calendar.MONTH);
    return c1.get(Calendar.DAY_OF_MONTH) - c2.get(Calendar.DAY_OF_MONTH);
  }
}

29voto

Adamski Puntos 29884

Mi preferencia sería utilizar el Joda biblioteca insetad de java.util.Date directamente, ya que Joda distingue entre fecha y hora (véase AñoMesDía y DateTime clases).

Sin embargo, si desea utilizar java.util.Date Yo sugeriría escribir un método de utilidad; por ejemplo

public static Date setTimeToMidnight(Date date) {
    Calendar calendar = Calendar.getInstance();

    calendar.setTime( date );
    calendar.set(Calendar.HOUR_OF_DAY, 0);
    calendar.set(Calendar.MINUTE, 0);
    calendar.set(Calendar.SECOND, 0);
    calendar.set(Calendar.MILLISECOND, 0);

    return calendar.getTime();
}

13voto

Rob Puntos 3465

¿Alguna opinión sobre esta alternativa?

SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMdd");
sdf.format(date1).equals(sdf.format(date2));

Iteramos.com

Iteramos es una comunidad de desarrolladores que busca expandir el conocimiento de la programación mas allá del inglés.
Tenemos una gran cantidad de contenido, y también puedes hacer tus propias preguntas o resolver las de los demás.

Powered by:

X