Wie subtrahiere ich X Tag von einem Datumsobjekt in Java?


146

Ich möchte so etwas tun wie:

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

Wie es geht?


4
Obligatorische Bemerkung "Use Joda Time".
Steve McLeod

1
Die folgenden Links könnten für Sie nützlich sein. [ Linkbeschreibung hier eingeben] [1] [ Linkbeschreibung hier eingeben] [2] [1]: stackoverflow.com/questions/212321/… [2]: stackoverflow.com/questions/ 2623610 /…
Ami

Zu Ihrer Information , die problematischen alten Datums- / Uhrzeitklassen, wie sie java.util.Datejetzt Legacy sind , werden durch die Klassen java.time ersetzt .
Basil Bourque

Antworten:


279

Java 8 und höher

Mit der Änderung der Datums- und Uhrzeit-API von Java 8 verwenden Sie LocalDate

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

Ebenso können Sie haben

LocalDate date = someLocalDateInstance.minusDays(300);

Unter https://stackoverflow.com/a/23885950/260990 finden Sie eine Übersetzung zwischen 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 und früher

Verwenden Sie Calendardie add()Methode von

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

22
Es ist Ihre benutzerdefinierte dateInstance festzulegen, falls Sie die aktuelle Datumszeit nicht berücksichtigen möchten
Jigar Joshi

11
Javas Datumsbehandlung ist so aufgebläht!
Digory Doo

1
Dies ist eine 4 Jahre alte Antwort. In den letzten Versionen wurden neue Änderungen an der DateTime-API vorgenommen. Ich werde die Antwort bearbeiten
Jigar Joshi

Zu Ihrer Information, die störenden alten Datum Zeitklassen wie java.util.Date, java.util.Calendarund java.text.SimpleTextFormatsind jetzt Erbe , durch die verdrängte java.time Klassen. Siehe Tutorial von Oracle .
Basil Bourque

@JigarJoshi Es wäre großartig, wenn Sie Ihre Antwort mit der Java 8-API aktualisieren würden. Ihre Antwort ist die akzeptierte, die die Leute zuerst sehen.
Jotaen

47

@JigarJoshi es ist die gute Antwort und natürlich auch @ Tim Empfehlung zu verwenden. Joda-Zeit .

Ich möchte nur weitere Möglichkeiten hinzufügen, um Tage von a zu subtrahieren java.util.Date.

Apache-Commons

Eine Möglichkeit ist die Verwendung von apache-commons-lang . Sie können dies DateUtilsfolgendermaßen tun :

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

Natürlich fügen Sie die commons-langAbhängigkeit hinzu, um nur das Datum zu subtrahieren. Dies ist wahrscheinlich keine gute Option. Wenn Sie sie jedoch bereits verwenden commons-lang, ist dies eine gute Wahl. Es gibt auch praktische Möglichkeiten zu addYears, addMonths, addWeeksund so weiter, einen Blick auf die nehmen hier api .

Java 8

Eine andere Möglichkeit besteht darin, die Vorteile LocalDatevon Java 8 mithilfe der folgenden minusDays(long days)Methode zu nutzen:

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

Es macht keinen Sinn, LocalDateTimediese Klasse absichtlich zu verwenden, da sie weder ein Konzept der Zeitzone noch einen Versatz von UTC hat. Verwenden Sie dies nur, wenn Zone / Versatz unbekannt oder nicht relevant ist. Verwenden Sie stattdessen a LocalDateund übergeben Sie es, ZoneIdwenn Sie die nowMethode aufrufen . Siehe die richtige Antwort von Jacob van Lingen.
Basil Bourque

1
@BasilBourque Nach deinem Rat überprüfe ich die API und du hast vollkommen recht, daher aktualisiere ich die Antwort. Vielen Dank.
Albciff

Brian Montellano würde Kommentar mag: es nicht sein sollte , sin DateUtils, es ist nur DateUtil.
Ole VV

@ OleV.V. Brian Montellano ist falsch, Sie können die DateUtilsDokumente überprüfen
Albciff

33

Verwenden Sie dies einfach, um ein Datum vor 300 Tagen zu erhalten, und ersetzen Sie 300 durch Ihre Tage:

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

Hier,

DateTime ist org.joda.time.DateTime;

Date ist java.util.Date


7
Das Joda-Time- Projekt befindet sich jetzt im Wartungsmodus und empfiehlt die Migration zu den Klassen java.time .
Basil Bourque

13

Java 8 Time API:

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

Ich muss Java 8 API meinen, nicht 7. Und das Erwähnen des Pakets java.timekönnte helfen. Außerdem wird im Allgemeinen eine Diskussion / Erklärung zum Stapelüberlauf erwartet und nicht nur ein Code-Snippet. Sie sollten auf jeden Fall erklären Duration, dass dies der Mehrwert Ihrer Antwort gegenüber der bestehenden von van Lingen ist .
Basil Bourque

Java 8 der Ursache, behoben
Grigory Kislin

so nah, sollte aber zum Ändern eines beliebigen
Datumsobjekts dienen

9

Wie Sie HIER sehen können, können Sie viel manipulieren. Hier ein Beispiel, das zeigt, was Sie tun können!

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: Ich habe deine Antwort nicht gesehen ... Soll ich meine löschen?
Waldyr.ar

Zu Ihrer Information, die furchtbar lästig alten Datum Zeitklassen wie java.util.Date, java.util.Calendarund java.text.SimpleDateFormatsind jetzt Erbe , durch die verdrängte java.time Klassen in Java gebaut 8 und höher. Siehe Tutorial von Oracle .
Basil Bourque

9

Mit Java 8 ist es jetzt ganz einfach:

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

Eine großartige Anleitung zur neuen API finden Sie hier .


4
Ich schlage vor, immer die optionale Zeitzone (oder den Versatz von UTC) an diese nowMethode zu übergeben. Wenn nicht angegeben, wird die aktuelle Standardzeitzone der JVM implizit und stillschweigend angewendet. Dass Standard liegt außerhalb Ihrer Kontrolle und kann sich jederzeit ändern, auch während der Laufzeit. Beispiel : LocalDate.now( ZoneId.of( "America/Montreal" ).
Basil Bourque

muss sich auf einem beliebigen
Datumsobjekt

1

Ich habe eine Funktion erstellt, um die Aufgabe zu vereinfachen.

  • Für 7 Tage nach dateString: dateCalculate(dateString,"yyyy-MM-dd",7);

  • Um 7 Tage auf dem neuesten Stand zu seinString: 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());
}

Diese Antwort Anwendungen lästig alte Datum Zeitklassen wie java.util.Date, java.util.Calendarund java.text.SimpleDateFormatdas ist jetzt Erbe , durch die verdrängte java.time Klassen. Siehe Tutorial von Oracle .
Basil Bourque

Die Frage umfasst Datums- / Uhrzeitobjekte, die keine Zeichenfolgen generieren. Übrigens LocalDate.parse( "2017-01-23").plusWeeks( 1 )ist einfacher als das Schreiben einer eigenen Methode und selbstdokumentierender.
Basil Bourque

0

Mit SimpleDateFormat können Sie ganz einfach mit dem Kalender subtrahieren

 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
Willkommen bei SO. Bitte unterlassen Sie nur Code-Antworten. Siehe stackoverflow.com/help/how-to-answer . Und bitte formatieren Sie Ihren Code.
Uwe Allner
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.