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)
Wynik to 28, a powinno być 29.
Czy strefa czasowa / lokalizacja mogą stanowić problem?
SimpleDateFormat
więcej, ponieważ jest przestarzały.java.time
Zamiast tego użyj pakietów . W takimSimpleDateFormat
przypadku użyjDateTimeFormatter
. W przypadku Java 7 zobacz komentarz Andy Turner poniżej.java.time
[zauważam, że korzystasz z Java 7], ThreeTenBp , Joda).TimeUnit
nie udaje, że nic nie wie o DST. Jak mówi javadoc: nanosekunda jest definiowana jako jedna tysięczna mikrosekundy, mikrosekunda jako jedna tysięczna milisekundy, milisekunda jako jedna tysięczna sekundy, minuta jako sześćdziesiąt sekund, godzina jako sześćdziesiąt minut i dzień jako dwadzieścia cztery godziny . --- Ponieważ DST powoduje, że 2 dni w roku nie są dokładnie 24 godziny,TimeUnit
robi się źle, gdy DST jest zaangażowany.Odpowiedzi:
Problem polega na tym, że z powodu zmiany czasu letniego (w niedzielę 8 marca 2020 r.) Między tymi datami jest 28 dni i 23 godziny .
TimeUnit.DAYS.convert(...)
skraca wynik do 28 dni.Aby zobaczyć problem (jestem w strefie czasowej USA Wschodniej):
Wynik
Aby to naprawić, użyj strefy czasowej, która nie ma czasu letniego, np. UTC :
Wynik
źródło
GregorianCalendar
obiektu i dodawanie 1 dnia na raz, aż do osiągnięcia daty końcowej. Zapłaciłbym wysoką cenę, aby tego uniknąć. A dodanie backportu biblioteki, która jest już częścią Java 8, 9, 10, 11, 12, 13,… nie jest wysoką ceną. Przeciwnie, następnym razem, gdy będziesz musiał zrobić cokolwiek z datą lub godziną, będzie to już zysk.Przyczyna tego problemu jest już wspomniana w odpowiedzi Andreasa .
Pytanie brzmi, co dokładnie chcesz liczyć. Fakt, że stwierdzasz, że rzeczywista różnica powinna wynosić 29 zamiast 28, i pytasz, czy „czas / lokalizacja może być problemem” , ujawnia, co naprawdę chcesz policzyć. Najwyraźniej chcesz pozbyć się różnicy stref czasowych.
Zakładam, że chcesz obliczyć tylko dni, bez czasu i strefy czasowej.
Java 8
Poniżej, w przykładzie, w jaki sposób można poprawnie obliczyć liczbę dni między, używam klasy, która dokładnie to reprezentuje - datę bez godziny i strefy czasowej
LocalDate
.Należy zauważyć, że
ChronoUnit
,DateTimeFormatter
iLocalDate
wymaga co najmniej Java 8, która nie jest dostępna dla użytkownika, zgodnie z java-7 tag. Być może jest to jednak dla przyszłych czytelników.Jak wspomniano w Ole VV, istnieje również ThreeTen Backport , który backportuje funkcjonalność API Java 8 Date and Time do Java 6 i 7.
źródło
ThreeTen
;-), ale niestety jest on offline w momencie pisania.) Zaktualizuję ten post.java.time
, ponieważ w szkole wciąż korzystają ze starych klas. Ale Java 8 Data i czas API jest bardzo dobrze zaprojektowany - byłaby to strata nie go używać.