Berechnen Sie Tage zwischen zwei Daten in Java 8

250

Ich weiß, dass es auf SO viele Fragen gibt, wie man es bekommt, aber ich möchte ein Beispiel für die Verwendung der neuen Java 8 Date-API. Ich kenne auch die JodaTime-Bibliothek, möchte aber ohne externe Bibliotheken arbeiten.

Die Funktion muss sich mit folgenden Einschränkungen beschweren:

  1. Verhindern Sie Fehler beim Speichern des Datums
  2. Eingabe sind zwei Datumsobjekte (ohne Zeit kenne ich die Ortszeit, aber ich muss mit Datumsinstanzen tun)
Marcos
quelle
2
So etwas zum Beispiel ?
MadProgrammer
@ MadProgrammer Nicht wirklich - Dauer ist nicht die beste
Lösung dafür
@assylias Nun, es ist besser als das, was das OP hatte
MadProgrammer
@assylias Was ist dann?
MadProgrammer
16
@ MadProgrammer DAYS.between(localDate1, localDate2).
Assylias

Antworten:

434

Wenn Sie logische Kalendertage wünschen , verwenden Sie die DAYS.between()Methode von java.time.temporal.ChronoUnit:

LocalDate dateBefore;
LocalDate dateAfter;
long daysBetween = DAYS.between(dateBefore, dateAfter);

Wenn Sie buchstäbliche 24-Stunden-Tage (eine Dauer ) möchten , können Sie Durationstattdessen die Klasse verwenden:

LocalDate today = LocalDate.now()
LocalDate yesterday = today.minusDays(1);
// Duration oneDay = Duration.between(today, yesterday); // throws an exception
Duration.between(today.atStartOfDay(), yesterday.atStartOfDay()).toDays() // another option

Weitere Informationen finden Sie in diesem Dokument .

Syntagma
quelle
15
Dies löst eine Ausnahme aus, da für die Duration.between-Methode zeitliche Objekte erforderlich sind, die die SECONDS-Einheit unterstützen können . Versuchen Sie es stattdessen Duration.between(today.atTime(0, 0), yesterday.atTime(0, 0)).toDays().
VGR
5
Anstelle von today.atTime(0, 0)dir kann today.atStartOfDay().
eee
5
@REACHUS Vielleicht war die -1 etwas hart, weil der von Ihnen vorgeschlagene Code funktioniert, aber die Dauer soll "zeitbasierte Zeitmengen" messen. Es gibt eine integrierte Methode zum Messen einer Anzahl von Tagen, für die keine Konvertierung von Datum zu Datum / Uhrzeit erforderlich ist.
Assylias
Die bessere Antwort für LocalDate ist die Antwort von @Sunil B unten:ChronoUnit.DAYS.between(firstDate, secondDate)
Lappro
@Lappro warum ist es besser? Es verwendet die gleiche Methode wie meine Antwort
Syntagma
130

Basierend auf den Kommentaren von VGR können Sie Folgendes verwenden:

ChronoUnit.DAYS.between(firstDate, secondDate)
Sunil B.
quelle
38

Sie können verwenden until():

LocalDate independenceDay = LocalDate.of(2014, Month.JULY, 4);
LocalDate christmas = LocalDate.of(2014, Month.DECEMBER, 25);

System.out.println("Until christmas: " + independenceDay.until(christmas));
System.out.println("Until christmas (with crono): " + independenceDay.until(christmas, ChronoUnit.DAYS));
nazar_art
quelle
4
Das Problem, auf das ich gerade bei der ersten Version von gestoßen bin, untilist, dass es ein Period- Objekt zurückgibt . Das gibt eine Anzahl von Jahren / Monaten / Tagen zwischen den beiden Daten zurück, nicht die tatsächliche Anzahl von Tagen. Und getDays () für den Zeitraum gibt nur den Tagesteil zurück (ohne Berücksichtigung der Anzahl der Jahre oder Monate) und nicht die Gesamtzahl der Tage. Die zweite Version funktioniert genau wie gewünscht, um eine Anzahl von Tagen zwischen zwei Daten zu erhalten.
M. Justin
Gibt es dafür eine komplette Alternative? Da es Android SDk 26 und höher benötigt
ralphgabb
12

Sie können DAYS.betweenvon verwendenjava.time.temporal.ChronoUnit

z.B

import java.time.temporal.ChronoUnit;

public long getDaysCountBetweenDates(LocalDate dateBefore, LocalDate dateAfter) {
    return DAYS.between(dateBefore, dateAfter);
}
Piotr Fryga
quelle
10

Wenn startDate und endDate eine Instanz von java.util.Date sind

Wir können die Between () -Methode aus ChronoUnit enum verwenden:

public long between(Temporal temporal1Inclusive, Temporal temporal2Exclusive) {
    //..
}

ChronoUnit.DAYS zählen Tage, die 24 Stunden abgeschlossen haben .

import java.time.temporal.ChronoUnit;

ChronoUnit.DAYS.between(startDate.toInstant(), endDate.toInstant());

//OR 

ChronoUnit.DAYS.between(Instant.ofEpochMilli(startDate.getTime()), Instant.ofEpochMilli(endDate.getTime()));
Pawan
quelle
8

