it-swarm.com.de

Java: Der einfachste Weg, um Datumsangaben abzuziehen

Ich habe eine Klasse mit zwei Feldern erstellt, die Datumsangaben sein müssen, start_date und date_passed. Ich habe nach dem besten Weg in Java gesucht, Datumsangaben in einem YYYY MM DD-Format zu haben, das eine einfache Datumsabzug ermöglicht und die Möglichkeit, ein Datum "aufzubereiten", beispielsweise in der Zukunft.

Beispiel für das, was ich gerne machen würde ...

library.circulate_book("Chemistry", **start date here**) //actual date or random date
library.pass_book("Chemistry", **Date Passed here**) //random date such as 5 days after start date
int days_had = Date_Passed - start_date

Bis jetzt habe ich viele Möglichkeiten gefunden, Datumsangaben mit Hilfe von Kalendern und Datumsklassen zu formatieren. Ich habe jedoch noch keinen gefunden, der so aussieht, als würde er funktionieren, wenn man bedenkt, dass die meisten Datumsangaben als Strings enden. Anregungen/kleine Beispiele werden sehr geschätzt! Auch Links zu Beispielen wären fantastisch!

8
Bob

tl; dr

Um von einem Datum zu einem anderen zu wechseln, indem Sie eine Anzahl von Tagen hinzufügen/subtrahieren.

LocalDate.now(
    ZoneId.of( "Pacific/Auckland" ) 
)
.minusDays( 5 )

So berechnen Sie die Anzahl der Tage, Monate und Jahre zwischen zwei Datumsangaben. 

Period.between( start , stop )

Parsing

Zuerst müssen Sie Ihre String-Eingaben in Datum-Uhrzeit-Objekte analysieren. Dann bearbeiten Sie Ihre Geschäftslogik mit diesen Objekten. 

Hören Sie auf, Datums- und Uhrzeitwerte als Zeichenfolgen zu betrachten, die Sie verrückt machen. Wir arbeiten mit Datum-Uhrzeit-Objekten in unserem Code. Wir tauschen Daten mit Benutzern oder anderen Apps aus, indem Sie eine String-Darstellung dieses Datums/Zeit-Objekts verwenden. 

Verwenden Sie in Java 8 und höher das Java.time - Framework. Siehe Tutorial

Sie möchten nur ein Datum ohne Uhrzeit, damit wir die LocalDate -Klasse verwenden können.

Diese funky-Doppelpunkt-Syntax ist eine Methodenreferenz , eine Art zu sagen, welche Methode von anderem Code aufgerufen werden soll.

String input = "2015 01 02";
DateTimeFormatter formatter = DateTimeFormatter.ofPattern ( "yyyy MM dd" );
LocalDate localDate = formatter.parse ( input , LocalDate :: from );

Aktuelles Datum

Um das heutige Datum zu bestimmen, ist eine Zeitzone erforderlich. Für jeden Moment variiert das Datum auf der ganzen Welt nach Zone. 

ZoneId z = ZoneId.of( "Africa/Tunis" ) ;
LocalDate todayTunis = LocalDate.now( z ) ;

Wenn Sie die aktuelle Standardzeitzone der JVM verwenden möchten, rufen Sie ZoneId.systemDefault auf.

Datum abziehen

Dies wurde schon mehrfach auf StackOveflow.com angesprochen. Zum Beispiel: Wie subtrahiert man X-Tage mit einem Java-Kalender von einem Datum? . Weitere Informationen finden Sie in anderen Antworten wie dieses von mir und dieses von mir für weitere Details. Tipp: "abgelaufen" ist ein Suchwort.

Verwenden Sie kurz eine Period , um eine Anzahl von Standardtagen, Monaten und Jahren zu definieren.

LocalDate weekLater = localDate.plusDays ( 7 );
Period period = Period.between ( localDate , weekLater );
Integer daysElapsed = period.getDays ();

Auf die Konsole ausgeben.

System.out.println ( "localDate: " + localDate + " to " + weekLater + " in days: " + daysElapsed );

