¿Cómo comparar dos fechas sin la porción de tiempo?

203

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

Arne Evertsson
fuente

Respuestas:

212

Actualización: aunque Joda Time era una buena recomendación en ese momento, use la java.timebiblioteca de Java 8+ en su lugar siempre que sea posible.


Mi preferencia es usar Joda Time, lo 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);

EDITAR: Como se señaló en los comentarios, si lo usa DateTimeComparator.getDateOnlyInstance()es aún más simple :)

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

("Use Joda Time" es la base de casi todas las preguntas SO sobre las que se pregunta java.util.Dateo java.util.Calendar. Es una API completamente superior. Si está haciendo algo significativo con las fechas / horas, realmente debería usarlo si es posible).

Si se ve obligado a usar la API integrada, debe crear una instancia Calendarcon la fecha adecuada y con la zona horaria adecuada. Luego, puede establecer cada campo en cada calendario fuera de la hora, minuto, segundo y milisegundo a 0, y comparar los tiempos resultantes. Definitivamente asqueroso en comparación con la solución de Joda :)

La zona horaria parte es importante: java.util.Datees siempre basada en UTC. En la mayoría de los casos en los que he estado interesado en una fecha, esa ha sido una fecha en una zona horaria específica . Eso por sí solo te obligará a usarCalendar o Joda Time (a menos que desee contabilizar la zona horaria usted mismo, lo que no recomiendo).

Referencia rápida para desarrolladores de Android

//Add joda library dependency to your build.gradle file
dependencies {
     ...
     implementation 'joda-time:joda-time:2.9.9'
}

Código de muestra (ejemplo)

DateTimeComparator dateTimeComparator = DateTimeComparator.getDateOnlyInstance();

Date myDateOne = ...;
Date myDateTwo = ...;

int retVal = dateTimeComparator.compare(myDateOne, myDateTwo);

if(retVal == 0)
   //both dates are equal
else if(retVal < 0)
   //myDateOne is before myDateTwo
else if(retVal > 0)
   //myDateOne is after myDateTwo
Jon Skeet
fuente
28
Aunque Jon dice "Use Joda Time" es la base de casi todas las preguntas SO que se refieren a java.util.Date o java.util.Calendar Siempre pienso que, en primer lugar, es mejor dar una respuesta concreta basada en la pregunta del usuario, en menos para mostrar lo difícil que puede ser hacer Java. Y después de eso sugiriendo usar Joda ...
JuanZe
13
@JuanZe: Eso requiere resolver exactamente cómo hacer algo correctamente en una API dolorosa, que por definición es dolorosa. Prefiero pasar ese tiempo haciendo algo más productivo :)
Jon Skeet
1
@ MetroidFan2002: LocalDate es una mejor opción que DateMidnight, ya que es más expresivo, y no todos los días tienen medianoche ...
Jon Skeet
2
@dertoni: Claro, en Brasil, cuando los relojes se adelantan debido al horario de verano, eso sucede al comienzo del día ... por lo que un reloj leería 23:59:58, 23:59:59, 01:00 : 00, 01:00:01 etc.
Jon Skeet
8
¿No sería mejor usar DateTimeComparator.getDateOnlyInstance ()
Emil
125

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
}
André
fuente
La versión 2.6 incluye una función truncatedCompareTo commons.apache.org/proper/commons-lang/javadocs/api-2.6/org/…
usuario de linux shonky
2
Lamentablemente no tolera fechas nulas
Pavel Niedoba
Chicos, hoy en día tenemos Java 8 stackoverflow.com/a/35411693/259237
André
No recomiendo el uso de antes de esta manera porque si el primer o el segundo objeto Fecha fue donado desde Timestamp y tiene miles de segundos, y el otro es un objeto Fecha normal, tendrá problemas porque, Fecha de la tienda de fecha y hora en una parte diferente de objeto, los milisegundos dan diferencias incluso cuando ambas fechas son iguales.
Zini
Desafortunadamente, Apache no está en más de 1.3 billones de dispositivos Android, y es una gran biblioteca de la que depender para un solo caso de uso. Necesitaré algo más: /
milosmns
58

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

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, usando un calendario en su lugar (preferido, ya que getYear () y tales están en desuso)

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);
  }
}
Jorn
fuente
1
En el segundo método, olvidó actualizar algunas de sus referencias, de d1, d2 a c1, c2.
stivlo
1
Después de corregir ese detalle, su código funciona bien: lo he probado exhaustivamente. Agregué el paso para crear un calendario a partir de las fechas y usé su código en mi proyecto github recién creado org.obliquid.helpers , gracias.
stivlo
Dulce, buena solución sin usar ninguna biblioteca externa.
4gus71n
1
Todos estos métodos están en desuso. ¿Puede esto tener algún tipo de impacto?
Pranav Mahajan
36

