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)El resultado es 28, cuando debería ser 29.
¿Podría ser la zona horaria o la ubicación el problema?
El problema es que debido al cambio de horario de verano (el domingo 8 de marzo de 2020), hay 28 días y 23 horas entre esas fechas. TimeUnit.DAYS.convert(...) trunca el resultado a 28 días.
Para ver el problema (estoy en la zona horaria del este de EE. UU.):
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);Producción
2502000000 Days: 28 Hours: 695 Days: 28.958333333333332Para solucionarlo, use una zona horaria que no tenga horario de verano, por ejemplo, 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();Producción
2505600000 Days: 29 Hours: 696 Days: 29.0La causa de este problema ya se menciona en la respuesta de Andreas .
La pregunta es qué es exactamente lo que quieres contar. El hecho de que indique que la diferencia real debería ser 29 en lugar de 28, y pregunte si "la ubicación/zona horaria podría ser un problema" , revela lo que realmente desea contar. Aparentemente, desea deshacerse de cualquier diferencia de zona horaria.
Supongo que solo desea calcular los días, sin hora ni zona horaria.
A continuación, en el ejemplo de cómo se puede calcular correctamente el número de días intermedios, estoy usando una clase que representa exactamente eso, una fecha sin hora ni zona horaria, 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); Tenga en cuenta que ChronoUnit , DateTimeFormatter y LocalDate requieren al menos Java 8, que no está disponible para usted, según la etiqueta java-7 . Sin embargo, tal vez lo sea para futuros lectores.
Como lo mencionó Ole VV, también está ThreeTen Backport , que respalda la funcionalidad de la API de fecha y hora de Java 8 a Java 6 y 7.