Diferencias entre Java 8 Date Time API (java.time) y Joda-Time

264

Sé que hay preguntas relacionadas con java.util.Date y Joda-Time. Pero después de investigar un poco, no pude encontrar un hilo sobre las diferencias entre la API java.time (nueva en Java 8 , definida por JSR 310 ) y Joda-Time .

He oído que la API java.time de Java 8 es mucho más limpia y puede hacer mucho más que Joda-Time. Pero no puedo encontrar ejemplos que comparen los dos.

  • ¿Qué puede hacer java.time que Joda-Time no puede hacer?
  • ¿Qué puede hacer java.time mejor que Joda-Time?
  • ¿El rendimiento es mejor con java.time?
Zack
fuente
8
No es, eso pertenece a Java 7, no a Java 8. La respuesta a esa pregunta fue editada para Java 8 con muy pocos detalles. Mi pregunta es específicamente sobre la nueva API DateTime de Java 8, no sobre java.util.Date de Java 7. Solo estoy buscando una respuesta que compare Java 8 con JodaTime.
Zack
2
Quizás este documento de Oracle pueda ayudarlo.
MarioDS
Si tiene Java 7, use la biblioteca adicional, si tiene Java 8, use la biblioteca integrada. Dado que ambas bibliotecas están diseñadas básicamente por la misma persona, no estoy seguro de las principales diferencias que espera.
Peter Lawrey
2
@PeterLawrey: Joda-Time y la API de fecha y hora de Java 8 son en realidad bastante diferentes.
jarnbjo
55
También puede leer esta publicación de blog de Stephen Colbourne, el autor principal de ambos proyectos.
Matt Johnson-Pint

Respuestas:

416

Características comunes

a) Ambas bibliotecas usan tipos inmutables. Joda-Time también ofrece tipos mutables adicionales como MutableDateTime.

b) Además: ambas bibliotecas están inspiradas en el estudio de diseño "TimeAndMoney" de Eric Evans o en las ideas de Martin Fowler sobre el estilo controlado por dominio, por lo que se esfuerzan más o menos por un estilo de programación fluido (aunque no siempre perfecto ;-)).

c) Con ambas bibliotecas obtenemos un tipo de fecha de calendario real (llamado LocalDate), un tipo de tiempo de pared real (llamado LocalTime) y la composición (llamado LocalDateTime). Esa es una gran victoria en comparación con los viejos java.util.Calendary java.util.Date.

d) Ambas bibliotecas utilizan un enfoque centrado en el método, lo que significa que alientan al usuario a usar en getDayOfYear()lugar de hacerlo get(DAY_OF_YEAR). Esto provoca una gran cantidad de métodos adicionales en comparación con java.util.Calendar(aunque este último no es de tipo seguro en absoluto debido al uso excesivo de ints).

Actuación

Vea la otra respuesta de @ OO7 señalando el análisis de Mikhail Vorontsov, aunque el punto 3 (captura de excepciones) probablemente sea obsoleto; vea este error JDK . El rendimiento diferente (que es en general favorable a JSR-310 ) se debe principalmente al hecho de que la implementación interna de Joda-Time siempre utiliza una primitiva larga similar a tiempo máquina (en milisegundos).

Nulo

Joda-Time a menudo usa NULL como predeterminado para la zona horaria del sistema, la configuración regional predeterminada, la marca de tiempo actual, etc., mientras que JSR-310 casi siempre rechaza los valores NULL.

Precisión

JSR-310 maneja la precisión de nanosegundos, mientras que Joda-Time se limita a la precisión de milisegundos .

Campos soportados:

Algunas clases en el paquete temporal proporcionan una descripción general de los campos compatibles en Java-8 (JSR-310) (por ejemplo, ChronoField y WeekFields ), mientras que Joda-Time es bastante débil en esta área; consulte DateTimeFieldType . La mayor falta de Joda-Time es aquí la ausencia de campos locales relacionados con la semana. Una característica común de ambos diseños de implementación de campo es que ambos se basan en valores de tipo largo (no hay otros tipos, ni siquiera enumeraciones).