Preferiría usar la biblioteca Joda insetad de java.util.Datedirectamente, ya que Joda hace una distinción entre fecha y hora (vea las clases YearMonthDay y DateTime ).

Sin embargo, si desea utilizarlo java.util.Date, le sugiero que escriba un método de utilidad; p.ej

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();
}
Adamski
fuente
1
Joda-Time YearMonthDay está en desuso a favor de LocalDate. Además, el código en el calendario tendrá problemas si la zona horaria no tiene medianoche 00:00 debido al horario de verano.
JodaStephen
1
Esto no funciona el 100% del tiempo. Tuve un caso de uso donde hice eso y el calendar.getTime () aún devolvería la hora con las horas establecidas como la fecha del parámetro. Lo mejor es borrar los campos y establecer solo los de año, mes y día.
Jonathan Drapeau el
31

¿Alguna opinión sobre esta alternativa?

SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMdd");
sdf.format(date1).equals(sdf.format(date2));
Robert Brown
fuente
1
No creo que eso funcione, incluso si convertir a Strings fuera una buena idea. El ==operador no necesariamente devuelve truecadenas equivalentes (uso equals()). Ciertamente, tampoco puede usar los otros operadores de comparación que mencionó.
Harto
1
Ah, sí, ¡mi rubí está arruinando mi Java! Podría convertir las cadenas en ints para <,> etc.
Robert Brown
Usar Joda es la forma de sonido, ¡pero esto es elegante!
Arne Evertsson
Esto no funcionará para todos, pero es muy simple y liviano; Una buena alternativa cuando otras librerías no están disponibles.
Jacob Marble
Para obtener el orden de las fechas, también puede usar sdf.format(date1).compareTo(sdf.format(date2));.
Ole VV
18

Si desea comparar solo el mes, día y año de dos fechas, el siguiente código funciona para mí:

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

Gracias Rob

Dellanio
fuente
13

Yo también prefiero Joda Time , pero aquí hay una alternativa:

long oneDay = 24 * 60 * 60 * 1000
long d1 = first.getTime() / oneDay
long d2 = second.getTime() / oneDay
d1 == d2

EDITAR

Puse la cosa UTC a continuación en caso de que necesite comparar fechas para una zona horaria específica que no sea UTC. Sin embargo, si tienes esa necesidad, te aconsejo que vayas por Joda.

long oneDay = 24 * 60 * 60 * 1000
long hoursFromUTC = -4 * 60 * 60 * 1000 // EST with Daylight Time Savings
long d1 = (first.getTime() + hoursFromUTC) / oneDay
long d2 = (second.getTime() + hoursFromUTC) / oneDay
d1 == d2
Daniel C. Sobral
fuente
Dije que preferiría usar Joda Time, pero ese es un buen punto. Solo recurro a tácticas tan bajas cuando no estoy realmente interesado en la TZ.
Daniel C. Sobral
Se puede evitar la división:Math.abs(second.getTime() - first.getTime()) < 1000L*60*60*24
Vadzim
@Vadzim Hazlo < oneDay.
Daniel C. Sobral
2
@Vadzim, eso solo verifica si las fechas tienen menos de 1 día de diferencia. No significa necesariamente que estén en el mismo día.
Arahant
@arahant, sí. Esto puede ser suficiente cuando la segunda fecha siempre está alineada a medianoche.
Vadzim
12

