Antworten:
Aus den Dokumenten hier entnommen :
Addiert oder subtrahiert die angegebene Zeit zum angegebenen Kalenderfeld, basierend auf den Regeln des Kalenders. Um beispielsweise 5 Tage von der aktuellen Uhrzeit des Kalenders abzuziehen, können Sie dies erreichen, indem Sie Folgendes aufrufen:
Calendar calendar = Calendar.getInstance(); // this would default to now calendar.add(Calendar.DAY_OF_MONTH, -5).
Calendar.DAY_OF_MONTH
in diesem Fall nicht verwenden , da die Rolle zwischen den Monaten nicht so verarbeitet wird, wie Sie es möchten. Verwenden Sie Calendar.DAY_OF_YEAR
stattdessen
Sie können die add
Methode verwenden und eine negative Zahl übergeben. Sie können jedoch auch eine einfachere Methode schreiben, die die Calendar
Klasse nicht verwendet , wie die folgende
public static void addDays(Date d, int days)
{
d.setTime( d.getTime() + (long)days*1000*60*60*24 );
}
Dadurch wird der Zeitstempelwert des Datums (Millisekunden seit der Epoche) abgerufen und die richtige Anzahl von Millisekunden hinzugefügt. Sie können eine negative Ganzzahl für den Parameter days übergeben, um die Subtraktion durchzuführen. Dies wäre einfacher als die "richtige" Kalenderlösung:
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() );
}
Beachten Sie, dass beide Lösungen Date
das als Parameter übergebene Objekt ändern, anstatt ein völlig neues zurückzugeben Date
. Jede Funktion kann leicht geändert werden, um sie auf Wunsch auch andersherum auszuführen.
java.util.Calendar
jetzt Legacy sind , werden durch die Klassen java.time ersetzt . Siehe Tutorial von Oracle .
Ansons Antwort wird für den einfachen Fall gut funktionieren, aber wenn Sie komplexere Datumsberechnungen durchführen möchten, würde ich empfehlen, Joda Time zu überprüfen . Es wird Ihr Leben viel einfacher machen.
Zu Ihrer Information in Joda Time, die Sie tun könnten
DateTime dt = new DateTime();
DateTime fiveDaysEarlier = dt.minusDays(5);
LocalDate.now().minusDays( 10 )
Besser Zeitzone angeben.
LocalDate.now( ZoneId.of( "America/Montreal" ) ).minusDays( 10 )
Die alten Datums- / Uhrzeitklassen, die mit früheren Java-Versionen wie java.util.Date
/ gebündelt sind .Calendar
, haben sich als problematisch, verwirrend und fehlerhaft erwiesen. Vermeide sie.
Java 8 und höher ersetzt diese alten Klassen durch das neue java.time-Framework. Siehe Tutorial . Definiert von JSR 310 , inspiriert von Joda-Time und erweitert durch das ThreeTen-Extra- Projekt. Das ThreeTen-Backport-Projekt portiert die Klassen zurück zu Java 6 & 7; das ThreeTenABP-Projekt für Android.
Die Frage ist vage und nicht klar, ob sie nur ein Datum oder eine Uhrzeit erfordert.
LocalDate
Verwenden Sie die LocalDate
Klasse nur für ein Datum ohne Uhrzeit . Beachten Sie, dass eine Zeitzone für die Bestimmung eines Datums wie "Heute" von entscheidender Bedeutung ist.
LocalDate today = LocalDate.now( ZoneId.of( "America/Montreal" ) );
LocalDate tenDaysAgo = today.minusDays( 10 );
ZonedDateTime
Wenn Sie eine Datums- und Uhrzeitangabe gemeint haben, verwenden Sie die Instant
Klasse, um einen Moment auf der Zeitachse in UTC abzurufen . Passen Sie von dort aus eine Zeitzone an, um ein ZonedDateTime
Objekt zu erhalten.
Instant now = Instant.now(); // UTC.
ZoneId zoneId = ZoneId.of( "America/Montreal" );
ZonedDateTime zdt = ZonedDateTime.ofInstant( instant , zoneId );
ZonedDateTime tenDaysAgo = zdt.minusDays( 10 );
Das java.time- Framework ist in Java 8 und höher integriert. Diese Klassen verdrängen die lästigen alten Legacy - Datum-Zeit - Klassen wie java.util.Date
, Calendar
, & SimpleDateFormat
.
Das Joda-Time- Projekt, das sich jetzt im Wartungsmodus befindet , empfiehlt die Migration zu den Klassen java.time .
Weitere Informationen finden Sie im Oracle-Lernprogramm . Suchen Sie im Stapelüberlauf nach vielen Beispielen und Erklärungen. Die Spezifikation ist JSR 310 .
Sie können java.time- Objekte direkt mit Ihrer Datenbank austauschen . Verwenden Sie einen JDBC-Treiber, der mit JDBC 4.2 oder höher kompatibel ist . Keine Notwendigkeit für Zeichenfolgen, keine Notwendigkeit für java.sql.*
Klassen.
Woher bekomme ich die java.time-Klassen?
Das ThreeTen-Extra- Projekt erweitert java.time um zusätzliche Klassen. Dieses Projekt ist ein Testfeld für mögliche zukünftige Ergänzungen von java.time. Sie können einige nützliche Klassen hier wie finden Interval
, YearWeek
, YearQuarter
, und mehr .
int x = -1;
Calendar cal = ...;
cal.add(Calendar.DATE, x);
edit: Der Parser scheint den Link zum Javadoc nicht zu mögen, also hier im Klartext:
http://java.sun.com/j2se/1.4.2/docs/api/java/util/Calendar.html#add(int , int)
Anstatt meine eigenen zu schreiben, addDays
wie von Eli vorgeschlagen, würde ich lieber DateUtils
von Apache verwenden . Dies ist besonders praktisch, wenn Sie es an mehreren Stellen in Ihrem Projekt verwenden müssen.
Die API sagt:
addDays(Date date, int amount)
Fügt einem Datum, das ein neues Objekt zurückgibt, eine Anzahl von Tagen hinzu.
Beachten Sie, dass ein neues Date
Objekt zurückgegeben wird und keine Änderungen am vorherigen selbst vorgenommen werden.
Dies kann auf einfache Weise wie folgt durchgeführt werden
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
ist viel einfacher und angemessener.
Jemand hat Joda Time empfohlen - ich habe diese CalendarDate- Klasse http://calendardate.sourceforge.net verwendet
Es ist ein etwas konkurrierendes Projekt für Joda Time, aber viel grundlegender in nur 2 Klassen. Es ist sehr praktisch und hat hervorragend für das funktioniert, was ich brauchte, da ich kein größeres Paket als mein Projekt verwenden wollte. Im Gegensatz zu den Java-Gegenstücken ist die kleinste Einheit der Tag, also ist es wirklich ein Datum (ohne Millisekunden oder so). Sobald Sie das Datum erstellt haben, müssen Sie nur noch myDay.addDays (-5) subtrahieren, um 5 Tage zurück zu gehen. Sie können es verwenden, um den Wochentag und ähnliche Dinge zu finden. Ein anderes Beispiel:
CalendarDate someDay = new CalendarDate(2011, 10, 27);
CalendarDate someLaterDay = today.addDays(77);
Und:
//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
}
Ich glaube, dass mit der Klasse java.time.Instant eine saubere und nette Methode zum Subtrahieren oder Addieren einer beliebigen Zeiteinheit (Monate, Tage, Stunden, Minuten, Sekunden, ...) erreicht werden kann .
Beispiel für das Subtrahieren von 5 Tagen von der aktuellen Zeit und das Abrufen des Ergebnisses als Datum:
new Date(Instant.now().minus(5, ChronoUnit.DAYS).toEpochMilli());
Ein weiteres Beispiel zum Subtrahieren von 1 Stunde und Addieren von 15 Minuten:
Date.from(Instant.now().minus(Duration.ofHours(1)).plus(Duration.ofMinutes(15)));
Wenn Sie mehr Genauigkeit benötigen, misst Instance bis zu Nanosekunden. Methoden zur Manipulation des Nanosekunden-Teils:
minusNano()
plusNano()
getNano()
Beachten Sie auch, dass das Datum nicht so genau ist wie Instant.
Date.from(Instant.now().minus(5, ChronoUnit.DAYS))
Eli Courtwright zweite Lösung ist falsch, es sollte sein:
Calendar c = Calendar.getInstance();
c.setTime(date);
c.add(Calendar.DATE, -days);
date.setTime(c.getTime().getTime());
addDays
: seine Lösung ist richtig. Wenn Sie Tage vom Datum abziehen möchten, übergeben Sie einen negativen Wert für days
.
java.util.Calendar
jetzt Legacy sind , werden durch die Klassen java.time ersetzt . Siehe Tutorial von Oracle .