Enum

JSR-310 ofrece enumeraciones como DayOfWeeko Monthmientras Joda-Time no ofrece esto porque se desarrolló principalmente en los años 2002-2004 antes de Java 5 .

API de zona

a) JSR-310 ofrece más funciones de zona horaria que Joda-Time. Latter no puede proporcionar un acceso programático al historial de transiciones de desplazamiento de zona horaria, mientras que JSR-310 es capaz de hacerlo.

b) Para su información: JSR-310 ha movido su repositorio de zona horaria interna a una nueva ubicación y un formato diferente. La antigua carpeta de biblioteca lib / zi ya no existe.

Ajustador vs. Propiedad

JSR-310 ha introducido la TemporalAdjusterinterfaz como una forma formalizada de externalizar los cálculos y manipulaciones temporales, especialmente para los escritores de bibliotecas o marcos. Esta es una manera agradable y relativamente fácil de incorporar nuevas extensiones de JSR-310 (una especie de equivalente a la ayuda estática clases para ex java.util.Date).

Sin embargo, para la mayoría de los usuarios, esta característica tiene un valor muy limitado porque la carga de escribir código aún recae en el usuario. Las soluciones TemporalAdjusterintegradas basadas en el nuevo concepto no son muchas, actualmente solo existe la clase auxiliar TemporalAdjusterscon un conjunto limitado de manipulaciones (y las enumeraciones Monthu otros tipos temporales).

Joda-Time ofrece un paquete de campo, pero la práctica ha demostrado que las nuevas implementaciones de campo son muy difíciles de codificar. Por otro lado, Joda-Time ofrece las llamadas propiedades que hacen que algunas manipulaciones sean mucho más fáciles y elegantes que en JSR-310, por ejemplo, property.withMaximumValue () .

Sistemas de calendario

JSR-310 ofrece 4 sistemas de calendario adicionales. El más interesante es Umalqura (usado en Arabia Saudita). Los otros 3 son: Minguo (Taiwán), japonés (¡solo el calendario moderno desde 1871!) Y ThaiBuddhist (solo correcto después de 1940).

Joda-Time ofrece un calendario islámico basado en una base calculadora, no un calendario basado en avistamientos como Umalqura. El budista tailandés también es ofrecido por Joda-Time en una forma similar, Minguo y el japonés no. De lo contrario, Joda-Time también ofrece un calendario cóptico y etíope (pero sin ningún apoyo para la internacionalización).

Más interesante para los europeos: Joda-Time también ofrece un calendario gregoriano , juliano y mixto gregoriano-juliano. Sin embargo, el valor práctico para los cálculos históricos reales es limitado porque las características importantes como los diferentes años de inicio en el historial de fechas no son compatibles (la misma crítica es válida para los antiguos java.util.GregorianCalendar).

Otros calendarios como el hebreo o el persa o hindú están completamente ausentes en ambas bibliotecas.

Días de la época

JSR-310 tiene la clase JulianFields, mientras que Joda-Time (versión 2.0) ofrece algunos métodos auxiliares en la clase DateTimeUtils .

Relojes

JSR-310 no tiene interfaz (un error de diseño) sino una clase abstracta java.time.Clockque puede usarse para cualquier inyección de dependencia de reloj. Joda-Time ofrece la interfaz MillisProvider y algunos métodos auxiliares en DateTimeUtils . De esta forma, Joda-Time también es capaz de admitir modelos probados con diferentes relojes (burlas, etc.).

Aritmética de duración

Ambas bibliotecas admiten el cálculo de distancias de tiempo en una o más unidades temporales. Sin embargo, cuando se manejan duraciones de una sola unidad, el estilo JSR-310 es obviamente más agradable (y de base larga en lugar de usar int):

JSR-310 => long days = ChronoUnit.DAYS.between(date1, date2);

Joda-Time => int days = DAYS.daysBetween(date1, date2).getDays();