tl; dr

myJavaUtilDate1.toInstant()
               .atZone( ZoneId.of( "America/Montreal" ) )
               .toLocalDate()
               .isEqual (
                   myJavaUtilDate2.toInstant()
                                  .atZone( ZoneId.of( "America/Montreal" ) )
                                  .toLocalDate()
               )

Evite las clases de fecha y hora heredadas

Evite las viejas clases problemáticas de fecha y hora heredadas como Date&Calendar , ahora suplantadas por las clases java.time.

Usando java.time

A java.util.Daterepresenta un momento en la línea de tiempo en UTC. El equivalente en java.time es Instant. Puede convertir utilizando nuevos métodos agregados a la clase heredada.

Instant instant1 = myJavaUtilDate1.toInstant();
Instant instant2 = myJavaUtilDate2.toInstant();

Quieres comparar por fecha. Una zona horaria es crucial para determinar una fecha. Para cualquier momento dado, la fecha varía en todo el mundo por zona. Por ejemplo, unos minutos después de la medianoche en París, Francia es un nuevo día mientras todavía "ayer" en Montreal Québec .

Especificar un nombre de zona horaria correcta en el formato de continent/region, por ejemplo America/Montreal, Africa/Casablancao Pacific/Auckland. Nunca use el 3-4 abreviatura de letras tales como ESTo IST, ya que son no verdaderas zonas de tiempo, no estandarizados, y ni siquiera único (!).

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

Aplica el ZoneIdpara Instantobtener un ZonedDateTime.

ZonedDateTime zdt1 = instant1.atZone( z );
ZonedDateTime zdt2 = instant2.atZone( z );

La LocalDateclase representa un valor de solo fecha sin hora del día y sin zona horaria. Podemos extraer a LocalDatede a ZonedDateTime, eliminando efectivamente la parte de la hora del día.

LocalDate localDate1 = zdt1.toLocalDate();
LocalDate localDate2 = zdt2.toLocalDate();

Ahora comparar, utilizando métodos tales como isEqual, isBefore, y isAfter.

Boolean sameDate = localDate1.isEqual( localDate2 );

Vea este código en vivo en IdeOne.com .

instant1: 2017-03-25T04: 13: 10.971Z | instant2: 2017-03-24T22: 13: 10.972Z

zdt1: 2017-03-25T00: 13: 10.971-04: 00 [América / Montreal] | zdt2: 2017-03-24T18: 13: 10.972-04: 00 [América / Montreal]

localDate1: 2017-03-25 | localDate2: 2017-03-24

sameDate: false


Sobre java.time

El marco java.time está integrado en Java 8 y posterior. Estas clases suplantar la vieja problemáticos heredados clases de fecha y hora como java.util.Date, Calendar, ySimpleDateFormat .

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 java.time?

El proyecto ThreeTen-Extra extiende java.time con clases adicionales. Este proyecto es un campo de pruebas para posibles adiciones futuras a java.time. Usted puede encontrar algunas clases útiles aquí, como Interval, YearWeek, YearQuarter, y más .

Albahaca Bourque
fuente
7

Ya mencioné apache commons-utils :

org.apache.commons.lang.time.DateUtils.truncate(date, Calendar.DAY_OF_MONTH)

le da un objeto Fecha que contiene solo fecha, sin hora, y puede compararlo con Date.compareTo

Marinero danubiano
fuente
6

Me temo que no hay un método para comparar dos fechas que podrían llamarse "fácil" o "simple".

Al comparar dos instancias de tiempo con cualquier tipo de precisión reducida (por ejemplo, solo comparar fechas), siempre debe tener en cuenta cómo la zona horaria afecta la comparación.

Si date1está especificando un evento que ocurrió en la zona horaria +2 y date2está especificando un evento que ocurrió en EST, por ejemplo, debe tener cuidado para comprender adecuadamente las implicaciones de la comparación.

¿Su propósito es determinar si los dos eventos ocurrieron en la misma fecha del calendario en sus propias zonas horarias respectivas? ¿O necesita saber si las dos fechas caen en la misma fecha del calendario en una zona horaria específica (UTC o su TZ local, por ejemplo).

