Como subtrair X dias a partir de uma data usando o calendar Java?

Alguém sabe de uma maneira simples usando o calendar Java para subtrair X dias a partir de uma data?

Eu não consegui encontrar nenhuma function que me permita subtrair X dias diretamente de uma data em Java. Alguém pode me apontar para a direção certa?

Extraído dos documentos aqui :

Adiciona ou subtrai o período de tempo especificado ao campo de calendar determinado, com base nas regras do calendar. Por exemplo, para subtrair 5 dias da hora atual do calendar, você pode alcançá-lo chamando:

 Calendar calendar = Calendar.getInstance(); // this would default to now calendar.add(Calendar.DAY_OF_MONTH, -5). 

Você poderia usar o método add e passar um número negativo. No entanto, você também pode escrever um método mais simples que não use a class Calendar como a seguinte

 public static void addDays(Date d, int days) { d.setTime( d.getTime() + (long)days*1000*60*60*24 ); } 

Isso obtém o valor de registro de data e hora da data (milissegundos desde a época) e adiciona o número adequado de milissegundos. Você poderia passar um inteiro negativo para o parâmetro days para fazer subtração. Isso seria mais simples que a solução de calendar “adequada”:

 public static void addDays(Date d, int days) { Calendar c = Calendar.getInstance(); c.setTime(d); c.add(Calendar.DATE, days); d.setTime( c.getTime().getTime() ); } 

Observe que essas duas soluções alteram o object Date passado como um parâmetro em vez de retornar uma Date completamente nova. Qualquer function pode ser facilmente alterada para fazer o contrário, se desejado.

A resposta de Anson funcionará bem para o caso simples, mas se você fizer mais cálculos de data mais complexos, eu recomendaria verificar o Joda Time . Isso tornará sua vida muito mais fácil.

FYI em Joda Time você poderia fazer

 DateTime dt = new DateTime(); DateTime fiveDaysEarlier = dt.minusDays(5); 

tl; dr

 LocalDate.now().minusDays( 10 ) 

Melhor especificar o fuso horário.

 LocalDate.now( ZoneId.of( "America/Montreal" ) ).minusDays( 10 ) 

Detalhes

As antigas classs de data e hora empacotadas com versões anteriores do Java, como java.util.Date / .Calendar , provaram ser problemáticas, confusas e defeituosas. Evite-os.

java.time

O Java 8 e versões posteriores substituem essas classs antigas pelo novo framework java.time. Veja o tutorial . Definido pela JSR 310 , inspirado no Joda-Time , e ampliado pelo projeto ThreeTen-Extra . O projeto do ThreeTen-Backport faz back-ports das classs para o Java 6 & 7; o projeto ThreeTenABP para Android.

A pergunta é vaga, não é clara se ela pede apenas uma data ou uma data e hora.

LocalDate

Para uma data somente, sem hora do dia, use a class LocalDate . Observe que um fuso horário é crucial para determinar uma data como “hoje”.

 LocalDate today = LocalDate.now( ZoneId.of( "America/Montreal" ) ); LocalDate tenDaysAgo = today.minusDays( 10 ); 

ZonedDateTime

Se você quis dizer uma data e hora, use a class Instant para obter um momento na linha do tempo no UTC . De lá, ajuste para um fuso horário para obter um object ZonedDateTime .

 Instant now = Instant.now(); // UTC. ZoneId zoneId = ZoneId.of( "America/Montreal" ); ZonedDateTime zdt = ZonedDateTime.ofInstant( instant , zoneId ); ZonedDateTime tenDaysAgo = zdt.minusDays( 10 ); 

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 .

Você pode trocar objects java.time diretamente com seu database. Use um driver JDBC compatível com o JDBC 4.2 ou posterior. Não há necessidade de strings, não há necessidade de classs java.sql.* .

Onde obter as classs java.time?

  • Java SE 8 , Java SE 9 , Java SE 10 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 Java SE 7
    • Grande parte da funcionalidade java.time é transferida para o Java 6 e 7 no ThreeTen-Backport .
  • Android
    • Versões posteriores das implementações do pacote Android das classs java.time.
    • Para Android anterior (<26), o projeto ThreeTenABP adapta o ThreeTen-Backport (mencionado acima). 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 .

 int x = -1; Calendar cal = ...; cal.add(Calendar.DATE, x); 

edit: o parser não parece gostar do link para o Javadoc, então aqui está em texto simples:

http://java.sun.com/j2se/1.4.2/docs/api/java/util/Calendar.html#add(int , int)

Em vez de escrever meus próprios addDays como sugerido por Eli, eu preferiria usar o DateUtils do Apache . É útil especialmente quando você tem que usar vários lugares em seu projeto.

A API diz:

addDays(Date date, int amount)

Adiciona um número de dias a uma data retornando um novo object.

Observe que ele retorna um novo object Date e não faz alterações no anterior.

Alguém recomendou o Joda Time então – eu tenho usado esta class CalendarDate http://calendardate.sourceforge.net

É um projeto um pouco competitivo para a Joda Time, mas muito mais básico em apenas duas classs. É muito útil e funcionou muito bem para o que eu precisava, já que eu não queria usar um pacote maior do que o meu projeto. Ao contrário das contrapartes de Java, sua menor unidade é o dia, então é realmente uma data (não ter isso em milissegundos ou algo assim). Depois de criar a data, tudo que você faz para subtrair é algo como myDay.addDays (-5) para voltar 5 dias. Você pode usá-lo para encontrar o dia da semana e coisas assim. Outro exemplo:

 CalendarDate someDay = new CalendarDate(2011, 10, 27); CalendarDate someLaterDay = today.addDays(77); 

E:

 //print 4 previous days of the week and today String dayLabel = ""; CalendarDate today = new CalendarDate(TimeZone.getDefault()); CalendarDateFormat cdf = new CalendarDateFormat("EEE");//day of the week like "Mon" CalendarDate currDay = today.addDays(-4); while(!currDay.isAfter(today)) { dayLabel = cdf.format(currDay); if (currDay.equals(today)) dayLabel = "Today";//print "Today" instead of the weekday name System.out.println(dayLabel); currDay = currDay.addDays(1);//go to next day } 

Eli Courtwright segunda solução está errada, deve ser:

 Calendar c = Calendar.getInstance(); c.setTime(date); c.add(Calendar.DATE, -days); date.setTime(c.getTime().getTime()); 

Isso pode ser feito facilmente pelo seguinte

 Calendar calendar = Calendar.getInstance(); // from current time long curTimeInMills = new Date().getTime(); long timeInMills = curTimeInMills - 5 * (24*60*60*1000); // `enter code here`subtract like 5 days calendar.setTimeInMillis(timeInMills); System.out.println(calendar.getTime()); // from specific time like (08 05 2015) calendar.set(Calendar.DAY_OF_MONTH, 8); calendar.set(Calendar.MONTH, (5-1)); calendar.set(Calendar.YEAR, 2015); timeInMills = calendar.getTimeInMillis() - 5 * (24*60*60*1000); calendar.setTimeInMillis(timeInMills); System.out.println(calendar.getTime());