web-dev-qa-db-de.com

Anzahl der Tage zwischen zwei Daten in Joda-Time

Wie finde ich den Unterschied in Tagen zwischen zwei Joda-ZeitDateTime -Instanzen? Mit "Differenz in Tagen" meine ich, wenn der Start am Montag und Ende am Dienstag ist, erwarte ich einen Rückgabewert ungeachtet der Stunde/Minute/Sekunde des Start- und Enddatums.

Days.daysBetween(start, end).getDays() gibt mir 0, wenn der Start am Abend ist und am Morgen endet.

Ich habe auch das gleiche Problem mit anderen Datumsfeldern, also hoffte ich, es gäbe einen generischen Weg, die Felder von geringerer Bedeutung zu "ignorieren". 

Mit anderen Worten, die Monate zwischen Feb. und 4. März wären ebenfalls 1, ebenso wie die Stunden zwischen 14:45 und 15:12 Uhr. Die Stundendifferenz zwischen 14:01 und 14:55 wäre jedoch 0.

303
pvgoddijn

Ärgerlicherweise ist die withTimeAtStartOfDay-Antwort falsch, jedoch nur gelegentlich. Sie wollen:

Days.daysBetween(start.toLocalDate(), end.toLocalDate()).getDays()

Es stellt sich heraus, dass "Mitternacht/Tagesbeginn" manchmal 1 Uhr morgens bedeutet (in manchen Fällen erfolgt die Sommerzeit auf diese Weise).

// 5am on the 20th to 1pm on the 21st, October 2013, Brazil
DateTimeZone BRAZIL = DateTimeZone.forID("America/Sao_Paulo");
DateTime start = new DateTime(2013, 10, 20, 5, 0, 0, BRAZIL);
DateTime end = new DateTime(2013, 10, 21, 13, 0, 0, BRAZIL);
System.out.println(daysBetween(start.withTimeAtStartOfDay(),
                               end.withTimeAtStartOfDay()).getDays());
// prints 0
System.out.println(daysBetween(start.toLocalDate(),
                               end.toLocalDate()).getDays());
// prints 1

Wenn Sie über eine LocalDate gehen, wird das gesamte Problem umgangen.

358
Alice Purcell

Days Klasse

Die Verwendung der Days Klasse mit der withTimeAtStartOfDay Methode sollte funktionieren:

Days.daysBetween(start.withTimeAtStartOfDay() , end.withTimeAtStartOfDay() ).getDays() 
183

sie können LocalDate verwenden:

Days.daysBetween(new LocalDate(start), new LocalDate(end)).getDays() 
82
Bozho

tl; dr

Java.time.temporal.ChronoUnit.DAYS.between( 
    earlier.truncatedTo( ChronoUnit.DAYS )  , 
    later.truncatedTo( ChronoUnit.DAYS ) 
)

…oder…

Java.time.temporal.ChronoUnit.HOURS.between( 
    earlier.truncatedTo( ChronoUnit.HOURS )  , 
    later.truncatedTo( ChronoUnit.HOURS ) 
)

Java.time

Zu Ihrer Information, das Projekt Joda-Time befindet sich jetzt in Wartungsmodus , wobei das Team die Migration zu den Klassen Java.time empfiehlt. 

Das Äquivalent von Joda-Time DateTime ist ZonedDateTime.

ZoneId z = ZoneId.of( "Pacific/Auckland" ) ;
ZonedDateTime now = ZonedDateTime.now( z ) ;

Anscheinend möchten Sie die Tage nach Datumsangaben zählen, dh Sie möchten die Uhrzeit ignorieren. Wenn Sie beispielsweise eine Minute vor Mitternacht beginnen und eine Minute nach Mitternacht enden, sollte dies zu einem einzigen Tag führen. Extrahieren Sie für dieses Verhalten eine LocalDate aus Ihrer ZonedDateTime. Die Klasse LocalDate steht für einen Datumswert ohne Uhrzeit und ohne Zeitzone.

LocalDate localDateStart = zdtStart.toLocalDate() ;
LocalDate localDateStop = zdtStop.toLocalDate() ;

Verwenden Sie die Aufzählung ChronoUnit , um verstrichene Tage oder andere Einheiten zu berechnen.