localDate: 2015-01-02 bis 2015-01-09 in Tagen: 7

Beachten Sie die Einschränkung, dass Period nur für ganze Tage funktioniert, d. H. Nur Datumswerte ohne Tageszeit. Das ist es, was wir hier für diese Frage brauchen, also erledigt. Wenn Sie Datums-/Uhrzeitwerte (ZonedDateTime-Objekte) hatten, verwenden Sie die Days-Klasse des ThreeTen-Extra -Projekts, wie oben in der verknüpften Frage/Antwort angegeben.

10
Basil Bourque

Der beste Weg, dies in Java-8 zu tun, ist nicht die fehlerhafte Antwort von Basil Bourque, sondern dieser Ansatz:

String startDate = "2016 01 02";
String passedDate = "2016 02 29";

DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy MM dd");
LocalDate date1 = LocalDate.parse(startDate, formatter);
LocalDate date2 = LocalDate.parse(passedDate, formatter);

long elapsedDays = ChronoUnit.DAYS.between(date1, date2);
System.out.println(elapsedDays); // 58 (correct)

Die vorgeschlagene Verwendung von Java.time.Period.getDays() ist gefährlich und häufig falsch, sobald die verstrichene Dauer einen Monat überschreitet. Der ganze Periodist P1M27D, daher fragt dieser Code effektiv nur die Teilmenge der verstrichenen Tage ab (es gibt auch einen verstrichenen Monat):

System.out.println(Period.between(date1, date2).getDays()); // 27 (WRONG!!!)

Eine zufriedenstellende Lösung mit den Klassen Java.util.Date, GregorianCalendarusw. ist schwer zu finden. Sie können die Antwort von Tacktheritrix verwenden, müssen sich jedoch der Tatsache bewusst sein, dass die berechnete Anzahl der verstrichenen Tage aufgrund der Untertageteile von Java.util.Date unterschiedlich sein kann und aufgrund der Nichteinhaltung der Schalter für die Einstellung des Tageslichts nicht zuverlässig ist (wo die Uhr in vielen Teilen der Welt um eine Stunde springt).

Randbemerkung: Mindestens 8 externe Bibliotheken bieten auch gute Antworten auf Ihr Problem. Ich denke jedoch, Ihr einfacher Anwendungsfall rechtfertigt das Einbetten einer zusätzlichen Bibliothek nicht, es sei denn, Sie sind noch nicht auf Java-8. Eine alternative Lösung zum Zählen der verstrichenen Tage zwischen zwei Datumsangaben wäre nicht einfacher als in Java-8 - nur ähnlich. Und da Sie die auf Java-8 bezogene Antwort von Basil Bourque akzeptiert haben, gehe ich davon aus, dass Sie sich tatsächlich auf Java-8 befinden. Ich lasse die Antwort aus, wie Sie Ihr Problem mit anderen Bibliotheken lösen können.

8
Meno Hochschild

verwenden Sie Java 8 Date API oder Joda, keine neuen Erfindungen erforderlich.

beispiele finden Sie hier: http://examples.javacodegeeks.com/core-Java/java-8-datetime-api-tutorial/

2
Emerson Cod

Hier ist eine Antwort mit Calendar:

Calendar cal = Calendar.getInstance();
Calendar cal2 = Calendar.getInstance();

cal2.setTime(cal.getTime());
cal2.add(Calendar.DAY_OF_YEAR, 5);
System.out.println((cal2.getTimeInMillis() - cal.getTimeInMillis()) / (1000d * 60 * 60 * 24));
1
Evan LaHurd

Wenn Sie ein älteres Java verwenden, können Sie SimpleDateFormat verwenden.

    //For substraction
    long differenceInMillis = date1.getTime() - date2.getTime();

    //Date Format
    SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy MM dd");
    String dateAsString = dateFormat.format(date1); //To get a text representation
    Date dateParsed = dateFormat.parse(dateAsString); //To get it back as date
0
liloargana