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_MONTH
en este caso ya que no manejará el rollo entre meses como le gustaría. Usar en su Calendar.DAY_OF_YEAR
lugar
Podrías usar el add
método y pasarle un número negativo. Sin embargo, también podría escribir un método más simple que no use la Calendar
clase 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 Date
objeto 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.Calendar
ahora 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.
LocalDate
Para una fecha solamente, sin hora del día, use la LocalDate
clase. 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 );
ZonedDateTime
Si se refería a una fecha y hora, use la Instant
clase para obtener un momento en la línea de tiempo en UTC . Desde allí, ajústese a una zona horaria para obtener un ZonedDateTime
objeto.
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 addDays
como lo sugiere Eli, preferiría usarlo DateUtils
desde 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 Date
objeto 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());
LocalDate
es 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.Calendar
ahora son heredadas , suplantadas por las clases java.time . Ver Tutorial de Oracle .