2009-12-28 15 views
76

Muy a menudo encuentro comentarios negativos sobre Java Date y otras clases relacionadas con la fecha/hora. Siendo un desarrollador de .NET, no puedo entender completamente (sin haberlos usado) lo que está realmente mal con ellos.¿Qué pasa con Java Date & Time API?

¿Alguien puede arrojar algo de luz sobre esto?

+0

Vea también: [Fechas Java: ¿Cuál es la clase correcta de usar?] (Https://stackoverflow.com/q/8511430/642706) –

Respuesta

107

Ah, la clase Java Date. Tal vez uno de los mejores ejemplos de cómo no hacer algo en cualquier idioma, en cualquier lugar. ¿Dónde empiezo?

La lectura de JavaDoc podría llevar a pensar que los desarrolladores han obtenido algunas buenas ideas. Continúa sobre la diferencia entre UTC y GMT en longitud, a pesar de que la diferencia entre los dos es básicamente segundos intercalares (que suceden prettyrarely).

Sin embargo, las decisiones de diseño realmente ponen a perder cualquier pensamiento de ser una API bien diseñada. Éstos son algunos de los errores frecuentes:

  • A pesar de estar diseñado en la última década del milenio, se clasifica como dos dígitos año desde 1900. Hay literalmente millones de soluciones que hacen 1900+ (o 1900-) en el Mundo de Java como resultado de esta decisión banal.
  • Los meses no tienen índice, para atender el caso espectacularmente inusual de tener una serie de meses y no vivir con una matriz de trece elementos, el primero de los cuales contiene un null. Como resultado, tenemos 0..11 (y hoy es el mes 11 del año 109). Hay una cantidad similar de ++ y - en los meses para convertir a una cadena.
  • Son mutable. Como resultado, cada vez que desee devolver una fecha (por ejemplo, como una estructura de instancia) debe devolver un clon de esa fecha en lugar del propio objeto de fecha (ya que de lo contrario, las personas pueden modificar su estructura).
  • El Calendar, diseñado para 'corregir' esto, en realidad comete los mismos errores. Todavía son mutables.
  • Date representa DateTime, pero para diferir a aquellos en SQL tierra, hay otra subclase java.sql.Date, que representa un solo día (aunque sin una zona horaria asociada a él).
  • No hay TimeZone s asociados con un Date, y así rangos (como un 'todo el día') se representan a menudo como la medianoche a medianoche (a menudo en alguna zona horaria arbitraria)

Por último, vale la pena observando que los segundos intercalares generalmente se corrigen frente a un buen reloj del sistema que se actualiza con ntp en una hora (ver enlaces a continuación). La posibilidad de que un sistema siga en funcionamiento en la introducción de dos segundos intercalares (cada seis meses como mínimo, prácticamente cada pocos años) es bastante improbable, especialmente teniendo en cuenta el hecho de que tiene que volver a implementar versiones nuevas de su código de vez en cuando. . Incluso el uso de un lenguaje dinámico que regenera las clases o algo así como un motor de WAR contaminará el espacio de la clase y se quedará sin permgen eventualmente.

+0

+1, también gracias para los enlaces. – Reddy

11

Lo siento por ti ... como antiguo programador .NET, hice las mismas preguntas, el tiempo API en .NET (timespans, sobrecarga del operador) es muy conveniente.

En primer lugar, para crear una fecha específica, se utiliza ya sea una API en desuso, o:

Calendar c = Calendar.getInstance(); 
c.set(2000, 31, 12) 

Para restar un día haces cosas malas como

Date firstDate = ... 
Calendar c = Calendar.getInstance(); 
c.setTime(fistDate); 
c.add(Calendar.DATE,-1); 
Date dayAgo = c.getTime(); 

o peor

Date d = new Date(); 
Date d2 = new Date(d.getTime() - 1000*60*60*24); 

Para saber cuánto tiempo pasó entre dos fechas (en días/semanas/meses) ... se pone aún peor

Sin embargo DateUtils de Apache (org.apache.commons.lang.time.DateUtils) ofrecen algunos métodos convenientes y me encontré usando sólo ellos últimamente

Como escribió Brabster, Joda El tiempo es también una buena biblioteca externa, pero Apache parece más "común" de cualquier otra cosa ...

+0

Por favor, muéstrenos cómo hacerlo ("averigüe cuánto el tiempo pasó entre dos fechas ")! –

+0

Ojalá supiera de una manera fácil ... incluyendo años bisiestos, meses de mal agüero y días volátiles ... –

+10

Maestro Joda (Tiempo), busca, debes. –

25
  • Las instancias de fecha son mutable, lo cual es casi siempre inconveniente.
  • Tienen una doble naturaleza. Representan una marca de tiempo y una fecha de calendario. Resulta que esto es problemático al hacer cálculos en fechas.
  • Las representaciones numéricas de los datos del calendario son contraintuitivas en muchos casos. Por ejemplo: getMonth() tiene base cero, getYear() está basado en 1900 (es decir, el año 2009 se representa como 109).
  • Faltan muchas funcionalidades que espera de una clase Date.
3

La API de fecha de Java se puede utilizar, para ser sincero. La mayoría de los problemas que he visto y oído se relacionan con la verbosidad, la necesidad de involucrar a varias clases para hacer algo útil (Calendar, Date, DateFormat/SimpleDateFormat) y la falta de accesadores simples como getDayOfWeek().

Joda Time es una API alternativa muy respetada en Java, y en la sección Por qué tiempo Joda da más argumentos sobre por qué es una alternativa viable que podría ser de interés.

37

JSR 310, que suplantó las clases pasadas de fecha y hora con java.time en Java 8, se justifica en el original JSR de la siguiente manera:

2,5 ¿Qué necesidad de la comunidad de Java se aborda en las especificaciones propuesto?

Actualmente Java SE tiene dos API de fecha y hora separadas - java.util.Date y java.util.Calendar. Ambas API son consistentemente descritas como difíciles de usar por los desarrolladores de Java en weblogs y foros . Notablemente, ambos usan un índice cero durante meses, que es la causa de muchos errores . Calendario también ha sufrido de muchos errores y problemas de rendimiento durante los años, principalmente debido a almacenar su estado de dos maneras diferentes internamente.

Un error clásico (4639407) impidió que se crearan ciertas fechas en un objeto de calendario . Se podría escribir una secuencia de código que podría crear una fecha en algunos años pero no en otros, teniendo el efecto de evitar que algunos usuarios de ingresen sus fechas de nacimiento correctas. Esto fue causado por la clase de calendario que solo permite una ganancia de horario de verano de de una hora en verano, cuando históricamente era más 2 horas durante la segunda guerra mundial . Si bien este error es ahora fijado, si en algún momento en el futuro un país eligió introducir ganancia de horario de verano de plus tres horas en verano, entonces la clase de calendario volvería a estar rota.

La API Java SE actual también sufre en entornos de subprocesos múltiples. Las clases inmutables son conocidas por ser inherentemente seguras para subprocesos ya que su estado no se puede cambiar. Sin embargo, tanto Date como Calendar son modificables, lo que requiere que los programadores consideren clonar y enhebrar de forma explícita. Además, la falta de seguridad de subprocesos en DateTimeFormat no es ampliamente conocida, y ha sido la causa de muchos problemas difíciles de subprocesamiento de seguimiento de .

Además de los problemas con los que clases Java SE tiene para la fecha y hora, que no tiene clases para modelar otros conceptos. Las fechas de zona no horaria o intervalos de tiempos, períodos y no tienen representación de clase en Java SE. Como resultado, los desarrolladores utilizan con frecuencia un int para representar un período de tiempo , con javadoc especificando la unidad.

La falta de una fecha completa y modelo de tiempo también se traduce en muchas operaciones comunes siendo más complicado de lo que deberían ser . Por ejemplo, calcular la cantidad de días entre dos fechas es un problema particularmente difícil en presente.

Este JSR abordará el problema de un modelo fecha y hora completa, incluyendo fechas y horas (con y sin zonas de tiempo), duraciones y períodos de tiempo, intervalos, el formato y análisis.