Como subtrair X dias de uma data usando calendário Java?
-
03-07-2019 - |
Pergunta
Alguém sabe uma maneira simples utilizando calendário Java para subtrair X dias de uma data?
Eu não tenho sido capaz de encontrar qualquer função que me permite subtrair diretamente X dias de uma data em Java. Pode alguém me aponte para a direção certa?
Solução
Tomado de os docs aqui :
adiciona ou subtrai a quantidade especificada de tempo para o campo determinado calendário, com base nas regras do calendário. Por exemplo, para subtrair 5 dias a partir do momento atual do calendário, você pode alcançá-lo chamando:
Calendar calendar = Calendar.getInstance(); // this would default to now calendar.add(Calendar.DAY_OF_MONTH, -5).
Outras dicas
Você pode usar o método add
e passá-lo um número negativo. No entanto, você também pode escrever um método mais simples que não usa a classe Calendar
como o seguinte
public static void addDays(Date d, int days)
{
d.setTime( d.getTime() + (long)days*1000*60*60*24 );
}
Esta obtém o valor timestamp da data (milissegundos desde a época) e adiciona o número adequado de milissegundos. Você poderia passar um inteiro negativo para os dias parâmetro para fazer a subtração. Isso seria mais simples do que a solução de calendário "adequado":
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() );
}
Note que ambas as soluções alterar o objeto Date
passado como um parâmetro em vez de retornar uma nova Date
. De qualquer função poderia ser facilmente alterado para fazê-lo para o outro lado, se desejar.
o Anson resposta irá funcionar bem para o caso simples, mas se você está indo fazer quaisquer cálculos de data mais complexos que eu recomendo verificar Joda Tempo . Ele vai fazer a sua vida muito mais fácil.
FYI em Joda Tempo que você poderia fazer
DateTime dt = new DateTime();
DateTime fiveDaysEarlier = dt.minusDays(5);
tl; dr
LocalDate.now().minusDays( 10 )
Melhor para especificar o fuso horário.
LocalDate.now( ZoneId.of( "America/Montreal" ) ).minusDays( 10 )
Detalhes
As velhas classes de data e hora empacotados com as primeiras versões do Java, como java.util.Date
/ .Calendar
, provaram ser problemático, confuso e falho. Evitá-los.
java.time
Java 8 e suplanta posteriores essas classes antigo com o novo quadro java.time. Consulte Tutorial . Definido por JSR 310 , inspirado por Joda-Time , e prorrogado pelo projeto ThreeTen-extra. Os ThreeTen-Backport projeto back-portas as classes para Java 6 e 7; o projeto ThreeTenABP para Android.
A questão é vago, não é claro se ele pede para uma data-only ou uma data de tempo.
LocalDate
Para uma data-only, sem tempo-de-dia, use o class LocalDate
. Note-se que um fuso horário no crucial para determinar uma data como o "hoje".
LocalDate today = LocalDate.now( ZoneId.of( "America/Montreal" ) );
LocalDate tenDaysAgo = today.minusDays( 10 );
ZonedDateTime
Se você significou uma data-hora, em seguida, usar o Instant
classe para obter um momento na linha do tempo em UTC . De lá, ajuste para um fuso horário para obter um ZonedDateTime
objeto .
Instant now = Instant.now(); // UTC.
ZoneId zoneId = ZoneId.of( "America/Montreal" );
ZonedDateTime zdt = ZonedDateTime.ofInstant( instant , zoneId );
ZonedDateTime tenDaysAgo = zdt.minusDays( 10 );
Sobre java.time
O java.time framework é construído em Java 8 e posterior. Essas classes suplantar o problemático idade legados aulas de data e hora, como java.util.Date
, Calendar
, e SimpleDateFormat
.
O Joda-Time projeto , agora em < a href = "https://en.wikipedia.org/wiki/Maintenance_mode" rel = "nofollow noreferrer"> modo de manutenção , aconselha migração para o java.time classes.
Para saber mais, consulte a A Oracle Tutorial . E busca Stack Overflow para muitos exemplos e explicações. Especificação é JSR 310 .
Você pode trocar java.time objetos diretamente com seu banco de dados. Use a driver JDBC compatível com JDBC 4,2 ou mais tarde. Não há necessidade de cordas, sem necessidade de aulas java.sql.*
.
Where obter as classes java.time?
- Java SE 8 , Java SE 9 , Java SE 10 , e mais tarde
- Built-in.
- Parte da API Java padrão com uma implementação empacotado.
- Java 9 adiciona alguns recursos menores e correções.
- Java SE 6 e Java SE 7
- Grande parte da funcionalidade java.time é back-portados para o Java 6 e 7 em ThreeTen-Backport .
- Android
- As versões posteriores do Android pacote implementações das classes java.time.
- Para Android mais cedo (<26), a ThreeTenABP adapta projeto ThreeTen-Backport (mencionados acima). Consulte Como usar ThreeTenABP ... .
O ThreeTen-Extra projeto estende java.time com aulas adicionais. Este projeto é um campo de provas para possíveis adições futuras para java.time. Você pode encontrar algumas classes úteis aqui, como Interval
, YearWeek
, YearQuarter
, e mais .
int x = -1;
Calendar cal = ...;
cal.add(Calendar.DATE, x);
edit: o analisador não parece como o link para o Javadoc, por isso 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 minha própria addDays
como sugerido por Eli, eu preferiria usar DateUtils
de Apache . É útil especialmente quando você tem que usá-lo vários lugares em seu projeto.
A API diz:
addDays(Date date, int amount)
Adiciona um número de dias para a data de retornar um novo objeto.
Note que ele retorna um novo objeto Date
e não faz alterações no próprio anterior.
Alguém recomendado Joda tempo assim - tenho vindo a utilizar este CalendarDate classe http: // CalendarDate. sourceforge.net
É um projeto um tanto competindo para Joda Time, mas muito mais básico e a apenas 2 classes. É muito útil e trabalhou muito para o que eu precisava desde que eu não queria usar um pacote maior do que o meu projeto. Ao contrário dos homólogos Java, a menor unidade é o dia por isso é realmente uma data (não tê-la para baixo para milissegundos ou algo). 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
}
Isso pode ser feito facilmente pela 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());
segunda solução Eli Courtwright está errado, deve ser:
Calendar c = Calendar.getInstance();
c.setTime(date);
c.add(Calendar.DATE, -days);
date.setTime(c.getTime().getTime());