Una vez que descubres qué es lo que realmente estás tratando de comparar, solo es cuestión de obtener el triple de la fecha año-mes en una zona horaria apropiada y hacer la comparación.

El tiempo de Joda puede hacer que la operación de comparación real parezca mucho más limpia, pero la semántica de la comparación sigue siendo algo que debe descubrir usted mismo.

Roland Tepp
fuente
5

Si solo desea comparar dos fechas sin tiempo, el siguiente código podría ayudarlo:

final SimpleDateFormat dateFormat = new SimpleDateFormat("yyyyMMdd");
Date dLastUpdateDate = dateFormat.parse(20111116);
Date dCurrentDate = dateFormat.parse(dateFormat.format(new Date()));
if (dCurrentDate.after(dLastUpdateDate))
{
   add your logic
}
Pritesh Shah
fuente
Eso es lo mismo que la respuesta de Rob . Creo que la solución de Jorn es mejor, ya que no implica un viaje de ida y vuelta a las cuerdas y debería lograr lo mismo.
Rup
4

Aquí hay una solución de este blog: http://brigitzblog.blogspot.com/2011/10/java-compare-dates.html

long milliseconds1 = calendar1.getTimeInMillis();
long milliseconds2 = calendar2.getTimeInMillis();
long diff = milliseconds2 - milliseconds1;
long diffDays = diff / (24 * 60 * 60 * 1000);
System.out.println("Time in days: " + diffDays  + " days.");

es decir, puede ver si la diferencia horaria en milisegundos es menor que la duración de un día.

wilbert
fuente
44
Esa muestra verificará si las dos fechas están dentro de las 24 horas una de la otra, pero no necesariamente si ambas están en la misma fecha, es decir, es posible abarcar una medianoche. Mejor sería dividir ambos conjuntos de millis entre MILLIS_IN_DAY y comparar el resultado, pero eso solo será exacto para las horas UTC no locales.
Rup
4

``

SimpleDateFormat sdf= new SimpleDateFormat("MM/dd/yyyy")

   Date date1=sdf.parse("03/25/2015");



  Date currentDate= sdf.parse(sdf.format(new Date()));

   return date1.compareTo(currentDate);

``

zakir
fuente
3

No sé si es nuevo pensar o de lo contrario, pero te muestro como lo hice

SimpleDateFormat dtf = new SimpleDateFormat("dd/MM/yyyy");
Date td_date = new Date();
String first_date = dtf.format(td_date);    //First seted in String 
String second_date = "30/11/2020";          //Second date you can set hear in String

String result = (first_date.equals(second_date)) ? "Yes, Its Equals":"No, It is not Equals";
System.out.println(result);
13hola
fuente
3

Simplemente marque DAY_OF_YEAR en combinación con la propiedad YEAR

boolean isSameDay = 
firstCal.get(Calendar.YEAR) == secondCal.get(Calendar.YEAR) &&
firstCal.get(Calendar.DAY_OF_YEAR) == secondCal.get(Calendar.DAY_OF_YEAR)

EDITAR:

Ahora podemos usar el poder de las funciones de extensión de Kotlin

fun Calendar.isSameDay(second: Calendar): Boolean {

    return this[Calendar.YEAR] == second[Calendar.YEAR] && this[Calendar.DAY_OF_YEAR] == second[Calendar.DAY_OF_YEAR]
}

fun Calendar.compareDatesOnly(other: Calendar): Int {

    return when {
        isSameDay(other) -> 0
        before(other) -> -1
        else -> 1
    }
}
Simon K. Gerges
fuente
Está mal porque las fechas con años diferentes pueden tener el mismo día del año, por ejemplo, 2015-01-01 y 2016-01-01.
nelson eldoro
@nelsoneldoro gracias por tu comentario, olvidé agregar un cheque para el año, ahora debería estar bien.
Simon K. Gerges
2

En Java 8 puede usar LocalDate, que es muy similar al de Joda Time.

