Número de días entre dos fechas en Joda-Time

Resuelto pvgoddijn asked hace 14 años • 9 respuestas

¿Cómo encuentro la diferencia en días entre dos instancias de Joda-Time ? DateTimeCon "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.

pvgoddijn avatar Sep 27 '10 17:09 pvgoddijn
Aceptado

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 LocalDatealto todo el asunto.

alicederyn avatar Jul 30 '2013 23:07 alicederyn

DaysClase

Usar la Daysclase con el withTimeAtStartOfDaymétodo debería funcionar:

Days.daysBetween(start.withTimeAtStartOfDay() , end.withTimeAtStartOfDay() ).getDays() 
Michael Borgwardt avatar Sep 27 '2010 10:09 Michael Borgwardt

puedes usar LocalDate:

Days.daysBetween(new LocalDate(start), new LocalDate(end)).getDays() 
Bozho avatar Sep 27 '2010 10:09 Bozho

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 DateTimees 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 LocalDatede su ZonedDateTime. La LocalDateclase 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 ChronoUnitenumeració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 truncatedTomé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, Calendary 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 .YearWeekYearQuarter

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 .YearWeekYearQuarter

Basil Bourque avatar Aug 22 '2017 04:08 Basil Bourque