La mejor forma de comparar fechas en Android

102

Estoy tratando de comparar una fecha en formato String con la fecha actual. Así es como lo hice (no lo he probado, pero debería funcionar), pero estoy usando métodos obsoletos. ¿Alguna buena sugerencia de alternativa? Gracias.

PD: Realmente odio hacer cosas de Date en Java. Hay tantas formas de hacer lo mismo, que realmente no estás seguro de cuál es la correcta, de ahí mi pregunta aquí.

String valid_until = "1/1/1990";

Calendar cal = Calendar.getInstance();
SimpleDateFormat sdf = new SimpleDateFormat("dd/mm/yyyy");
Date strDate = sdf.parse(valid_until);

int year = strDate.getYear(); // this is deprecated
int month = strDate.getMonth() // this is deprecated
int day = strDate.getDay(); // this is deprecated       

Calendar validDate = Calendar.getInstance();
validDate.set(year, month, day);

Calendar currentDate = Calendar.getInstance();

if (currentDate.after(validDate)) {
    catalog_outdated = 1;
}
nunos
fuente
4
En 2018 la mejor manera no implica Calendar, SimpleDateFormat, Dateo cualquiera de las otras clases de fecha y hora de Java anticuadas largas. En su lugar java.time, utilice la API moderna de fecha y hora de Java . Sí, puedes usarlo en Android. Para Android anterior, consulte Cómo usar ThreeTenABP en un proyecto de Android .
Ole VV

Respuestas:

219

Tu código podría reducirse a

SimpleDateFormat sdf = new SimpleDateFormat("dd/MM/yyyy");
Date strDate = sdf.parse(valid_until);
if (new Date().after(strDate)) {
    catalog_outdated = 1;
}

o

SimpleDateFormat sdf = new SimpleDateFormat("dd/MM/yyyy");
Date strDate = sdf.parse(valid_until);
if (System.currentTimeMillis() > strDate.getTime()) {
    catalog_outdated = 1;
}
JB Nizet
fuente
funciona seguro, publiqué la misma solución en otro hilo pero no aquí porque el colega fue más rápido O_o.
Simon Dorociak
solo quería estar seguro, antes de aceptar. Gracias. funcionó perfectamente y es conciso y simple como quería.
nunos
16
Creo que debería usarse el formato dd / MM / aaaa en lugar de dd / mm / aaaa, porque "m" significa minutos y "M" significa mes.
Demwis
¿No sería mejor utilizar el método compareTo ()?
clase Android
25

Puede usar compareTo ()

El método CompareTo debe devolver un número negativo si el objeto actual es menor que otro objeto, un número positivo si el objeto actual es mayor que otro objeto y cero si ambos objetos son iguales entre sí.

// Get Current Date Time
Calendar c = Calendar.getInstance();
SimpleDateFormat sdf = new SimpleDateFormat("MM/dd/yyyy HH:mm aa");
String getCurrentDateTime = sdf.format(c.getTime());
String getMyTime="05/19/2016 09:45 PM ";
Log.d("getCurrentDateTime",getCurrentDateTime); 
// getCurrentDateTime: 05/23/2016 18:49 PM

if (getCurrentDateTime.compareTo(getMyTime) < 0)
{

}
else
{
 Log.d("Return","getMyTime older than getCurrentDateTime "); 
}
IntelliJ Amiya
fuente
1
Para su información, las clases de fecha y hora viejas problemáticas tales como java.util.Date, java.util.Calendary java.text.SimpleDateFormatahora están legado, suplantados por los java.time clases. La mayor parte de la funcionalidad java.time se ha actualizado a Java 6 y Java 7 en el proyecto ThreeTen-Backport . Más adaptado para Android anterior (<26) en ThreeTenABP . Consulte Cómo utilizar ThreeTenABP… .
Basil Bourque
10

Puede crear directamente un Calendardesde un Date:

Calendar validDate = new GregorianCalendar();
validDate.setTime(strDate);
if (Calendar.getInstance().after(validDate)) {
    catalog_outdated = 1;
}
Assylias
fuente
10

Tenga en cuenta que el formato correcto es ("dd / MM / aaaa") antes de que funcione el código. "mm" significa minuts!

String valid_until = "01/07/2013";
SimpleDateFormat sdf = new SimpleDateFormat("dd/MM/yyyy");
Date strDate = null;
try {
    strDate = sdf.parse(valid_until);
} catch (ParseException e) {
    e.printStackTrace();
}
if (new Date().after(strDate)) {
    catalog_outdated = 1;
}
Rocologo
fuente
7
Calendar toDayCalendar = Calendar.getInstance();
Date date1 = toDayCalendar.getTime();


Calendar tomorrowCalendar = Calendar.getInstance();
tomorrowCalendar.add(Calendar.DAY_OF_MONTH,1);
Date date2 = tomorrowCalendar.getTime();

// date1 is a present date and date2 is tomorrow date

