TimeUnit.DAYS.convert(
Math.abs(
new SimpleDateFormat("dd-MM-yyyy HH:mm:ss").parse("30-03-2020 00:00:00").getTime() -
new SimpleDateFormat("dd-MM-yyyy HH:mm:ss").parse("1-03-2020 00:00:00").getTime()
),
TimeUnit.MILLISECONDS)
Il risultato è 28 e dovrebbe essere 29. Il problema potrebbe essere il fuso orario/la posizione?
Il problema è che a causa del passaggio all'ora legale (domenica 8 marzo 2020), ci sono 28 giorni e 23 ore tra queste date. TimeUnit.DAYS.convert(...)
tronca il risultato a 28 giorni.
Per vedere il problema (sono nel fuso orario orientale degli Stati Uniti):
SimpleDateFormat fmt = new SimpleDateFormat("dd-MM-yyyy HH:mm:ss");
long diff = fmt.parse("30-03-2020 00:00:00").getTime() -
fmt.parse("1-03-2020 00:00:00").getTime();
System.out.println(diff);
System.out.println("Days: " + TimeUnit.DAYS.convert(Math.abs(diff), TimeUnit.MILLISECONDS));
System.out.println("Hours: " + TimeUnit.HOURS.convert(Math.abs(diff), TimeUnit.MILLISECONDS));
System.out.println("Days: " + TimeUnit.HOURS.convert(Math.abs(diff), TimeUnit.MILLISECONDS) / 24.0);
Output
``lang-none 2502000000 Giorni: 28 Ore: 695 Giorni: 28.958333333333332
Per risolvere, usate un fuso orario che non ha il DST, per esempio **UTC**:
SimpleDateFormat fmt = new SimpleDateFormat("dd-MM-yyyy HH:mm:ss"); fmt.setTimeZone(TimeZone.getTimeZone("UTC")); long diff = fmt.parse("30-03-2020 00:00:00").getTime() - fmt.parse("1-03-2020 00:00:00").getTime();
*Output*
``lang-none
2505600000
Giorni: 29
Ore: 696
Giorni: 29.0
La causa di questo problema è già menzionata nella risposta di Andreas.
La questione è cosa esattamente vuoi contare. Il fatto che tu dichiari che la differenza effettiva dovrebbe essere 29 invece di 28, e chiedi se "la posizione/zona oraria potrebbe essere un problema", rivela cosa vuoi effettivamente contare. Apparentemente, volete sbarazzarvi di qualsiasi differenza di fuso orario.
Presumo che tu voglia solo calcolare i giorni, senza l'ora e il fuso orario.
Sotto, nell'esempio di come il numero di giorni tra potrebbe essere calcolato correttamente, sto usando una classe che rappresenta esattamente questo - una data senza ora e fuso orario - LocalDate
.
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("d-MM-yyyy HH:mm:ss");
LocalDate start = LocalDate.parse("1-03-2020 00:00:00", formatter);
LocalDate end = LocalDate.parse("30-03-2020 00:00:00", formatter);
long daysBetween = ChronoUnit.DAYS.between(start, end);
Si noti che ChronoUnit
, DateTimeFormatter
e LocalDate
richiedono almeno Java 8, che non è disponibile per voi, secondo il tag [tag:java-7]. Tuttavia, forse lo è per i futuri lettori.
Come menzionato da Ole V.V., c'è anche il ThreeTen Backport, che riporta le funzionalità di Java 8 Date and Time API a Java 6 e 7.