Necesito comparar dos Date
s (por ejemplo, date1
y date2
) y llegar a una boolean sameDay
que sea verdadera para las dos Date
s compartidas el mismo día, y falsa si no lo son.
¿Cómo puedo hacer esto? Parece que hay un torbellino de confusión aquí ... y me gustaría evitar atraer otras dependencias más allá del JDK si es posible.
para aclarar: si date1
y date2
comparte el mismo año, mes y día, entonces sameDay
es cierto, de lo contrario es falso. Me doy cuenta de que esto requiere el conocimiento de una zona horaria ... sería bueno pasar en una zona horaria, pero puedo vivir con GMT o la hora local siempre que sepa cuál es el comportamiento.
de nuevo, para aclarar:
date1 = 2008 Jun 03 12:56:03
date2 = 2008 Jun 03 12:59:44
=> sameDate = true
date1 = 2009 Jun 03 12:56:03
date2 = 2008 Jun 03 12:59:44
=> sameDate = false
date1 = 2008 Aug 03 12:00:00
date2 = 2008 Jun 03 12:00:00
=> sameDate = false
Respuestas:
Tenga en cuenta que "el mismo día" no es un concepto tan simple como parece cuando pueden involucrarse diferentes zonas horarias. El código anterior calculará para ambas fechas el día relativo a la zona horaria utilizada por la computadora en la que se está ejecutando. Si esto no es lo que necesita, debe pasar la (s) zona (s) horaria (s) correspondiente (s) a las
Calendar.getInstance()
llamadas, después de haber decidido exactamente qué quiere decir con "el mismo día".Y sí, Joda Time's
LocalDate
haría que todo fuera mucho más limpio y fácil (aunque las mismas dificultades relacionadas con las zonas horarias estarían presentes).fuente
Qué tal si:
También puede establecer la zona horaria en SimpleDateFormat, si es necesario.
fuente
SimpleDateFormat
método es realmente más rápido que el otro mencionado aquí usandoCalendar
s. En promedio, toma la mitad del tiempo que elCalendar
método. (Al menos en mi sistema). ¡Prestigio!Utilizo el paquete "apache commons lang" para hacer esto (es decir, org.apache.commons.lang.time.DateUtils )
fuente
Puede evitar las dependencias externas y el impacto en el rendimiento del uso del Calendario calculando el Número de día juliano para cada una de las fechas y luego comparándolas:
fuente
Date
no encapsulan la noción de zonas horarias, por lo que no hay forma de solucionar esto de manera no arbitraria.Joda-Time
En cuanto a agregar una dependencia, me temo que java.util.Date & .Calendar realmente son tan malos que lo primero que hago a cualquier proyecto nuevo es agregar la biblioteca Joda-Time. En Java 8 puede usar el nuevo paquete java.time, inspirado en Joda-Time.
El núcleo de Joda-Time es la
DateTime
clase. A diferencia de java.util.Date, entiende su zona horaria asignada (DateTimeZone
). Al convertir de juDate, asigne una zona.LocalDate
Una forma de verificar si dos fechas y horas aterrizan en la misma fecha es convertirlas en
LocalDate
objetos.Esa conversión depende de la zona horaria asignada. Para comparar
LocalDate
objetos, deben haberse convertido con la misma zona.Aquí hay un pequeño método de utilidad.
Mejor sería otro argumento, especificando la zona horaria en lugar de asumir que se debe usar la primera zona horaria del objeto DateTime.
Representación de cuerdas
Otro enfoque es crear una representación de cadena de la porción de fecha de cada fecha-hora, luego comparar cadenas.
Nuevamente, la zona horaria asignada es crucial.
Lapso de tiempo
La solución generalizada es definir un período de tiempo, luego preguntar si el período contiene su objetivo. Este código de ejemplo está en Joda-Time 2.4. Tenga en cuenta que las clases relacionadas con la "medianoche" están en desuso. En su lugar, use el
withTimeAtStartOfDay
método. Joda-Time ofrece tres clases para representar un lapso de tiempo de varias maneras: intervalo, período y duración.Usando el enfoque "medio abierto" donde el comienzo del tramo es inclusivo y el final exclusivo.
La zona horaria del objetivo puede ser diferente a la zona horaria del intervalo.
java.time
Java 8 y posterior viene con el framework java.time . Inspirado por Joda-Time, definido por JSR 310, y ampliado por el proyecto ThreeTen-Extra. Ver tutorial .
Los creadores de Joda-Time nos han ordenado a todos que nos traslademos a java.time tan pronto como sea conveniente. Mientras tanto, Joda-Time continúa como un proyecto mantenido activamente. Pero espere que el trabajo futuro ocurra solo en java.time y ThreeTen-Extra en lugar de Joda-Time.
Para resumir java.time en pocas palabras ... Un
Instant
es un momento en la línea de tiempo en UTC. Aplique una zona horaria (ZoneId
) para obtener unZonedDateTime
objeto. Para mover fuera de la línea de tiempo, para tener una idea vaga indefinida de una fecha-hora, utilice las clases "locales":LocalDateTime
,LocalDate
,LocalTime
.La lógica discutida en la sección Joda-Time de esta Respuesta se aplica a java.time.
La antigua clase java.util.Date tiene un nuevo
toInstant
método para la conversión a java.time.Determinar una fecha requiere una zona horaria.
Aplicamos ese objeto de zona horaria
Instant
para obtener aZonedDateTime
. De ahí extraemos un valor de solo fecha (aLocalDate
) ya que nuestro objetivo es comparar fechas (no horas, minutos, etc.).Haga lo mismo con el segundo
java.util.Date
objeto que necesitamos para comparar. Solo usaré el momento actual en su lugar.Use el
isEqual
método especial para probar el mismo valor de fecha.fuente
LocalDate localDate = LocalDate.fromDateFields(yourJavaUtilDate);
fromDateFields()
en miLocalDate
clase .Convierta fechas a Java 8 java.time.LocalDate como se ve aquí .
fuente
ZoneId.of("America/Phoenix")
o enZoneId.of("Europe/Budapest")
lugar de la configuración predeterminada del sistema.Java 8
Si está utilizando Java 8 en su proyecto y está comparando
java.sql.Timestamp
, podría usar laLocalDate
clase:Si está utilizando
java.util.Date
, eche un vistazo a la respuesta de Istvan, que es menos ambigua.fuente
date1
ydate2
estásjava.sql.Timestamp
? Según la pregunta que sonDate
, lo entenderíajava.util.Date
. Además, su código utiliza la configuración de zona horaria de la computadora, que para muchos propósitos estará bien; aun así, preferiría hacer explícito este hecho en el código.java.sql.Timestamp
. Como dijiste, generalmente es mejor establecer explícitamente la zona horaria.fuente
PARA USUARIOS DE ANDROID:
Puede usar
DateUtils.isToday(dateMilliseconds)
para verificar si la fecha dada es el día actual o no.Referencia API: https://developer.android.com/reference/android/text/format/DateUtils.html#isToday(long)
fuente
DateUtils.isToday(x.getTime())
(x es una instancia de java.util.date) serviráAdemás de la solución Binil Thomas
uso
fuente
Para los desarrolladores de Kotlin, esta es la versión con enfoque de comparación de cadenas formateadas:
No es la mejor manera, pero es corta y funciona.
fuente
SimpleDateFormat
clase fue suplantada hace años por lajava.time.DateTimeFormatter
clase moderna definida en JSR 310. Sugerir su uso en 2019 es un mal consejo.puede aplicar la misma lógica que la solución SimpleDateFormat sin depender de SimpleDateFormat
fuente