if ( date1.compareTo(date2) < 0 ) {

  //  0 comes when two date are same,
  //  1 comes when date1 is higher then date2
  // -1 comes when date1 is lower then date2

 }
Siva krishna
fuente
Para su información, las clases de fecha y hora viejas problemáticas tales como java.util.Date, java.util.Calendary java.text.SimpleDateFormatahora están legado, suplantados por los java.time clases. La mayor parte de la funcionalidad java.time se ha actualizado a Java 6 y Java 7 en el proyecto ThreeTen-Backport . Más adaptado para Android anterior (<26) en ThreeTenABP . Consulte Cómo utilizar ThreeTenABP… .
Basil Bourque
6
String date = "03/26/2012 11:00:00";
    String dateafter = "03/26/2012 11:59:00";
    SimpleDateFormat dateFormat = new SimpleDateFormat(
            "MM/dd/yyyy hh:mm:ss");
    Date convertedDate = new Date();
    Date convertedDate2 = new Date();
    try {
        convertedDate = dateFormat.parse(date);
        convertedDate2 = dateFormat.parse(dateafter);
        if (convertedDate2.after(convertedDate)) {
            txtView.setText("true");
        } else {
            txtView.setText("false");
        }
    } catch (ParseException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    }

devuelve verdadero .. y también puede verificar antes e igual con la ayuda de date.before y date.equal ..

Dilavar Malek
fuente
3
SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd",Locale.getDefault());
Calendar calendar1 = Calendar.getInstance();
Calendar calendar2 = Calendar.getInstance();

Date date1 = dateFormat.parse("2013-01-01");
Date date2 = dateFormat.parse("2013-01-02");

calendar1.setTime(date1);
calendar2.setTime(date2);

System.out.println("Compare Result : " + calendar2.compareTo(calendar1));
System.out.println("Compare Result : " + calendar1.compareTo(calendar2));

Compara el tiempo representado por este Calendario con el representado por el Calendario dado.

Devuelve 0 si los tiempos de los dos Calendarios son iguales, -1 si el tiempo de este Calendario es anterior al otro, 1 si el tiempo de este Calendario es posterior al otro.

Kirit Vaghela
fuente
1
Gracias .. Me ayuda.
PRANEO
2

convierta la fecha en Calendario y haga sus cálculos allí. :)

Calendar cal = Calendar.getInstance();
cal.setTime(date);

int year = cal.get(Calendar.YEAR);
int month = cal.geT(Calendar.MONTH);
int day = cal.get(Calendar.DAY_OF_MONTH); //same as cal.get(Calendar.DATE)

O:

SimpleDateFormat sdf = new SimpleDateFormat("dd/mm/yyyy");
Date strDate = sdf.parse(valid_until);

