Melhor maneira de comparar datas no Android

102

Estou tentando comparar uma data em formato de string com a data atual. É assim que eu fiz (não testei, mas deve funcionar), mas estou usando métodos obsoletos. Alguma boa sugestão de alternativa? Obrigado.

PS: Eu realmente odeio fazer coisas de Date em Java. Existem tantas maneiras de fazer a mesma coisa, que você realmente não tem certeza de qual é a correta, daí a minha pergunta aqui.

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
fonte
4
Em 2018 a melhor maneira não envolve Calendar, SimpleDateFormat, Dateou qualquer um dos outros longas desatualizados data e hora Java classes. Em vez disso java.time, use a moderna API Java de data e hora . Sim, você pode usá-lo no Android. Para Android mais antigo, consulte Como usar o ThreeTenABP no projeto Android .
Ole VV de

Respostas:

219

Seu código pode ser reduzido a

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

ou

SimpleDateFormat sdf = new SimpleDateFormat("dd/MM/yyyy");
Date strDate = sdf.parse(valid_until);
if (System.currentTimeMillis() > strDate.getTime()) {
    catalog_outdated = 1;
}
JB Nizet
fonte
funciona certo, postei a mesma solução em outro tópico mas não aqui porque o colega foi mais rápido O_o.
Simon Dorociak
só queria ter certeza, antes de aceitar. obrigado. funcionou perfeitamente e é conciso e simples como desejado.
nunos
16
Eu acho que deveria ser usado o formato dd / MM / aaaa em vez de dd / mm / aaaa, porque "m" significa minutos e "M" significa mês.
Demwis de
Não seria melhor usar o método compareTo ()?
classe Android
25

Você pode usar compareTo ()

O método CompareTo deve retornar um número negativo se o objeto atual for menor que outro objeto, um número positivo se o objeto atual for maior que outro objeto e zero se ambos os objetos forem iguais um ao outro.

// 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
fonte
1
FYI, os incômodos aulas em tempo data antigas, tais como java.util.Date, java.util.Calendare java.text.SimpleDateFormatestão agora legado, suplantado pelos java.time classes. A maior parte da funcionalidade java.time é portada para Java 6 e Java 7 no projeto ThreeTen-Backport . Adaptado para Android anterior (<26) em ThreeTenABP . Consulte Como usar o ThreeTenABP… .
Basil Bourque
10

Você pode criar diretamente a Calendarpartir de Date:

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

Observe que o formato correto é ("dd / MM / aaaa") antes de o código funcionar. "mm" significa minutos!

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
fonte
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
fonte
FYI, os incômodos aulas em tempo data antigas, tais como java.util.Date, java.util.Calendare java.text.SimpleDateFormatestão agora legado, suplantado pelos java.time classes. A maior parte da funcionalidade java.time é portada para Java 6 e Java 7 no projeto ThreeTen-Backport . Adaptado para Android anterior (<26) em ThreeTenABP . Consulte Como usar o 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();
    }

retorna true .. e você também pode verificar antes e igual com a ajuda de date.before e date.equal ..

Dilavar Malek
fonte
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 a hora representada por este calendário com a representada pelo calendário fornecido.

Retorna 0 se os horários dos dois Calendários forem iguais, -1 se o horário deste Calendário for anterior ao outro, 1 se o horário deste Calendário for posterior ao outro.

Kirit Vaghela
fonte
1
Obrigado .. É me ajudar.
PRANAY
2

converta a data em Calendário e faça seus cálculos lá. :)

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)

Ou:

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

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

É hora da resposta moderna.

java.time e 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");
    }

Quando executei este código agora, o resultado foi:

Catálogo está desatualizado

Como nunca é a mesma data em todos os fusos horários, forneça um fuso horário explícito a LocalDate.now. Se você deseja que o catálogo expire ao mesmo tempo em todos os fusos horários, você pode fornecerZoneOffset.UTC , desde que informe aos usuários que está usando UTC.

Estou usando java.time, a API moderna de data e hora do Java. As classes de data e hora que você usou Calendar, SimpleDateFormate Date, são todas mal projetadas e, felizmente, há muito desatualizadas. Além disso, apesar do nome, a Datenão representa uma data, mas um ponto no tempo. Uma consequência disso é: embora hoje seja 15 de fevereiro de 2019, um Dateobjeto recém-criado já está após (não é igual a) um Dateobjeto da análise 15/02/2019. Isso confunde alguns. Ao contrário disso, o moderno LocalDateé uma data sem hora do dia (e sem fuso horário), então dois LocalDates representando a data de hoje sempre serão iguais.

Pergunta: Posso usar java.time no Android?

Sim, java.time funciona bem em dispositivos Android mais antigos e mais recentes. Requer apenas pelo menos Java 6 .

  • No Java 8 e posterior e em dispositivos Android mais recentes (da API de nível 26), a API moderna vem embutida.
  • Em Java 6 e 7, obtenha o Backport ThreeTen, o backport das classes modernas (ThreeTen para JSR 310; consulte os links na parte inferior).
  • No Android (mais antigo), use a edição Android do ThreeTen Backport. É chamado ThreeTenABP. E certifique-se de importar as classes de data e hora org.threeten.bpcom subpacotes.

Links

Ole VV
fonte
1

Você poderia tentar isso

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); 

e você pode usar today.getTime()para recuperar o valor e comparar.

Anurag Ramdasan
fonte
1

Às vezes, precisamos fazer uma lista com datas, como

hoje com hora

ontem com ontem

outros dias com 23/06/2017

Para fazer isso, precisamos comparar a hora atual com nossos dados.

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;
    }
}

Além disso, você pode verificar este exemplo no GitHub e neste post .

Cabezas
fonte
1

Atualização: A biblioteca Joda-Time agora está em modo de manutenção e recomenda migrar para a estrutura java.time que a sucede. Veja a resposta de Ole VV .


Joda-Time

As classes java.util.Date e .Calendar são notoriamente problemáticas. Evite-os. Use o Joda-Time ou o novo pacote java.time no Java 8.

LocalDate

Se você quiser apenas data sem hora do dia, use a classe LocalDate.

Fuso horário

Obter a data atual depende do fuso horário. Um novo encontro rola em Paris antes de Montreal. Especifique o fuso horário desejado em vez de depender do padrão da JVM.

Exemplo em 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 );
Basil Bourque
fonte
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
fonte
0

Kotlin oferece suporte à sobrecarga de operadores

Em Kotlin, você pode comparar facilmente datas com operadores de comparação. Porque Kotlin já suporta sobrecarga de operadores. Então, para comparar objetos de data:

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

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

e se estiver usando objetos de calendário, você pode comparar facilmente assim:

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