habsq
fuente
2
public Date saveDateWithoutTime(Date date) {
    Calendar calendar = Calendar.getInstance();

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

    return calendar.getTime();
}

Esto lo ayudará a comparar fechas sin tener en cuenta la hora.

Km de Fathima
fuente
1

Usando getDateInstance de SimpleDateFormat, podemos comparar solo dos objetos de fecha sin tiempo. Ejecute el siguiente código.

public static void main(String[] args) {        
        Date date1  = new Date();
        Date date2  = new Date();
        DateFormat dfg = SimpleDateFormat.getDateInstance(DateFormat.DATE_FIELD);
        String dateDtr1 = dfg.format(date1);
        String dateDtr2 = dfg.format(date2);
        System.out.println(dateDtr1+" : "+dateDtr2);
        System.out.println(dateDtr1.equals(dateDtr2));  

    }
Senthil Eswaramoorthy
fuente
1

Otro método simple de comparación basado en las respuestas aquí y mi guía de mentor

public static int compare(Date d1, Date d2) {
    Calendar c1 = Calendar.getInstance();
    Calendar c2 = Calendar.getInstance();
    c1.setTime(d1);
    c1.set(Calendar.MILLISECOND, 0);
    c1.set(Calendar.SECOND, 0);
    c1.set(Calendar.MINUTE, 0);
    c1.set(Calendar.HOUR_OF_DAY, 0);
    c2.setTime(d2);
    c2.set(Calendar.MILLISECOND, 0);
    c2.set(Calendar.SECOND, 0);
    c2.set(Calendar.MINUTE, 0);
    c2.set(Calendar.HOUR_OF_DAY, 0);
    return c1.getTime().compareTo(c2.getTime());
  }

EDITAR : Según @Jonathan Drapeau, el código anterior falla algunos casos (me gustaría ver esos casos, por favor) y sugirió lo siguiente, según entiendo:

public static int compare2(Date d1, Date d2) {
    Calendar c1 = Calendar.getInstance();
    Calendar c2 = Calendar.getInstance();
    c1.clear();
    c2.clear();
    c1.set(Calendar.YEAR, d1.getYear());
    c1.set(Calendar.MONTH, d1.getMonth());
    c1.set(Calendar.DAY_OF_MONTH, d1.getDay());
    c2.set(Calendar.YEAR, d2.getYear());
    c2.set(Calendar.MONTH, d2.getMonth());
    c2.set(Calendar.DAY_OF_MONTH, d2.getDay());
    return c1.getTime().compareTo(c2.getTime());
}

Tenga en cuenta que la clase Date está en desuso porque no era susceptible de internacionalización. ¡La clase Calendario se usa en su lugar!

Abdelrahman Aly
fuente
Esto no funciona el 100% del tiempo. Tuve un caso de uso donde hice eso y el calendar.getTime () aún devolvería la hora con las horas establecidas como la fecha del parámetro. Lo mejor es borrar los campos y establecer solo los de año, mes y día.
Jonathan Drapeau el
@ JonathanDrapeau, me parece que es posible que te hayas encontrado con una consecuencia de no elegir una zona horaria explícita. Ciertamente, es mejor hacer explícita la zona horaria que utilizar los getXxxmétodos obsoletos de Date.
Ole VV
1

Primero, tenga en cuenta que esta operación depende de la zona horaria. Por lo tanto, elija si desea hacerlo en UTC, en la zona horaria de la computadora, en su propia zona horaria favorita o dónde. Si aún no está convencido de que es importante, vea mi ejemplo al final de esta respuesta.

Como su pregunta no es muy clara sobre esto, supongo que tiene una clase con un campo de instancia que representa un punto en el tiempo y la implementación Comparable, y desea que el orden natural de sus objetos sea por fecha, pero no por hora , de ese campo. Por ejemplo:

public class ArnesClass implements Comparable<ArnesClass> {

    private static final ZoneId arnesTimeZone = ZoneId.systemDefault();

    private Instant when;

    @Override
    public int compareTo(ArnesClass o) {
        // question is what to put here
    }

}

java.timeClases de Java 8