El manejo de múltiples unidades de duración también es diferente. Incluso los resultados del cálculo pueden diferir; vea este problema cerrado de Joda-Time . Mientras que JSR-310 usa un enfoque muy simple y limitado para usar solo las clases Period(duración basada en años, meses y días) y Duration(basado en segundos y nanosegundos), Joda-Time usa una forma más sofisticada usando la clase PeriodTypepara controlar en qué unidades se expresará una duración (Joda-Time lo llama "período"). Mientras que laPeriodType-API es de alguna manera incómodo usar una forma similar que JSR-310 no ofrece en absoluto. Especialmente aún no es posible en JSR-310 definir duraciones mixtas de fecha y hora (basadas en días y horas, por ejemplo). Así que tenga cuidado si se trata de la migración de una biblioteca a otra. Las bibliotecas en discusión son incompatibles, a pesar de tener parcialmente los mismos nombres de clase.

Intervalos

JSR-310 no es compatible con esta característica, mientras que Joda-Time tiene soporte limitado. Vea también esta respuesta SO .

Formateo y análisis

La mejor manera de comparar ambas bibliotecas es ver las clases con el mismo nombre DateTimeFormatterBuilder (JSR-310) y DateTimeFormatterBuilder (Joda-Time). La variante JSR-310 es un poco más potente (también puede manejar cualquier tipo de TemporalFieldcondición siempre que el implementador de campo haya logrado codificar algunos puntos de extensión como resolve () ). Sin embargo, la diferencia más importante es, en mi opinión:

JSR-310 puede analizar mucho mejor los nombres de zonas horarias (símbolo de patrón de formato z), mientras que Joda-Time no pudo hacer esto en sus versiones anteriores y ahora solo de una manera muy limitada.

Otra ventaja de JSR-310 es la compatibilidad con nombres de meses independientes que es importante en idiomas como el ruso o el polaco, etc. Joda-Time no tiene acceso a dichos recursos , ni siquiera en las plataformas Java-8.

La sintaxis del patrón en JSR-310 también es más flexible que en Joda-Time, permite secciones opcionales (usando corchetes), está más orientada hacia el estándar CLDR y ofrece relleno (símbolo de letra p) y más campos.

De lo contrario, debe tenerse en cuenta que Joda-Time puede formatear duraciones usando PeriodFormatter . JSR-310 no puede hacer esto.


Espero que este resumen ayude. Toda la información recopilada está principalmente allí debido a mis esfuerzos e investigaciones sobre cómo diseñar e implementar una mejor biblioteca de fecha y hora (nada es perfecto).

Actualización del 2015-06-24:

Mientras tanto, he encontrado el tiempo para escribir y publicar una descripción tabular para diferentes bibliotecas de tiempo en Java. Las tablas también contienen una comparación entre Joda-Time v2.8.1 y Java-8 (JSR-310). Es más detallado que este post.

Meno Hochschild
fuente
12
Esta es una publicación sobresaliente. Muchas gracias por compartir toda esta información. Si tuviera la opción entre Joda y JSR-310 (solo para casos de uso de vainilla), ¿cuál elegiría? Estoy enfrentando esta elección en este momento. Estoy considerando JSR-310, solo porque es más nuevo y trato de apoyar "avanzar" siempre que sea posible.
kevinarpe
77
@kevinarpe Si solo tuviera la opción entre JSR-310 y Joda-Time, probablemente preferiría JSR-310 porque Joda-Time casi ha detenido cualquier desarrollo adicional (no se pueden esperar nuevas características grandes, solo corrección de errores y pequeñas actualizaciones). Y el diseño de JSR-310 es simplemente más moderno (y con mejor calidad interna). Por cierto, y no es sorprendente, sin embargo, mi verdadera decisión es preferir mi propia biblioteca Time4J; vea también el enlace a la descripción general en forma de tabla que se encuentra al final de mi publicación. Siempre es bueno tener alternativas, y depende en gran medida de las características que necesite.
Meno Hochschild
¿No es la versión de Duración de Java8 de un intervalo?
Christian Hujer
1
@ChristianHujer No, java.time.Durationno se puede consultar su inicio o final, en contraste con un intervalo que está anclado en una línea de tiempo. Este tipo JSR-310 es solo un par de segundos y nanosegundos transcurridos desde un inicio desconocido.
Meno Hochschild el
42

