¿Cómo restar X day de un objeto Date en Java?


147

Quiero hacer algo como:

Date date = new Date(); // current date
date = date - 300; // substract 300 days from current date and I want to use this "date"

¿Cómo hacerlo?


44
Comentario obligatorio "Use Joda Time".
Steve McLeod

1
Los siguientes enlaces pueden ser útiles para usted. [Ingrese la descripción del enlace aquí] [1] [ingrese la descripción del enlace aquí] [2] [1]: stackoverflow.com/questions/212321/… [2]: stackoverflow.com/questions/ 2623610 /…
Ami

Para su información, las viejas clases problemáticas de fecha y hora, como java.util.Dateahora son heredadas , suplantadas por las clases java.time .
Basil Bourque

Respuestas:


280

Java 8 y posterior

Con el cambio de API de fecha y hora de Java 8, use LocalDate

LocalDate date = LocalDate.now().minusDays(300);

Del mismo modo puedes tener

LocalDate date = someLocalDateInstance.minusDays(300);

Consulte https://stackoverflow.com/a/23885950/260990 para la traducción entre java.util.Date <--> java.time.LocalDateTime

Date in = new Date();
LocalDateTime ldt = LocalDateTime.ofInstant(in.toInstant(), ZoneId.systemDefault());
Date out = Date.from(ldt.atZone(ZoneId.systemDefault()).toInstant());

Java 7 y versiones anteriores

Use Calendarel add()método

Calendar cal = Calendar.getInstance();
cal.setTime(dateInstance);
cal.add(Calendar.DATE, -30);
Date dateBefore30Days = cal.getTime();

22
Es para configurar su fecha de entrada personalizada en caso de que no quiera considerar la fecha y hora actual
Jigar Joshi

11
¡El manejo de la fecha de Java está tan hinchado!
digory doo

1
Esta es la respuesta de 4 años. se han realizado nuevos cambios en la API de DateTime a versiones recientes de la misma. Editaré la respuesta
Jigar Joshi

Para su información, las clases de fecha y hora viejas problemáticas tales como java.util.Date, java.util.Calendary java.text.SimpleTextFormatahora están legado , suplantados por los java.time clases. Ver Tutorial de Oracle .
Basil Bourque

@JigarJoshi sería genial si actualizaras tu respuesta con la API de Java 8. Su respuesta es la aceptada que la gente ve primero.
jotaen

47

@JigarJoshi es la buena respuesta, y por supuesto también la recomendación de @Tim para usar. joda-time .

Solo quiero agregar más posibilidades para restar días de a java.util.Date.

Apache-commons

Una posibilidad es usar apache-commons-lang . Puedes hacerlo usando DateUtilslo siguiente:

Date dateBefore30Days = DateUtils.addDays(new Date(),-30);

Por supuesto, agregue la commons-langdependencia para hacer solo restar fecha, probablemente no sea una buena opción, sin embargo, si ya está usando commons-lang, es una buena opción. También hay métodos convenientes a addYears, addMonths, addWeeksy así sucesivamente, echar un vistazo a la API aquí .

Java 8

Otra posibilidad es aprovechar las novedades LocalDatede Java 8 utilizando el minusDays(long days)método:

LocalDate dateBefore30Days = LocalDate.now(ZoneId.of("Europe/Paris")).minusDays(30);

No tiene sentido usarlo, LocalDateTimeya que esa clase no tiene un concepto de zona horaria ni compensación de UTC. Úselo solo cuando la zona / desplazamiento es desconocida o no relevante. En su lugar, use LocalDatey pase un ZoneIdal llamar a su nowmétodo. Ver la respuesta correcta de Jacob van Lingen.
Basil Bourque

1
@BasilBourque Después de su consejo, verifico la API y tiene toda la razón, por lo tanto, actualizo la respuesta. Gracias.
albciff

Brian Montellano gustaría comentar: no debe haber ninguna sen DateUtils, es sólo DateUtil.
Ole VV

@ OleV.V. Brian Montellano está equivocado, puedes consultar los DateUtilsdocumentos
albciff

33

Simplemente use esto para obtener la fecha antes de 300 días, reemplace 300 con sus días:

Date date = new Date(); // Or where ever you get it from
Date daysAgo = new DateTime(date).minusDays(300).toDate();

Aquí,

DateTime es org.joda.time.DateTime;

Date es java.util.Date


77
El proyecto Joda-Time ahora está en modo de mantenimiento y aconseja la migración a las clases java.time .
Basil Bourque

13

API de Java 8 Time:

Instant now = Instant.now(); //current date
Instant before = now.minus(Duration.ofDays(300));
Date dateBefore = Date.from(before);

Debo decir Java 8 API, no 7. Y mencionar el paquete java.timepodría ayudar. Además, generalmente se espera alguna discusión / explicación en Stack Overflow en lugar de solo un fragmento de código. Definitivamente debe explicar, Durationya que ese es el valor agregado de su Respuesta sobre la existente de van Lingen .
Basil Bourque

Java 8 de causa, fijada
Grigory Kislin

tan cerca, pero debería ser para modificar un objeto de fecha arbitraria, no "ahora"
bharal

9

Como puede ver AQUÍ, hay mucha manipulación que puede hacer. ¡Aquí un ejemplo que muestra lo que puedes hacer!

DateFormat dateFormat = new SimpleDateFormat("yyyy/MM/dd HH:mm:ss");
Calendar cal = Calendar.getInstance();

//Add one day to current date.
cal.add(Calendar.DATE, 1);
System.out.println(dateFormat.format(cal.getTime()));

//Substract one day to current date.
cal = Calendar.getInstance();
cal.add(Calendar.DATE, -1);
System.out.println(dateFormat.format(cal.getTime()));

/* Can be Calendar.DATE or
*  Calendar.MONTH, Calendar.YEAR, Calendar.HOUR, Calendar.SECOND
*/

@Jigar Joshi: No vi tu respuesta ... ¿Debo eliminar la mía?
waldyr.ar

Para su información, las antiguas clases de fecha y hora terriblemente problemáticas como java.util.Date, java.util.Calendary java.text.SimpleDateFormatahora son heredadas , suplantadas por las clases java.time integradas en Java 8 y posteriores. Ver Tutorial de Oracle .
Basil Bourque

9

Con Java 8 es realmente simple ahora:

 LocalDate date = LocalDate.now().minusDays(300);

Una gran guía para la nueva API se puede encontrar aquí .


44
Sugiero pasar siempre la zona horaria opcional (o offset-from-UTC) a ese nowmétodo. Si se omite, la zona horaria predeterminada actual de la JVM se aplica implícita y silenciosamente. Ese valor predeterminado queda fuera de su control y puede cambiar en cualquier momento, incluso durante el tiempo de ejecución. Ejemplo: LocalDate.now( ZoneId.of( "America/Montreal" ).
Basil Bourque

debe estar en un objeto de fecha arbitraria según la pregunta, no "ahora"
bharal

1

He creado una función para facilitar la tarea.

  • Durante 7 días después de la fecha dateCalculate(dateString,"yyyy-MM-dd",7);

  • Para obtener 7 días hasta la fecha dateCalculate(dateString,"yyyy-MM-dd",-7);


public static String dateCalculate(String dateString, String dateFormat, int days) {
    Calendar cal = Calendar.getInstance();
    SimpleDateFormat s = new SimpleDateFormat(dateFormat);
    try {
        cal.setTime(s.parse(dateString));
    } catch (ParseException e) {
        e.printStackTrace();
    }
    cal.add(Calendar.DATE, days);
    return s.format(cal.getTime());
}

Esta respuesta usos problemáticos clases pasadas de fecha y hora como java.util.Date, java.util.Calendary java.text.SimpleDateFormatque ahora están legado , suplantados por los java.time clases. Ver Tutorial de Oracle .
Basil Bourque

La pregunta involucra objetos de fecha y hora, no generar cadenas. Por cierto, LocalDate.parse( "2017-01-23").plusWeeks( 1 )es más simple que escribir su propio método y es más autodocumentado.
Basil Bourque

0

Puede restar fácilmente con el calendario con SimpleDateFormat

 public static String subtractDate(String time,int subtractDay) throws ParseException {


        Calendar cal = Calendar.getInstance();
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm", Locale.ENGLISH);
        cal.setTime(sdf.parse(time));
        cal.add(Calendar.DATE,-subtractDay);
        String wantedDate = sdf.format(cal.getTime());

        Log.d("tag",wantedDate);
        return wantedDate;

    }

-4
c1.set(2017, 12 , 01); //Ex: 1999 jan 20    //System.out.println("Date is : " + sdf.format(c1.getTime()));
  c1.add(Calendar.MONTH, -2); // substract 1 month
  System.out.println
  ("Date minus 1 month : "
      + sdf.format(c1.getTime()));

2
Bienvenido a SO. Por favor, abstenerse de código solo respuestas. Ver stackoverflow.com/help/how-to-answer . Y por favor formatee su código.
Uwe Allner el
Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.