Me he tomado la libertad de cambiar el tipo de su campo de instancia de Datea Instant, la clase correspondiente en Java 8. Prometo volver al tratamiento de Dateabajo. También he agregado una zona horaria constante. Puede establecerlo en ZoneOffset.UTCo ZoneId.of("Europe/Stockholm")lo que considere apropiado (establecerlo en un ZoneOffsettrabajo porque ZoneOffsetes una subclase de ZoneId).

Elegí mostrar la solución usando las clases de Java 8. Pediste la forma más sencilla, ¿verdad? :-) Aquí está el compareTométodo que solicitó:

public int compareTo(ArnesClass o) {
    LocalDate dateWithoutTime = when.atZone(arnesTimeZone).toLocalDate();
    LocalDate otherDateWithoutTime = o.when.atZone(arnesTimeZone).toLocalDate();
    return dateWithoutTime.compareTo(otherDateWithoutTime);
}

Si nunca necesita la pieza del tiempo de when, por supuesto, es más fácil para declarar whenuna LocalDatey saltar todas las conversiones. Entonces tampoco tenemos que preocuparnos por la zona horaria.

Ahora suponga que por alguna razón no puede declarar su whencampo Instanto desea mantenerlo a la antigua Date. Si aún puede usar Java 8, simplemente conviértalo Instant, luego haga lo que hizo antes:

    LocalDate dateWithoutTime = when.toInstant().atZone(arnesTimeZone).toLocalDate();

Del mismo modo para o.when .

No Java 8?

Si no puede usar Java 8, hay dos opciones:

  1. Resuélvelo usando una de las clases antiguas, ya sea CalendaroSimpleDateFormat .
  2. Utilice el backport de las clases de fecha y hora de Java 8 para Java 6 y 7, luego haga lo que se indica arriba. Incluyo un enlace en la parte inferior. No use JodaTime. JodaTime fue probablemente una buena sugerencia cuando se escribieron las respuestas que lo recomendaban; pero JodaTime ahora está en modo de mantenimiento, por lo que el backport ThreeTen es una opción mejor y más segura para el futuro.

Las formas anticuadas

La respuesta de Adamski le muestra cómo quitar la parte del tiempo de Dateusar la Calendarclase. Le sugiero que utilice getInstance(TimeZone)para obtener la Calendarinstancia para la zona horaria que desee. Como alternativa, puede usar la idea de la segunda mitad de la respuesta de Jorn .

Usar SimpleDateFormates realmente una forma indirecta de usar Calendarya que a SimpleDateFormatcontiene un Calendarobjeto. Sin embargo, puede encontrarlo menos problemático que usarlo Calendardirectamente:

private static final TimeZone arnesTimeZone = TimeZone.getTimeZone("Europe/Stockholm");
private static final DateFormat formatter = new SimpleDateFormat("yyyyMMdd");
static {
    formatter.setTimeZone(arnesTimeZone);
}

private Date when;

@Override
public int compareTo(ArnesClass o) {
    return formatter.format(when).compareTo(formatter.format(o.when));
}

Esto fue inspirado por la respuesta de Rob .

Dependencia de zona horaria

¿Por qué tenemos que elegir una zona horaria específica? Digamos que queremos comparar dos veces que en UTC son 24 de marzo 0:00 (medianoche) y 12:00 (mediodía). Si hace eso en CET (digamos, Europa / París), son las 1 am y la 1 pm el 24 de marzo, es decir, la misma fecha. En Nueva York (hora de verano del este), son las 20:00 el 23 de marzo y las 8:00 el 24 de marzo, es decir, no es la misma fecha. Por lo tanto, hace una diferencia la zona horaria que elija. Si solo confía en el valor predeterminado de la computadora, puede encontrarse con sorpresas cuando alguien intenta ejecutar su código en una computadora en otro lugar de este mundo globalizado.

Enlace

Enlace a ThreeTen Backport, el backport de las clases de fecha y hora de Java 8 a Java 6 y 7: http://www.threeten.org/threetenbp/ .

Ole VV
fuente
0

