sumar - ¿Cómo restar X días de una fecha utilizando el calendario de Java?
restar horas en java (9)
¿Alguien sabe de manera simple usar el calendario de Java para restar X días de una fecha?
No he podido encontrar ninguna función que me permita restar directamente X días de una fecha en Java. ¿Puede alguien señalarme en la dirección correcta?
tl; dr
LocalDate.now().minusDays( 10 )
Es mejor especificar la zona horaria.
LocalDate.now( ZoneId.of( "America/Montreal" ) ).minusDays( 10 )
Detalles
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.time
Java 8 y versiones posteriores suplantan esas antiguas clases con el nuevo framework java.time. Ver Tutorial . Definido por JSR 310 , inspirado en Joda-Time , y ampliado por el proyecto ThreeTen-Extra . El proyecto ThreeTen-Backport respalda las clases en Java 6 y 7; el proyecto ThreeTenABP para Android.
La pregunta es vaga, no está clara si solicita una fecha o una fecha.
LocalDate
Para una fecha solamente, sin hora del día, use la clase LocalDate
. Tenga en cuenta que un huso horario 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, entonces use la clase Instant
para obtener un momento en la línea de tiempo en UTC . A partir de ahí, ZonedDateTime
a un huso horario para obtener un objeto ZonedDateTime
.
Instant now = Instant.now(); // UTC.
ZoneId zoneId = ZoneId.of( "America/Montreal" );
ZonedDateTime zdt = ZonedDateTime.ofInstant( instant , zoneId );
ZonedDateTime tenDaysAgo = zdt.minusDays( 10 );
Acerca de java.time
El marco java.time está integrado en Java 8 y posterior. Estas clases suplantan a las problemáticas antiguas clases legacy 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 . Y busque para obtener muchos ejemplos y explicaciones. La especificación es JSR 310 .
Puede intercambiar objetos java.time directamente con su base de datos. Use un controlador JDBC que cumpla con JDBC 4.2 o posterior. Sin necesidad de cadenas, sin necesidad de clases java.sql.*
.
¿Dónde obtener las clases de java.time?
- Java SE 8 , Java SE 9 , Java SE 10 y posterior
- Incorporado.
- Parte de la API Java estándar con una implementación integrada.
- Java 9 agrega algunas características y correcciones menores.
- Java SE 6 y Java SE 7
- Gran parte de la funcionalidad de java.time se transfiere a Java 6 y 7 en ThreeTen-Backport .
- Android
- Versiones posteriores de las implementaciones del paquete de Android de las clases java.time.
- Para Android anterior (<26), el proyecto ThreeTenABP adapta ThreeTen-Backport (mencionado anteriormente). Consulte Cómo utilizar ThreeTenABP ....
El proyecto ThreeTen-Extra amplía java.time con clases adicionales. Este proyecto es un terreno de prueba para posibles adiciones futuras a java.time. Puede encontrar algunas clases útiles aquí, como Interval
, YearWeek
, YearQuarter
y more .
Alguien recomendó Joda Time entonces - 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 en 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 realmente es una fecha (sin tener que reducirla a milisegundos o algo así). Una vez que crea la fecha, todo lo que hace para restar es algo así como myDay.addDays (-5) para retroceder 5 días. Puede usarlo para encontrar el día de la semana y cosas por el estilo. 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
}
En lugar de escribir mis propios addDays
como lo sugiere Eli, preferiría usar DateUtils
de Apache . Es útil especialmente cuando tiene que usarlo en varios lugares de su proyecto.
La API dice:
addDays(Date date, int amount)
Agrega un número de días a una fecha para devolver un nuevo objeto.
Tenga en cuenta que devuelve un nuevo objeto Date
y no realiza cambios en el anterior.
La segunda solución de Eli Courtwright es incorrecta, debería ser:
Calendar c = Calendar.getInstance();
c.setTime(date);
c.add(Calendar.DATE, -days);
date.setTime(c.getTime().getTime());
Puede usar el método add
y pasarle un número negativo. Sin embargo, también podría escribir un método más simple que no utiliza la clase Calendar
, 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 la marca de tiempo 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 de días para hacer resta. 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 objeto Date
pasado como parámetro en lugar de devolver una fecha completamente nueva. Cualquiera de las funciones podría cambiarse fácilmente para hacerlo de otra manera si así lo desea.
Se puede hacer fácilmente por el siguiente
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());
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 a:
Calendar calendar = Calendar.getInstance(); // this would default to now calendar.add(Calendar.DAY_OF_MONTH, -5).
La respuesta de Anson funcionará bien para el caso simple, pero si va a hacer cálculos de fecha más complejos, le recomiendo consultar Joda Time . Hará tu vida mucho más fácil.
FYI en Joda Time podrías hacer
DateTime dt = new DateTime();
DateTime fiveDaysEarlier = dt.minusDays(5);
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 plano:
http://java.sun.com/j2se/1.4.2/docs/api/java/util/Calendar.html#add(int , int)