2009-01-17 8 views
17

Ich finde es witzig, dass Java (oder die java.util-Bibliothek) keine eingebaute Funktion hat, um Unterschiede in Daten zu berechnen. Ich möchte ein Datum von einem anderen subtrahieren, um die verstrichene Zeit zwischen ihnen zu erhalten. Was ist der beste Weg, dies zu tun?Differenz in Datumsangaben in Java berechnen

Ich weiß, der einfache Weg ist, die Differenz der Zeit in Millisekunden zu nehmen und diese in Tage zu konvertieren. Ich wollte jedoch wissen, ob dies in allen Fällen (mit Sommerzeit usw.) funktioniert.

+2

Siehe http://www.xmission.com/~goodhill/dates/deltaDates.html für einige Hintergrundinformationen. –

+0

Das ist ein schöner Artikel. Vielen Dank! – Anirudh

+0

@Anirudh Suche StackOverflow für "joda" und Begriff wie "span", "Intervall", "Dauer", "Zeitraum". Sie finden viele Beispiele mit Diskussion. –

Antwort

6

Ich weiß, die auf einfache Weise die Differenz der Zeit in Millisekunden zu nehmen ist, und dann, dass in Tagen umwandeln. Allerdings wollte ich wissen, ob dies in allen Fällen funktioniert (mit Tageslicht speichern, etc.).

Wenn Ihre Zeiten von UTC Daten abgeleitet sind, oder sie sind nur die Differenz zwischen zwei Anrufen zu System.getCurrentTimeMillis() auf dem gleichen System gemessen, erhalten Sie eine gültige Anzahl von Millisekunden als die Differenz erhalten, unabhängig von Alle Zeitzonenprobleme. (Aus diesem Grund sollte UTC als Speicherformat verwendet werden - es ist viel einfacher, von UTC-> Ortszeit zu wechseln; wenn Sie versuchen, in die andere Richtung zu gehen, müssen Sie die lokale Zeitzone zusammen mit der Ortszeit speichern.) oder versuchen Sie es abzuleiten, gack!)

Um dies in eine Anzahl von Tagen zu verwandeln, sollten Sie nur in der Lage sein, durch 86400000 zu dividieren ... mit der Einschränkung, dass es gelegentlich alle ein Jahr oder so leap second gibt.

8

Java fehlt nicht viel, wenn Sie Open Source betrachten: versuchen Joda-Time.

+3

Frage zu Java Datum ==> Antwort erwähnt Joda! –

+1

Ja, so funktioniert es, wenn eine Sprache zwei defekte Datum/Uhrzeit-Klassen hat. – krosenvold

+0

