Número de días entre dos fechas en Joda-Time
¿Cómo encuentro la diferencia en días entre dos instancias de Joda-Time ? DateTime
Con "diferencia en días" me refiero a que si el inicio es el lunes y el final es el martes, espero un valor de retorno de 1, independientemente de la hora/minuto/segundo de las fechas de inicio y finalización.
Days.daysBetween(start, end).getDays()
me da 0 si el inicio es por la tarde y termina por la mañana.
También tengo el mismo problema con otros campos de fecha, por lo que esperaba que hubiera una forma genérica de "ignorar" los campos de menor importancia.
Es decir, los meses comprendidos entre febrero y el 4 de marzo también serían 1, al igual que las horas entre las 14:45 y las 15:12. Sin embargo, la diferencia horaria entre las 14:01 y las 14:55 sería 0.
Es molesto que la respuesta withTimeAtStartOfDay sea incorrecta, pero solo ocasionalmente. Quieres:
Days.daysBetween(start.toLocalDate(), end.toLocalDate()).getDays()
Resulta que "medianoche/inicio del día" a veces significa 1 a.m. (el horario de verano ocurre de esta manera en algunos lugares), lo cual Days.daysBetween no maneja correctamente.
// 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
Pasando por LocalDate
alto todo el asunto.
Days
Clase
Usar la Days
clase con el withTimeAtStartOfDay
método debería funcionar:
Days.daysBetween(start.withTimeAtStartOfDay() , end.withTimeAtStartOfDay() ).getDays()
puedes usar LocalDate
:
Days.daysBetween(new LocalDate(start), new LocalDate(end)).getDays()
tl; dr
java.time.temporal.ChronoUnit.DAYS.between(
earlier.toLocalDate(),
later.toLocalDate()
)
…o…
java.time.temporal.ChronoUnit.HOURS.between(
earlier.truncatedTo( ChronoUnit.HOURS ) ,
later.truncatedTo( ChronoUnit.HOURS )
)
java.tiempo
Para su información, el proyecto Joda-Time ahora está en modo de mantenimiento y el equipo recomienda la migración a las clases java.time .
El equivalente de Joda-Time DateTime
es ZonedDateTime
.
ZoneId z = ZoneId.of( "Pacific/Auckland" ) ;
ZonedDateTime now = ZonedDateTime.now( z ) ;
Aparentemente desea contar los días por fechas, lo que significa que desea ignorar la hora del día. Por ejemplo, comenzar un minuto antes de la medianoche y terminar un minuto después de la medianoche debería dar como resultado un solo día. Para este comportamiento, extraiga a LocalDate
de su ZonedDateTime
. La LocalDate
clase representa un valor de solo fecha sin hora del día y sin zona horaria.
LocalDate localDateStart = zdtStart.toLocalDate() ;
LocalDate localDateStop = zdtStop.toLocalDate() ;
Utilice la ChronoUnit
enumeración para calcular los días transcurridos u otras unidades.
long days = ChronoUnit.DAYS.between( localDateStart , localDateStop ) ;
Truncar
En cuanto a si pregunta sobre una forma más general de hacer este conteo en la que le interesa el delta de horas como hora del reloj en lugar de horas completas como lapsos de tiempo de sesenta minutos, utilice el truncatedTo
método.
Aquí está su ejemplo de 14:45 a 15:12 del mismo día.
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
Esto no funciona durante días. Utilice toLocalDate() en este caso.
Acerca de java.time
El marco java.time está integrado en Java 8 y versiones posteriores. Estas clases reemplazan a las antiguas y problemáticas clases de fecha y hora heredadas , como java.util.Date
, Calendar
y SimpleDateFormat
.
El proyecto Joda-Time , ahora en modo de mantenimiento , aconseja la migración a las clases java.time .
Para obtener más información, consulte el Tutorial de Oracle . Y busque Stack Overflow para obtener muchos ejemplos y explicaciones. La especificación es JSR 310 .
Puede intercambiar objetos java.time directamente con su base de datos. Utilice un controlador JDBC compatible con JDBC 4.2 o posterior. No hay necesidad de cadenas, no hay necesidad de java.sql.*
clases.
¿Dónde obtener las clases java.time?
- Java SE 8 , Java SE 9 , Java SE 10 y posteriores
- Incorporado.
- Parte de la API de Java estándar con una implementación incluida.
- Java 9 agrega algunas características y correcciones menores.
- Java SE 6 y Java SE 7
- Gran parte de la funcionalidad java.time está adaptada a Java 6 y 7 en ThreeTen-Backport .
- Androide
- Versiones posteriores de implementaciones de paquetes de Android de las clases java.time.
- Para Android anterior (<26), el proyecto ThreeTenABP adapta ThreeTen-Backport (mencionado anteriormente). Consulte Cómo utilizar ThreeTenABP… .
El proyecto ThreeTen-Extra amplía java.time con clases adicionales. Este proyecto es un campo de pruebas para posibles adiciones futuras a java.time. Puede encontrar algunas clases útiles aquí, como , Interval
, y más .YearWeek
YearQuarter
El proyecto ThreeTen-Extra amplía java.time con clases adicionales. Este proyecto es un campo de pruebas para posibles adiciones futuras a java.time. Puede encontrar algunas clases útiles aquí, como , Interval
, y más .YearWeek
YearQuarter