Come sottrarre X day da un oggetto Date in Java?


147

Voglio fare qualcosa del tipo:

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

Come farlo?


4
Osservazione obbligatoria "Usa Joda Time".
Steve McLeod,

1
I seguenti link potrebbero esserti utili. [Inserisci la descrizione del link qui] [1] [inserisci la descrizione del link qui] [2] [1]: stackoverflow.com/questions/212321/… [2]: stackoverflow.com/questions/ 2623610 /…
Ami

Cordiali saluti, le vecchie classi problematiche di data e ora come java.util.Dateora sono legacy , soppiantate dalle classi java.time .
Basil Bourque,

Risposte:


280

Java 8 e versioni successive

Con la modifica dell'API di data e ora di Java 8, Usa LocalDate

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

Allo stesso modo puoi avere

LocalDate date = someLocalDateInstance.minusDays(300);

Fare riferimento a https://stackoverflow.com/a/23885950/260990 per la traduzione tra 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 e precedenti

Usa Calendaril add()metodo

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

22
Serve a impostare la tua data personalizzata, nel caso in cui non desideri prendere in considerazione la data corrente
Jigar Joshi,

11
La gestione della data di Java è così gonfia!
digory doo,

1
Questa è una risposta di 4 anni. sono state apportate nuove modifiche all'API DateTime apportate alle versioni recenti di esso.
Modificherò

Cordiali saluti, le classi data-ora vecchi problematici, come java.util.Date, java.util.Calendare java.text.SimpleTextFormatora sono l'eredità , soppiantato dai java.time classi. Vedi Tutorial di Oracle .
Basil Bourque,

@JigarJoshi sarebbe fantastico se aggiorni la tua risposta con l'API Java 8. La tua risposta è quella accettata che la gente vede per prima.
jotaen,

47

@JigarJoshi è la buona risposta, e ovviamente anche la raccomandazione @Tim da usare. tempo di joda .

Voglio solo aggiungere più possibilità per sottrarre giorni da a java.util.Date.

Apache-commons

Una possibilità è usare apache-commons-lang . Puoi farlo usando DateUtilscome segue:

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

Naturalmente aggiungi la commons-langdipendenza per fare solo la sottrazione della data, probabilmente non è una buona opzione, tuttavia se stai già usando commons-langè una buona scelta. Ci sono anche convenienti metodi per addYears, addMonths, addWeekse così via, date un'occhiata al api qui .

Java 8

Un'altra possibilità è quella di sfruttare le novità LocalDatedi Java 8 usando il minusDays(long days)metodo:

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

Non ha senso utilizzare LocalDateTimecome tale classe intenzionalmente non ha alcun concetto di fuso orario né offset da UTC. Usalo solo quando la zona / offset è sconosciuta o non pertinente. Invece usa LocalDatee passa a ZoneIdquando chiami il suo nowmetodo. Vedi la risposta corretta di Jacob van Lingen.
Basil Bourque,

1
@BasilBourque Dopo il tuo consiglio, controllo l'API e hai perfettamente ragione, quindi aggiorno la risposta. Grazie.
albciff,

Brian Montellano vorrebbe commento: non ci dovrebbe essere alcuna sin DateUtils, è solo DateUtil.
Ole VV,

@ OleV.V. Brian Montellano ha torto, puoi controllare i DateUtilsdocumenti
albciff

33

Basta usare questo per ottenere la data prima di 300 giorni, sostituire 300 con i giorni:

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

Qui,

DateTime è org.joda.time.DateTime;

Date è java.util.Date


7
Il progetto Joda-Time è ora in modalità manutenzione e consiglia la migrazione alle classi java.time .
Basil Bourque,

13

API Java 8 Time:

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

Voglio dire Java 8 API, non 7. E menzionare il pacchetto java.timepotrebbe aiutare. Inoltre, ci si aspetta una discussione / spiegazione su Stack Overflow piuttosto che su un semplice frammento di codice. Dovresti assolutamente spiegare Durationperché questo è il valore aggiunto della tua risposta rispetto a quella esistente di van Lingen .
Basil Bourque,

Java 8 della causa, risolto
Grigory Kislin

così vicino, ma dovrebbe essere per modificare un oggetto data arbitrario, non "ora"
bharal

9

Come puoi vedere QUI c'è molta manipolazione che puoi fare. Ecco un esempio che mostra cosa potresti fare!

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: Non ho visto la tua risposta ... Devo cancellare la mia?
waldyr.ar,

Cordiali saluti, le vecchie classi data-ora terribilmente fastidiose come java.util.Date, java.util.Calendare java.text.SimpleDateFormatora sono legacy , soppiantate dalle classi java.time integrate in Java 8 e versioni successive. Vedi Tutorial di Oracle .
Basil Bourque,

9

Con Java 8 è davvero semplice ora:

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

Una grande guida alla nuova API può essere trovata qui .


4
Suggerisco di passare sempre il fuso orario opzionale (o offset-da-UTC) a quel nowmetodo. Se omesso, l'attuale fuso orario predefinito della JVM viene applicato in modo implicito e silenzioso. Tale impostazione predefinita è al di fuori del tuo controllo e può cambiare in qualsiasi momento, anche durante il runtime. Esempio: LocalDate.now( ZoneId.of( "America/Montreal" ).
Basil Bourque,

deve essere su un oggetto data arbitrario secondo la domanda, non "ora"
bharal

1

Ho creato una funzione per semplificare l'attività.

  • Per 7 giorni dopo la data dateCalculate(dateString,"yyyy-MM-dd",7);

  • Per ottenere 7 giorni aggiornati String: 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());
}

Questo utilizza Risposta fastidioso classi scendere Data-time come java.util.Date, java.util.Calendare java.text.SimpleDateFormatche ora sono l'eredità , soppiantato dai java.time classi. Vedi Tutorial di Oracle .
Basil Bourque,

La domanda riguarda oggetti data-ora, non la generazione di stringhe. A proposito, LocalDate.parse( "2017-01-23").plusWeeks( 1 )è più semplice che scrivere il tuo metodo ed è più auto-documentante.
Basil Bourque,

0

Puoi sottrarre facilmente con il 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
Benvenuti in SO. Si prega di astenersi dal rispondere solo al codice. Vedi stackoverflow.com/help/how-to-answer . E per favore formatta il tuo codice.
Uwe Allner,
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.