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?
Respuestas
¿Demasiados anuncios?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).
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
}
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);
}
}
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();
}