if (strDate.after(new Date()) {
    catalog_outdated = 1;
}
Nuno Gonçalves
fuente
2

Es hora de la respuesta moderna.

java.time y ThreeTenABP

    DateTimeFormatter dateFormatter = DateTimeFormatter.ofPattern("d/M/u");
    String validUntil = "1/1/1990";
    LocalDate validDate = LocalDate.parse(validUntil, dateFormatter);
    LocalDate currentDate = LocalDate.now(ZoneId.of("Pacific/Efate"));
    if (currentDate.isAfter(validDate)) {
        System.out.println("Catalog is outdated");
    }

Cuando ejecuté este código hace un momento, el resultado fue:

El catálogo está desactualizado

Dado que nunca es la misma fecha en todas las zonas horarias, proporcione una zona horaria explícita a LocalDate.now. Si desea que el catálogo expire a la misma hora en todas las zonas horarias, puede dar ZoneOffset.UTCsiempre que les informe a los usuarios que está utilizando UTC.

Estoy usando java.time, la API moderna de fecha y hora de Java. Las clases de fecha y hora que se utilizan, Calendar, SimpleDateFormaty Date, están mal diseñados y afortunadamente siempre actualizado. Además, a pesar del nombre Date, a no representa una fecha, sino un punto en el tiempo. Una consecuencia de esto es: aunque hoy es 15 de febrero de 2019, un Dateobjeto recién creado ya está después (por lo que no es igual a) un Dateobjeto del análisis 15/02/2019. Esto confunde a algunos. Contrariamente a esto, el moderno LocalDatees una fecha sin hora del día (y sin zona horaria), por lo que dos LocalDates que representan la fecha de hoy siempre serán iguales.

Pregunta: ¿Puedo usar java.time en Android?

Sí, java.time funciona bien en dispositivos Android antiguos y nuevos. Solo requiere al menos Java 6 .

  • En Java 8 y posteriores y en los dispositivos Android más nuevos (desde el nivel de API 26), la API moderna viene incorporada.
  • En Java 6 y 7, obtenga ThreeTen Backport, el backport de las clases modernas (ThreeTen para JSR 310; consulte los enlaces en la parte inferior).
  • En Android (más antiguo), use la edición de Android de ThreeTen Backport. Se llama ThreeTenABP. Y asegúrese de importar las clases de fecha y hora desde org.threeten.bpcon subpaquetes.

Enlaces

Ole VV
fuente
1

Podrías intentar esto

Calendar today = Calendar.getInstance (); 
today.add(Calendar.DAY_OF_YEAR, 0); 
today.set(Calendar.HOUR_OF_DAY, hrs); 
today.set(Calendar.MINUTE, mins ); 
today.set(Calendar.SECOND, 0); 

y podría utilizar today.getTime()para recuperar valor y comparar.

Anurag Ramdasan
fuente
1

A veces necesitamos hacer una lista con fechas, como

hoy con hora

ayer con ayer

otros días con 23/06/2017

Para hacer esto, necesitamos comparar la hora actual con nuestros datos.

Public class DateUtil {

    Public static int getDateDayOfMonth (Date date) {
        Calendar calendar = Calendar.getInstance ();
        Calendar.setTime (date);
        Return calendar.get (Calendar.DAY_OF_MONTH);
    }

    Public static int getCurrentDayOfMonth () {
        Calendar calendar = Calendar.getInstance ();
        Return calendar.get (Calendar.DAY_OF_MONTH);
    }

    Public static String convertMillisSecondsToHourString (long millisSecond) {
        Date date = new Date (millisSecond);
        Format formatter = new SimpleDateFormat ("HH: mm");
        Return formatter.format (date);
    }

    Public static String convertMillisSecondsToDateString (long millisSecond) {
        Date date = new Date (millisSecond);
        Format formatter = new SimpleDateFormat ("dd / MM / yyyy");
        Return formatter.format (date);
    }

    Public static long convertToMillisSecond (Date date) {
        Return date.getTime ();
    }

    Public static String compare (String stringData, String yesterday) {

        String result = "";

        SimpleDateFormat simpleDateFormat = new SimpleDateFormat ("yyyy-MM-dd HH: mm: ss");
        Date date = null;

        Try {
            Date = simpleDateFormat.parse (stringData);
        } Catch (ParseException e) {
            E.printStackTrace ();
        }

        Long millisSecond = convertToMillisSecond (date);
        Long currencyMillisSecond = System.currentTimeMillis ();

        If (currencyMillisSecond> millisSecond) {
            Long diff = currencyMillisSecond - millisSecond;
            Long day = 86400000L;

            If (diff <day && getCurrentDayOfMonth () == getDateDayOfMonth (date)) {
                Result = convertMillisSecondsToHourString (millisSecond);

            } Else if (diff <(day * 2) && getCurrentDayOfMonth () -1 == getDateDayOfMonth (date)) {
                Result = yesterday;
            } Else {
                Result = convertMillisSecondsToDateString (millisSecond);
            }
        }

        Return result;
    }
}

También puede consultar este ejemplo en GitHub y esta publicación .

Cabezas
fuente
1

Actualización: La Joda-Time biblioteca se encuentra ahora en el modo de mantenimiento, y recomienda migrar a la java.time marco que tiene éxito. Vea la respuesta de Ole VV .


Joda-Time

Las clases java.util.Date y .Calendar son notoriamente problemáticas. Evítales. Utilice Joda-Time o el nuevo paquete java.time en Java 8.

LocalDate

Si desea solo fecha sin hora del día, use la clase LocalDate.

Zona horaria

Obtener la fecha actual depende de la zona horaria. Se acerca una nueva fecha en París antes de Montreal. Especifique la zona horaria deseada en lugar de depender del valor predeterminado de la JVM.

Ejemplo en Joda-Time 2.3.

DateTimeFormat formatter = DateTimeFormat.forPattern( "d/M/yyyy" );
LocalDate localDate = formatter.parseLocalDate( "1/1/1990" );
boolean outdated = LocalDate.now( DateTimeZone.UTC ).isAfter( localDate );
Albahaca Bourque
fuente
0
SimpleDateFormat sdf=new SimpleDateFormat("d/MM/yyyy");
Date date=null;
Date date1=null;
try {
       date=sdf.parse(startDate);
       date1=sdf.parse(endDate);
    }  catch (ParseException e) {
              e.printStackTrace();
    }
if (date1.after(date) && date1.equals(date)) {
//..do your work..//
}
kartik_g
fuente
0

Kotlin admite la sobrecarga de los operadores

En Kotlin puedes comparar fechas fácilmente con operadores de comparación. Porque Kotlin ya soporta la sobrecarga de los operadores. Entonces, para comparar objetos de fecha:

firstDate: Date = // your first date
secondDate: Date = // your second date

if(firstDate < secondDate){
// fist date is before second date
}

y si está utilizando objetos de calendario, puede comparar fácilmente así:

if(cal1.time < cal2.time){
// cal1 date is before cal2 date
}
Khaled Qasem
fuente