Java 8 Fecha / Hora:

  1. Las clases de Java 8 se construyen alrededor del tiempo humano. Los hace rápidos para la aritmética / conversión de fecha y hora humana.
  2. Los captadores de componentes de fecha / hora getDayOfMonthtienen complejidad O (1) en la implementación de Java 8.
  3. El análisis de OffsetDateTime/ OffsetTime/ ZonedDateTimees muy lento en Java 8 ea b121 debido a excepciones lanzadas y atrapadas internamente en el JDK.
  4. Un conjunto de paquetes: java.time.*, java.time.chrono.*, java.time.format.*, java.time.temporal.*,java.time.zone.*
  5. Instantes (marcas de tiempo) Fecha y hora Fecha y hora parcial Analizador y formateador Zonas horarias Diferentes cronologías (calendarios).
  6. Las clases existentes tienen problemas como Date no tiene soporte para I18N o L10N. ¡Son mutables!
  7. Más simple y más robusto.
  8. Se pueden inyectar relojes.
  9. Los relojes se pueden crear con varias propiedades: relojes estáticos, relojes simulados, relojes de baja precisión (segundos completos, minutos completos, etc.).
  10. Los relojes se pueden crear con zonas horarias específicas. Clock.system(Zone.of("America/Los_Angeles")).
  11. Hace que la fecha y hora de manejo del código sean comprobables.
  12. Hace pruebas independientes de la zona horaria.

Joda-Time:

  1. Joda-Time está utilizando el tiempo de la máquina en su interior. Una implementación manual basada en valores int / long sería mucho más rápida.
  2. Los captadores de Joda-Time requieren el cálculo del tiempo de computadora a humano en cada llamada de captador, lo que hace que Joda-Time sea un cuello de botella en tales escenarios.
  3. Se compone de clases inmutables que maneja instantes, fecha y hora, parciales y duraciones. Es flexible. Está bien diseñado.
  4. Representa las fechas como instantes. Pero una fecha y hora pueden corresponder a más de un instante. Hora superpuesta cuando finaliza el horario de verano. Además de no tener ningún instante que le corresponda en absoluto. Hora de intervalo cuando comienza la luz del día. Tiene que realizar cálculos complejos para operaciones simples.
  5. Acepta valores nulos como valores válidos en la mayoría de sus métodos. Conduce a errores sutiles.

Para una comparación más detallada ver: -

Rendimiento de la biblioteca Java 8 Date / Time (así como Joda-Time 2.3 y juCalendar) . & Nueva API de fecha y hora en Java 8

OO7
fuente
Cuando dices "Hace que las pruebas sean independientes de la zona horaria". ¿Qué quieres decir exactamente con eso?
Zack
@Zack: probablemente si prueba el código, que se comporta de manera diferente según la zona horaria, es posible que deba forzar la prueba para que se ejecute con una zona horaria predeterminada diferente a la que proporciona el sistema operativo.
jarnbjo
Hah: pensé que habías dicho que Joda funcionaba internamente en una máquina del tiempo en lugar de una máquina del tiempo ... Y no me sorprendería
Kyranstar
44
@ OO7 ¿Qué quiere decir "tiempo humano"? El tiempo es calculado por las máquinas de todos modos.
IgorGanapolsky
1

Joda-Time ahora está en modo de mantenimiento

No es una respuesta directa a la pregunta, pero el proyecto Joda-Time ya no está en desarrollo activo. El equipo sugiere que los usuarios migren a la nueva API java.time . Ver tutorial de Oracle .

Desde la página oficial del proyecto GitHub :

Joda-time ya no está en desarrollo activo, excepto para mantener actualizados los datos de la zona horaria. Desde Java SE 8 en adelante, se les pide a los usuarios que migren a java.time (JSR-310), una parte central del JDK que reemplaza este proyecto. Para los usuarios de Android, java.time se agrega en API 26+. Los proyectos que necesitan soportar niveles de API más bajos pueden usar la biblioteca ThreeTenABP.

Saikat
fuente