Ich schaute auf Joda - leider kann ich nicht-Standard-Bibliotheken verwenden :( – Anirudh

0

Java Implementierung von Daten ist arm. Wenn Sie Joda-Time zu kompliziert finden, versuchen Sie meinen kleinen Beitrag zur Open Source:

0

Ich stimme nicht mit der Behauptung, dass Java hat keinen Mechanismus zur Berechnung der Differenz zwischen Daten.

Java wurde für den globalen Einsatz entwickelt. Es wurde so entworfen, dass es kein Konzept des Datums gibt, es gibt nur ein Konzept von "Zeit in Millisekunden". Jede Interpretation einer solchen universellen Zeit als Zeit-und-Datum an einem bestimmten Ort unter einer bestimmten Konvention ist lediglich eine Projektion oder eine Ansicht.

Die Kalenderklasse wird verwendet, um diese Art absoluter Zeit in Daten umzuwandeln. Sie können Datumskomponenten auch hinzufügen oder abziehen, wenn Sie dies wirklich benötigen. Die einzige Möglichkeit, einen Unterschied in der Laufzeit von Komponenten zwischen zwei Zeitpunkten zu erhalten, wäre Kalender generiert und spezifisch. Man könnte also argumentieren, dass die Standardbibliothek keinen schlauen Gregorianischen Kalender enthält, und ich stimme zu, dass dies einige Wünsche offen lässt.

Das gesagt, gibt es zahlreiche Implementierungen dieser Art von Funktionalität, ich sehe andere haben Beispiele zur Verfügung gestellt.

+0

Ich stimme Ihnen grundsätzlich zu. Mein Anspruch von Java, diese Funktionalität nicht zu haben, basierte auf der Tatsache, dass andere Sprachen (Ruby, Python, usw.) eine sehr einfache (und funktionierende) Implementierung des Hinzufügens und Subtrahierens von Daten als Teil der Standard-Date-Klassen haben. – Anirudh

2

Mit der date4j Bibliothek:

int numDaysBetween = oneDate.numDaysFrom(anotherDate); 
1

Es ist einfach so, wie es zu implementieren. Wir können die Calendar.add-Methode mit Schleife verwenden.wie unten Zum Beispiel

DateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd"); 

Date beginDate = dateFormat.parse("2013-11-29"); 
Date endDate = dateFormat.parse("2013-12-4"); 

Calendar beginCalendar = Calendar.getInstance(); 
beginCalendar.setTime(beginDate); 

Calendar endCalendar = Calendar.getInstance(); 
endCalendar.setTime(endDate); 

Der Minus-Tage zwischen Begindate und endDate und der Code wie unten,

int minusDays = 0; 
while (true) { 
    minusDays++; 

    // Day increasing by 1 
    beginCalendar.add(Calendar.DAY_OF_MONTH, 1); 

    if (dateFormat.format(beginCalendar.getTime()). 
      equals(dateFormat.format(endCalendar).getTime())) { 
    break; 
    } 
} 
System.out.println("The substractation between two days is " + (minusDays + 1)); 

Spaß zu haben! @. @

+0

Ich habe diese Methode schon einmal benutzt. Die Laufzeit ist jedoch O (N), wobei N die Anzahl der Tage zwischen Beginndatum und Enddatum ist. Ich vermute, dass die Verwendung von JodaTime bessere Ergebnisse liefert. – jharig23

+0

Ja, du hast Recht. ABER ich denke, O (n) ist für einige Projekte akzeptabel. Weil ich nicht irgendeine lib importieren möchte. Trotzdem danke für deine Vorschläge. –

4

Verwenden Sie entweder Joda-Time oder die neue java.time Paket in Java 8.

Beide Frameworks verwenden, um die Halboffen Ansatz, bei dem der Anfang inklusive während das Ende ist exklusiv. Manchmal notiert als [). Dies ist im Allgemeinen der beste Ansatz zum Definieren von Zeitspannen.

java.time

Der java.time Rahmen in Java 8 gebaut und später hat eine Period Klasse eine Zeitspanne als eine Reihe von Jahren zu vertreten, eine Anzahl von Monaten, und eine Anzahl von Tagen. Aber diese Klasse ist auf ganze Tage beschränkt, keine Darstellung von Stunden, Minuten und Sekunden.

Beachten Sie, dass wir eine Zeitzone angeben, die für die Bestimmung eines Datums entscheidend ist. Zum Beispiel beginnt ein neuer Tag früher in Paris als in Montréal.

ZoneId zoneId = ZoneId.of("America/Montreal"); 
LocalDate now = LocalDate.now(zoneId); 
LocalDate then = LocalDate.of(2001, 1, 1); 
Period period = Period.between(then, now); 

Dann: 2001-01-01. Jetzt: 2015-09-07. Periode: P14Y8M6D. Tage: 5362

Für ganze Tage ist Daylight Saving Time (DST) irrelevant.

Wenn Sie eine Anzahl von insgesamt Tagen wollen, verwenden Sie die ChronoUnit Enum, die einige Berechnungsmethoden enthält. Beachten Sie, dass die Berechnungen lange zurückgehen.

long days = ChronoUnit.DAYS.between(then, now); // "5362" seen above. 

I have asked über eine volle Periode in java.time tun, einschließlich Stunden, Minuten, Sekunden. Nicht möglich ab Java 8. Eine überraschende Problemumgehung unter Verwendung der gebündelten Bibliotheken was suggested von Meno Hochschild: Verwenden Sie eine Duration Klasse, die in der javax.xml.datatype package gefunden wird.

Joda-Time

Hier ist ein Code Beispiel in Joda-Time 2.3.

DateTimeZone timeZone = DateTimeZone.forID("Europe/Paris"); 
DateTime start = new DateTime(2014, 1, 2, 3, 4, 5, timeZone); 
DateTime stop = new DateTime(2014, 5, 2, 3, 4, 5, timeZone); 
Period period = new Period(start, stop); 

toString Aufruf erhalten Sie eine String-Darstellung in Form von der ISO 8601 Standard definiert erhalten, PnYnMnDTnHnMnS.