Como comparar datas em Java?

Como faço para comparar datas entre em Java?

Exemplo:

date1 é 22-02-2010
date2 é 07-04-2010 hoje
date3 é 25-12-2010

date3 é sempre maior que date1 e date2 é sempre hoje. Como posso verificar se a data de hoje é entre data1 e data 3?

A data tem methods antes e depois e pode ser comparada entre si da seguinte maneira:

 if(todayDate.after(historyDate) && todayDate.before(futureDate)) { // In between } 

Para uma comparação inclusiva:

 if(!historyDate.after(todayDate) && !futureDate.before(todayDate)) { /* historyDate <= todayDate <= futureDate */ } 

Você também pode dar uma chance ao Joda-Time , mas observe que:

O Joda-Time é a biblioteca padrão de data e hora do Java antes do Java SE 8. Agora, os usuários são solicitados a migrar para o java.time ( JSR-310 ).

Os back-ports estão disponíveis para o Java 6 e 7, bem como para o Android.

Use compareTo :

date1.compareTo(date2);

A seguir, a maneira mais comum de comparar datas. Mas eu prefiro primeiro

Abordagem 1: usando Date.before (), Date.after () e Date.equals ()

  if(date1.after(date2)){ System.out.println("Date1 is after Date2"); } if(date1.before(date2)){ System.out.println("Date1 is before Date2"); } if(date1.equals(date2)){ System.out.println("Date1 is equal Date2"); } 

Abordagem 2: Date.compareTo ()

  if(date1.compareTo(date2)>0){ System.out.println("Date1 is after Date2"); }else if(date1.compareTo(date2)<0){ System.out.println("Date1 is before Date2"); }else{ System.out.println("Date1 is equal to Date2"); } 

Abordagem 3: Calender.before (), Calender.after () e Calender.equals ()

 Calendar cal1 = Calendar.getInstance(); Calendar cal2 = Calendar.getInstance(); cal1.setTime(date1); cal2.setTime(date2); if(cal1.after(cal2)){ System.out.println("Date1 is after Date2"); } if(cal1.before(cal2)){ System.out.println("Date1 is before Date2"); } if(cal1.equals(cal2)){ System.out.println("Date1 is equal Date2"); } 

tl; dr

 LocalDate today = LocalDate.now( ZoneId.of( "America/Montreal" ) ) ; Boolean isBetween = ( ! today.isBefore( localDate1 ) ) // “not-before” is short for “is-equal-to or later-than”. && today.isBefore( localDate3 ) ; 

Ou melhor, se você adicionar a biblioteca ThreeTen-Extra ao seu projeto.

 LocalDateRange.of( LocalDate.of( … ) , LocalDate.of( … ) ).contains( LocalDate.now() ) 

Abordagem semiaberta, em que o começo é inclusivo ao final é exclusivo .

Má escolha de formato

By the way, que é uma má escolha de formato para uma representação de texto de uma data ou valor de data e hora. Sempre que possível, mantenha os formatos padrão ISO 8601 . Os formatos ISO 8601 não são ambíguos, compreensíveis em todas as culturas humanas e são fáceis de analisar por máquina.

Para um valor somente de data, o formato padrão é AAAA-MM-DD. Observe como esse formato tem a vantagem de ser cronológico quando classificado em ordem alfabética.

LocalDate

A class LocalDate representa um valor somente de datas sem hora do dia e sem fuso horário.

Um fuso horário é crucial para determinar uma data. Para qualquer momento, a data varia ao redor do globo por zona. Por exemplo, poucos minutos depois da meia-noite em Paris, a França é um novo dia ainda em “ontem” em Montreal, Quebec .

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

DateTimeFormatter

Como suas strings de input são formato não padrão, devemos definir um padrão de formatação para corresponder.

 DateTimeFormatter f = DateTimeFormatter.ofPattern( "dd-MM-uuuu" ); 

Use isso para analisar as strings de input.

 LocalDate start = LocalDate.parse( "22-02-2010" , f ); LocalDate stop = LocalDate.parse( "25-12-2010" , f ); 

No trabalho de data e hora, geralmente é melhor definir um período de tempo pela abordagem Half-Open, em que o início é inclusivo, enquanto o final é exclusivo . Então, queremos saber se hoje é o mesmo ou depois do início e também antes da parada. Uma maneira mais breve de dizer “é o mesmo ou mais tarde que o começo” é “não antes do começo”.

 Boolean intervalContainsToday = ( ! today.isBefore( start ) ) && today.isBefore( stop ) ; 

Veja a resposta por gstackoverflow mostrando a lista de methods de comparação que você pode chamar.


Sobre o java.time

O framework java.time está embutido no Java 8 e posterior. Essas classs substituem as antigas classs herdadas de data e hora legadas , como java.util.Date , Calendar e SimpleDateFormat .

O projeto Joda-Time , agora em modo de manutenção , aconselha a migration para as classs java.time .

Para saber mais, veja o Oracle Tutorial . E pesquise o Stack Overflow para muitos exemplos e explicações. A especificação é JSR 310 .

Onde obter as classs java.time?

  • Java SE 8 e SE 9 e posterior
    • Construídas em.
    • Parte da API Java padrão com uma implementação integrada.
    • O Java 9 adiciona alguns resources e correções menores.
  • Java SE 6 e SE 7
    • Grande parte da funcionalidade java.time é transferida para o Java 6 e 7 no ThreeTen-Backport .
  • Android
    • O projeto ThreeTenABP adapta o ThreeTen-Backport (mencionado acima) especificamente para o Android.
    • Veja Como usar o ThreeTenABP… .

O projeto ThreeTen-Extra estende java.time com classs adicionais. Este projeto é um campo de testes para possíveis futuras adições ao java.time. Você pode encontrar algumas classs úteis aqui como Interval , YearWeek , YearQuarter e muito mais .


ATUALIZAÇÃO: Esta seção “Joda-Time” abaixo é deixada intacta como história. O projeto Joda-Time , agora em modo de manutenção , aconselha a migration para as classs java.time .

Joda-Time

Outras respostas estão corretas em relação às classs java.util.Date e java.util.Calendar empacotadas. Mas essas classs são notoriamente problemáticas. Então aqui está um exemplo de código usando a biblioteca Joda-Time 2.3.

Se você realmente deseja uma data sem qualquer parte do tempo e nenhum fuso horário, use a class LocalDate no Joda-Time. Essa class fornece methods de comparação, incluindo compareTo (usado com Java Comparators ), isBefore , isAfter e isEqual .

Entradas …

 String string1 = "22-02-2010"; String string2 = "07-04-2010"; String string3 = "25-12-2010"; 

Defina um formatador descrevendo as cadeias de input…

 DateTimeFormatter formatter = DateTimeFormat.forPattern( "dd-MM-yyyy" ); 

Use formatador para analisar as seqüências de caracteres em objects LocalDate …

 LocalDate localDate1 = formatter.parseLocalDate( string1 ); LocalDate localDate2 = formatter.parseLocalDate( string2 ); LocalDate localDate3 = formatter.parseLocalDate( string3 ); boolean is1After2 = localDate1.isAfter( localDate2 ); boolean is2Before3 = localDate2.isBefore( localDate3 ); 

Despeje para consolar…

 System.out.println( "Dates: " + localDate1 + " " + localDate2 + " " + localDate3 ); System.out.println( "is1After2 " + is1After2 ); System.out.println( "is2Before3 " + is2Before3 ); 

Quando correr …

 Dates: 2010-02-22 2010-04-07 2010-12-25 is1After2 false is2Before3 true 

Então veja se o segundo é entre os outros dois (exclusivamente, significando não igual a um dos endpoints) …

 boolean is2Between1And3 = ( ( localDate2.isAfter( localDate1 ) ) && ( localDate2.isBefore( localDate3 ) ) ); 

Trabalhando com períodos de tempo

Se você está trabalhando com o tempo, eu sugiro explorar em Joda-Time as classs: Duração , Intervalo e Período . Métodos como overlap e contains facilitam as comparações.

Para representações de texto, veja a norma ISO 8601:

  • duração
    Formato: PnYnMnDTnHnMnS
    Exemplo: P3Y6M4DT12H30M5S
    (Significa “três anos, seis meses, quatro dias, doze horas, trinta minutos e cinco segundos”)
  • intervalo
    Formato: início / fim
    Exemplo: 2007-03-01T13: 00: 00Z / 2008-05-11T15: 30: 00Z

As classs Joda-Time podem trabalhar com strings em ambos os formatos, tanto como input (parsing) e output (gerando strings).

O Joda-Time realiza comparações usando a abordagem Half-Open , em que o início do intervalo é inclusivo, enquanto o final é exclusivo . Essa abordagem é sábia para lidar com períodos de tempo. Pesquise StackOverflow para mais informações.

Compare as duas datas:

  Date today = new Date(); Date myDate = new Date(today.getYear(),today.getMonth()-1,today.getDay()); System.out.println("My Date is"+myDate); System.out.println("Today Date is"+today); if (today.compareTo(myDate)<0) System.out.println("Today Date is Lesser than my Date"); else if (today.compareTo(myDate)>0) System.out.println("Today Date is Greater than my date"); else System.out.println("Both Dates are equal"); 

Atualização para o Java 8 e posterior

  • isAfter()
  • isBefore()
  • isEqual()
  • compareTo()

Esses methods existem nas LocalDate , LocalTime e LocalDateTime .

Essas classs são construídas no Java 8 e posterior. Grande parte da funcionalidade java.time é transferida para o Java 6 e 7 no ThreeTen-Backport e adaptada para o Android no ThreeTenABP (consulte Como usar… ).

Você pode usar Date.getTime() que:

Retorna o número de milissegundos desde 1º de janeiro de 1970, 00:00:00 GMT representado por esse object Date.

Isso significa que você pode compará-los como números:

 if (date1.getTime() <= date.getTime() && date.getTime() <= date2.getTime()) { /* * date is between date1 and date2 (both inclusive) */ } /* * when date1 = 2015-01-01 and date2 = 2015-01-10 then * returns true for: * 2015-01-01 * 2015-01-01 00:00:01 * 2015-01-02 * 2015-01-10 * returns false for: * 2014-12-31 23:59:59 * 2015-01-10 00:00:01 * * if one or both dates are exclusive then change <= to < */ 

Use getTime () para obter o valor numérico da data e compare usando os valores retornados.

Tente isso

 public static boolean compareDates(String psDate1, String psDate2) throws ParseException{ SimpleDateFormat dateFormat = new SimpleDateFormat ("dd/MM/yyyy"); Date date1 = dateFormat.parse(psDate1); Date date2 = dateFormat.parse(psDate2); if(date2.after(date1)) { return true; } else { return false; } } 

Este código determina hoje é em alguma duração .. baseado no locale de KOREA

  Calendar cstart = Calendar.getInstance(Locale.KOREA); cstart.clear(); cstart.set(startyear, startmonth, startday); Calendar cend = Calendar.getInstance(Locale.KOREA); cend.clear(); cend.set(endyear, endmonth, endday); Calendar c = Calendar.getInstance(Locale.KOREA); if(c.after(cstart) && c.before(cend)) { // today is in startyear/startmonth/startday ~ endyear/endmonth/endday } 

Esse método funcionou para mim:

  public static String daysBetween(String day1, String day2) { String daysBetween = ""; SimpleDateFormat myFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); try { Date date1 = myFormat.parse(day1); Date date2 = myFormat.parse(day2); long diff = date2.getTime() - date1.getTime(); daysBetween = ""+(TimeUnit.DAYS.convert(diff, TimeUnit.MILLISECONDS)); } catch (ParseException e) { e.printStackTrace(); } return daysBetween; }