long days = ChronoUnit.DAYS.between( localDateStart , localDateStop ) ;

Kürzen

Wenn Sie nach einer allgemeineren Methode für diese Zählung fragen, bei der Sie interessiert sind, ob das Delta der Stunden als Stundenzeit statt vollständiger Stunden als Zeitspannen von 60 Minuten gilt, verwenden Sie die truncatedTo-Methode.

Hier ist Ihr Beispiel von 14:45 bis 15:12 Uhr am selben Tag.

ZoneId z = ZoneId.of( "America/Montreal" ); 
ZonedDateTime start = ZonedDateTime.of( 2017 , 1 , 17 , 14 , 45 , 0 , 0 , z );
ZonedDateTime stop = ZonedDateTime.of( 2017 , 1 , 17 , 15 , 12 , 0 , 0 , z );

long hours = ChronoUnit.HOURS.between( start.truncatedTo( ChronoUnit.HOURS ) , stop.truncatedTo( ChronoUnit.HOURS ) );

1

Für eine Anzahl von Tagen nach Datum wird auf ChronoUnit.DAYS gekürzt. Hier ist ein Beispiel, das über Mitternacht von fünf Minuten vor fünf Minuten nach fünf Minuten nach 1 rollt.

ZoneId z = ZoneId.of( "America/Montreal" );
ZonedDateTime start = ZonedDateTime.of( 2017 , 1 , 17 , 23 , 55 , 0 , 0 , z );
ZonedDateTime stop = ZonedDateTime.of( 2017 , 1 , 18 , 00 , 05 , 0 , 0 , z );

long days = ChronoUnit.DAYS.between( start.truncatedTo( ChronoUnit.DAYS ) , stop.truncatedTo( ChronoUnit.DAYS ) );

1


Über Java.time

Das Framework Java.time ist in Java 8 und höher integriert. Diese Klassen ersetzen die störenden alten Legacy Datum-Uhrzeit-Klassen, wie Java.util.Date , Calendar , & SimpleDateFormat .

Das Projekt Joda-Time , das sich jetzt im Wartungsmodus befindet, empfiehlt die Migration zu den Klassen Java.time .

Weitere Informationen finden Sie unter Oracle Tutorial . In Stack Overflow finden Sie viele Beispiele und Erklärungen. Die Spezifikation lautet 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.

Wo erhalten Sie die Java.time-Klassen? 

Das Projekt ThreeTen-Extra erweitert Java.time um zusätzliche Klassen. Dieses Projekt ist ein Testfeld für mögliche zukünftige Erweiterungen von Java.time. Hier finden Sie nützliche Klassen wie Interval , YearWeek , YearQuarter und mehr .

Das Projekt ThreeTen-Extra erweitert Java.time um zusätzliche Klassen. Dieses Projekt ist ein Testfeld für mögliche zukünftige Erweiterungen von Java.time. Hier finden Sie nützliche Klassen wie Interval , YearWeek , YearQuarter und mehr .

6
Basil Bourque

Die akzeptierte Antwort baut zwei LocalDate-Objekte auf, die ziemlich teuer sind, wenn Sie viele Daten lesen.

  public static int getDaysBetween(DateTime earlier, DateTime later)
  {
    return (int) TimeUnit.MILLISECONDS.toDays(later.getMillis()- earlier.getMillis());
  }

Mit dem Aufruf von getMillis() verwenden Sie bereits vorhandene Variablen.
MILLISECONDS.toDays() verwendet dann eine einfache arithmetische Berechnung und erstellt kein Objekt.

2
JBoy

Java.time.Period

Verwenden Sie die Java.time.Period class, um Tage zu zählen .

Da die Berechnung der Differenz in Java 8 intuitiver ist, verwenden Sie LocalDate und LocalDateTime, um die beiden Datumsangaben darzustellen 

    LocalDate now = LocalDate.now();
    LocalDate inputDate = LocalDate.of(2018, 11, 28);

    Period period = Period.between( inputDate, now);
    int diff = period.getDays();
    System.out.println("diff = " + diff);
1
Azi
DateTime  dt  = new DateTime(laterDate);        

DateTime newDate = dt.minus( new  DateTime ( previousDate ).getMillis());

System.out.println("No of days : " + newDate.getDayOfYear() - 1 );    
0
Arnab Bhui