Mi propuesta:

    Calendar cal = Calendar.getInstance();
    cal.set(1999,10,01);   // nov 1st, 1999
    cal.set(Calendar.AM_PM,Calendar.AM);
    cal.set(Calendar.HOUR,0);
    cal.set(Calendar.MINUTE,0);
    cal.set(Calendar.SECOND,0);
    cal.set(Calendar.MILLISECOND,0);

    // date column in the Thought table is of type sql date
    Thought thought = thoughtDao.getThought(date, language);

    Assert.assertEquals(cal.getTime(), thought.getDate());
Jean-Pierre Schnyder
fuente
0

Usando Apache commons puedes hacer:

import org.apache.commons.lang3.time.DateUtils

DateUtils.truncatedEquals(first, second, Calendar.DAY_OF_MONTH)
unificar
fuente
0
public static Date getZeroTimeDate(Date fecha) {
    Date res = fecha;
    Calendar calendar = Calendar.getInstance();

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

    res = calendar.getTime();

    return res;
}

Date currentDate = getZeroTimeDate(new Date());// get current date   

Esta es la forma más sencilla de resolver este problema.

rana_sadam
fuente
0

Resolví esto comparando por marca de tiempo:

    Calendar last = Calendar.getInstance();

    last.setTimeInMillis(firstTimeInMillis);

    Calendar current = Calendar.getInstance();

    if (last.get(Calendar.DAY_OF_MONTH) != current.get(Calendar.DAY_OF_MONTH)) {
        //not the same day
    }

Evito usar Joda Time porque en Android usa un gran espacio. El tamaño importa. ;)

Oscar Josue Alvrez
fuente
0

Otra solución que usa Java 8 e Instant, es usar el método truncatedTo

Devuelve una copia de este Instant truncado a la unidad especificada.

Ejemplo:

@Test
public void dateTruncate() throws InterruptedException {
    Instant now = Instant.now();
    Thread.sleep(1000*5);
    Instant later = Instant.now();
    assertThat(now, not(equalTo(later)));
    assertThat(now.truncatedTo(ChronoUnit.DAYS), equalTo(later.truncatedTo(ChronoUnit.DAYS)));
}
rince
fuente
0
// Create one day 00:00:00 calendar
int oneDayTimeStamp = 1523017440;
Calendar oneDayCal = Calendar.getInstance();
oneDayCal.setTimeInMillis(oneDayTimeStamp * 1000L);
oneDayCal.set(Calendar.HOUR_OF_DAY, 0);
oneDayCal.set(Calendar.MINUTE, 0);
oneDayCal.set(Calendar.SECOND, 0);
oneDayCal.set(Calendar.MILLISECOND, 0);

// Create current day 00:00:00 calendar
Calendar currentCal = Calendar.getInstance();
currentCal.set(Calendar.HOUR_OF_DAY, 0);
currentCal.set(Calendar.MINUTE, 0);
currentCal.set(Calendar.SECOND, 0);
currentCal.set(Calendar.MILLISECOND, 0);

if (oneDayCal.compareTo(currentCal) == 0) {
    // Same day (excluding time)
}
yaslam
fuente
¡Gracias! Sin embargo, hay un puñado de otras respuestas con el mismo enfoque, aunque ahora veo que está comparando los objetos de Calendario directamente, mientras que en gran medida comparan los getTime () s.
Rup
-2

Esto es lo que funcionó para mí:

var Date1 = new Date(dateObject1.toDateString()); //this sets time to 00:00:00
var Date2 = new Date(dateObject2.toDateString()); 
//do a normal compare
if(Date1 > Date2){ //do something }
technomama
fuente
2
Su comparación "normal" ni siquiera se compilaría en Java. Si lo hiciera, compararía las referencias de objeto, pero esto no está permitido.
stivlo
Edité para agregar Markdown, pero stivlo tiene razón. No tengo idea de cómo ese código "funcionó para ti".
Aparece el
Esto es probablemente js.
Andrey Luiz
-2

¿Qué tal DateUtil.daysBetween(). Es Java y devuelve un número (diferencia en días).

Jules
fuente