Respuestas:
Tomado de los documentos aquí :
Agrega o resta la cantidad de tiempo especificada al campo de calendario dado, según las reglas del calendario. Por ejemplo, para restar 5 días de la hora actual del calendario, puede lograrlo llamando:
Calendar calendar = Calendar.getInstance(); // this would default to now calendar.add(Calendar.DAY_OF_MONTH, -5).
Calendar.DAY_OF_MONTHen este caso ya que no manejará el rollo entre meses como le gustaría. Usar en su Calendar.DAY_OF_YEARlugar
Podrías usar el addmétodo y pasarle un número negativo. Sin embargo, también podría escribir un método más simple que no use la Calendarclase como el siguiente
public static void addDays(Date d, int days)
{
d.setTime( d.getTime() + (long)days*1000*60*60*24 );
}
Esto obtiene el valor de fecha y hora de la fecha (milisegundos desde la época) y agrega la cantidad adecuada de milisegundos. Podría pasar un número entero negativo para el parámetro días para restar. Esto sería más simple que la solución de calendario "adecuada":
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() );
}
Tenga en cuenta que ambas soluciones cambian el Dateobjeto pasado como parámetro en lugar de devolver uno completamente nuevo Date. Cualquiera de las funciones se puede cambiar fácilmente para hacerlo de la otra manera si se desea.
java.util.Calendarahora son heredadas , suplantadas por las clases java.time . Ver Tutorial de Oracle .
La respuesta de Anson funcionará bien para el caso simple, pero si va a hacer cálculos de fechas más complejos, le recomiendo que revise Joda Time . Hará tu vida mucho más fácil.
FYI en Joda Time que podrías hacer
DateTime dt = new DateTime();
DateTime fiveDaysEarlier = dt.minusDays(5);
LocalDate.now().minusDays( 10 )
Es mejor especificar la zona horaria.
LocalDate.now( ZoneId.of( "America/Montreal" ) ).minusDays( 10 )
Las antiguas clases de fecha y hora incluidas con las primeras versiones de Java, como java.util.Date/.Calendar , han demostrado ser problemáticas, confusas y defectuosas. Evítales.
Java 8 y posterior suplanta esas clases antiguas con el nuevo marco java.time. Ver tutorial . Definido por JSR 310 , inspirado en Joda-Time , y ampliado por el proyecto ThreeTen-Extra . El proyecto ThreeTen-Backport transfiere las clases a Java 6 y 7; el proyecto ThreeTenABP para Android.
La pregunta es vaga, no está clara si solicita una fecha solamente o una fecha y hora.
LocalDatePara una fecha solamente, sin hora del día, use la LocalDateclase. Tenga en cuenta que una zona horaria es crucial para determinar una fecha como "hoy".
LocalDate today = LocalDate.now( ZoneId.of( "America/Montreal" ) );
LocalDate tenDaysAgo = today.minusDays( 10 );
ZonedDateTimeSi se refería a una fecha y hora, use la Instantclase para obtener un momento en la línea de tiempo en UTC . Desde allí, ajústese a una zona horaria para obtener un ZonedDateTimeobjeto.
Instant now = Instant.now(); // UTC.
ZoneId zoneId = ZoneId.of( "America/Montreal" );
ZonedDateTime zdt = ZonedDateTime.ofInstant( instant , zoneId );
ZonedDateTime tenDaysAgo = zdt.minusDays( 10 );
El marco java.time está integrado en Java 8 y versiones posteriores. Estas clases suplantar la vieja problemáticos heredados clases de fecha y hora como java.util.Date, Calendar, y SimpleDateFormat.
El proyecto Joda-Time , ahora en modo de mantenimiento , aconseja la migración a las clases java.time .
Para obtener más información, consulte el Tutorial de Oracle . Y busque Stack Overflow para obtener muchos ejemplos y explicaciones. La especificación es JSR 310 .
Puede intercambiar objetos java.time directamente con su base de datos. Utilice un controlador JDBC compatible con JDBC 4.2 o posterior. No hay necesidad de cuerdas, no hay necesidad dejava.sql.* clases.
¿Dónde obtener las clases java.time?
El proyecto ThreeTen-Extra extiende java.time con clases adicionales. Este proyecto es un campo de pruebas para posibles adiciones futuras a java.time. Usted puede encontrar algunas clases útiles aquí, como Interval, YearWeek, YearQuarter, y más .
int x = -1;
Calendar cal = ...;
cal.add(Calendar.DATE, x);
editar: al analizador no parece gustarle el enlace al Javadoc, así que aquí está en texto sin formato:
http://java.sun.com/j2se/1.4.2/docs/api/java/util/Calendar.html#add(int , int)
En lugar de escribir el mío addDayscomo lo sugiere Eli, preferiría usarlo DateUtilsdesde Apache . Es útil especialmente cuando tienes que usarlo en múltiples lugares en tu proyecto.
La API dice:
addDays(Date date, int amount)
Agrega una cantidad de días a una fecha que devuelve un nuevo objeto.
Tenga en cuenta que devuelve un nuevo Dateobjeto y no realiza cambios en el anterior.
Se puede hacer fácilmente de la siguiente manera
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());
LocalDatees mucho más simple y más apropiado.
Alguien recomendó Joda Time, así que he estado usando esta clase CalendarDate http://calendardate.sourceforge.net
Es un proyecto un tanto competitivo para Joda Time, pero mucho más básico con solo 2 clases. Es muy útil y funcionó muy bien para lo que necesitaba, ya que no quería usar un paquete más grande que mi proyecto. A diferencia de las contrapartes de Java, su unidad más pequeña es el día, por lo que es realmente una fecha (no tenerla en milisegundos o algo así). Una vez que cree la fecha, todo lo que debe hacer para restar es algo como myDay.addDays (-5) para retroceder 5 días. Puedes usarlo para encontrar el día de la semana y cosas así. Otro ejemplo:
CalendarDate someDay = new CalendarDate(2011, 10, 27);
CalendarDate someLaterDay = today.addDays(77);
Y:
//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
}
Creo que se puede lograr una forma limpia y agradable de restar o agregar cualquier unidad de tiempo (meses, días, horas, minutos, segundos, ...) usando la clase java.time.Instant .
Ejemplo para restar 5 días de la hora actual y obtener el resultado como Fecha:
new Date(Instant.now().minus(5, ChronoUnit.DAYS).toEpochMilli());
Otro ejemplo para restar 1 hora y agregar 15 minutos:
Date.from(Instant.now().minus(Duration.ofHours(1)).plus(Duration.ofMinutes(15)));
Si necesita más precisión, la instancia mide hasta nanosegundos. Métodos que manipulan la parte de nanosegundos:
minusNano()
plusNano()
getNano()
Además, tenga en cuenta que esa Fecha no es tan precisa como Instant.
Date.from(Instant.now().minus(5, ChronoUnit.DAYS))
La segunda solución de Eli Courtwright está mal, debería ser:
Calendar c = Calendar.getInstance();
c.setTime(date);
c.add(Calendar.DATE, -days);
date.setTime(c.getTime().getTime());
addDays; Su solución es correcta. Si desea restar días de la fecha, pasa un valor negativo para days.
java.util.Calendarahora son heredadas , suplantadas por las clases java.time . Ver Tutorial de Oracle .