Verwenden Sie die TAGE in enum java.time.temporal.ChronoUnit . Unten ist der Beispielcode:

Ausgabe: * Anzahl der Tage zwischen dem Startdatum: 2015-03-01 und dem Enddatum: 2016-03-03 ist ==> 368. ** Anzahl der Tage zwischen dem Startdatum: 2016-03-03 und dem Enddatum: 2015-03-01 ist ==> -368 *

package com.bitiknow.date;

import java.time.LocalDate;
import java.time.temporal.ChronoUnit;

/**
 * 
 * @author pradeep
 *
 */
public class LocalDateTimeTry {
    public static void main(String[] args) {

        // Date in String format.
        String dateString = "2015-03-01";

        // Converting date to Java8 Local date
        LocalDate startDate = LocalDate.parse(dateString);
        LocalDate endtDate = LocalDate.now();
        // Range = End date - Start date
        Long range = ChronoUnit.DAYS.between(startDate, endtDate);
        System.out.println("Number of days between the start date : " + dateString + " and end date : " + endtDate
                + " is  ==> " + range);

        range = ChronoUnit.DAYS.between(endtDate, startDate);
        System.out.println("Number of days between the start date : " + endtDate + " and end date : " + dateString
                + " is  ==> " + range);

    }

}
Pradeep Padmarajaiah
quelle
8

Jeder sagt, ChronoUnit.DAYS.between zu verwenden, aber das delegiert nur an eine andere Methode, die Sie selbst nennen könnten. So könnten Sie auch tun firstDate.until(secondDate, ChronoUnit.DAYS).

Die Dokumente für beide erwähnen tatsächlich beide Ansätze und sagen, dass sie den besser lesbaren verwenden sollen.

nafg
quelle
FWIW ... Ich bin mir nicht sicher, warum beide existieren. Gibt es Zeiten, in denen das eine besser lesbar ist und das andere? Wann warum?
Nafg
5

Bitte schön:

public class DemoDate {
    public static void main(String[] args) {
        LocalDate today = LocalDate.now();
        System.out.println("Current date: " + today);

        //add 1 month to the current date
        LocalDate date2 = today.plus(1, ChronoUnit.MONTHS);
        System.out.println("Next month: " + date2);

        // Put latest date 1st and old date 2nd in 'between' method to get -ve date difference
        long daysNegative = ChronoUnit.DAYS.between(date2, today);
        System.out.println("Days : "+daysNegative);

        // Put old date 1st and new date 2nd in 'between' method to get +ve date difference
        long datePositive = ChronoUnit.DAYS.between(today, date2);
        System.out.println("Days : "+datePositive);
    }
}
Pra_A
quelle
5

Holen Sie sich die Anzahl der Tage vor Weihnachten vom aktuellen Tag, versuchen Sie dies

System.out.println(ChronoUnit.DAYS.between(LocalDate.now(),LocalDate.of(Year.now().getValue(), Month.DECEMBER, 25)));
Survivor_27
quelle
3

Wenn das Ziel nur darin besteht, den Unterschied in Tagen zu ermitteln und da in den obigen Antworten über Delegiertenmethoden erwähnt wird, möchte darauf hingewiesen werden, dass einmal auch einfach verwendet werden kann -

public long daysInBetween(java.time.LocalDate startDate, java.time.LocalDate endDate) {
  // Check for null values here

  return endDate.toEpochDay() - startDate.toEpochDay();
}
levenshtein
quelle
1
Im Herbst in die Falle gehen, um 'Period.between (date1, date2) .getDays ()' zu verwenden, ohne zu bemerken, dass Sie die Monate und Jahre der Differenz verlieren.
MrSmith42
2

Tage zwischen zwei Daten abrufen Datum ist eine Instanz von java.util.Date

public static long daysBetweenTwoDates(Date dateFrom, Date dateTo) {
            return DAYS.between(Instant.ofEpochMilli(dateFrom.getTime()), Instant.ofEpochMilli(dateTo.getTime()));
        }
Mohamed.Abdo
quelle
1

Ich weiß, dass diese Frage für Java 8 gilt, aber mit Java 9 können Sie Folgendes verwenden:

public static List<LocalDate> getDatesBetween(LocalDate startDate, LocalDate endDate) {
    return startDate.datesUntil(endDate)
      .collect(Collectors.toList());
}
Xxtreem
quelle
0

Verwenden Sie die Klasse oder Methode, die Ihren Anforderungen am besten entspricht:

  • die Dauer Klasse,
  • Periodenklasse ,
  • oder die ChronoUnit.between- Methode.

Eine Dauer misst eine Zeitspanne anhand zeitbasierter Werte (Sekunden, Nanosekunden).

Ein Zeitraum verwendet datumsbasierte Werte (Jahre, Monate, Tage).

Die ChronoUnit.between-Methode ist nützlich, wenn Sie eine Zeitspanne nur in einer einzigen Zeiteinheit messen möchten, z. B. Tage oder Sekunden.

https://docs.oracle.com/javase/tutorial/datetime/iso/period.html

Samuel
quelle