mkyong - zoneid java example
Java 8: Calcular la diferencia entre dos ZonedDateTime (2)
Estoy tratando de escribir un método para imprimir la diferencia horaria entre dos ZonedDateTime s, con respecto a la diferencia entre las zonas horarias.
Encontré algunas soluciones, pero todas fueron escritas para trabajar con LocalDateTime .
tl; dr
Por horas, minutos, segundos:
Duration.between( zdtA , zdtB )
Por años, meses, días:
Period.between(
zdtA.toLocalDate() ,
zdtB.toLocalDate()
)
Detalles
La respuesta de Michal S es correcta, mostrando ChronoUnit
.
Duration
y Period
Otra ruta son las clases de Duration
y Period
. Use el primero para períodos de tiempo más cortos (horas, minutos, segundos) y el segundo para más largos (años, meses, días).
Duration d = Duration.between( zdtA , zdtB );
Produce una cadena en formato estándar ISO 8601 llamando a toString
. El formato es PnYnMnDTnHnMnS
donde P
marca el comienzo y T
separa las dos partes.
String output = d.toString();
En Java 9 y versiones posteriores, llame to…Part
métodos de to…Part
para obtener los componentes individuales. Discutido en otra respuesta mía .
Código de ejemplo
ZoneId z = ZoneId.of( "America/Montreal" );
ZonedDateTime zdtStart = ZonedDateTime.now( z );
ZonedDateTime zdtStop = zdtStart.plusHours( 3 ).plusMinutes( 7 );
Duration d = Duration.between( zdtStart , zdtStop );
2016-12-11T03: 07: 50.639-05: 00 [America / Montreal] /2016-12-11T06:14:50.639-05:00 [America / Montreal]
PT3H7M
Ver código en vivo en IdeOne.com .
Interval
& LocalDateRange
El proyecto ThreeTen-Extra agrega funcionalidad a las clases java.time. Una de sus clases prácticas es Interval
para representar un lapso de tiempo como un par de puntos en la línea de tiempo. Otro es LocalDateRange
, para un par de objetos LocalDate
. En contraste, las clases Period
y Duration
representan un lapso de tiempo que no se adjunta a la línea de tiempo.
El método de fábrica para el Interval
toma un par de objetos Instant
.
Interval interval = Interval.of( zdtStart.toInstant() , zdtStop.toInstant() );
Puedes obtener una Duration
de un Interval
.
Duration d = interval.toDuration();
Acerca de java.time
El marco java.time está integrado en Java 8 y java.time posteriores. Estas clases sustituyen a las antiguas y problemáticas clases de fecha y hora 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 busca para 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 se necesitan cadenas, no se necesitan clases java.sql.*
.
¿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 en paquete.
- Java 9 agrega algunas características menores y correcciones.
- Java SE 6 y Java SE 7
- Gran parte de la funcionalidad de java.time está respaldada a Java 6 y 7 en ThreeTen-Backport .
- Android
- Versiones posteriores de las implementaciones de paquetes de Android de las clases java.time .
- Para Android anterior (<26), el proyecto ThreeTen-Backport adapta ThreeTen-Backport (mencionado anteriormente). Vea Cómo usar ThreeTenABP… .
El proyecto ThreeTen-Extra extiende java.time con clases adicionales. Este proyecto es un terreno de prueba para posibles adiciones futuras a java.time. Puede encontrar algunas clases útiles aquí como Interval
, YearWeek
, YearQuarter
, y more .
Puedes usar el método entre ChronoUnit .
Este método convierte esos tiempos a la misma zona (zona del primer argumento) y después de eso, invoca hasta el método declarado en la interfaz Temporal :
static long zonedDateTimeDifference(ZonedDateTime d1, ZonedDateTime d2, ChronoUnit unit){
return unit.between(d1, d2);
}
Dado que tanto ZonedDateTime como LocalDateTime implementan la interfaz temporal , también puede escribir un método universal para esos tipos de fecha y hora:
static long dateTimeDifference(Temporal d1, Temporal d2, ChronoUnit unit){
return unit.between(d1, d2);
}
Pero tenga en cuenta que invocar este método para mezclar LocalDateTime y ZonedDateTime conduce a DateTimeException .
Espero eso ayude.