¿Por qué a las clases Java 8 java.time les falta un método getMillis ()?

62

Java 8 tiene una biblioteca completamente nueva para fechas y horas en el paquete java.time, algo que es muy bienvenido para cualquiera que haya tenido que usar JodaTime antes o con problemas para crear sus propios métodos de ayuda para el procesamiento de fechas. Muchas clases en este paquete representan las marcas de tiempo y tienen métodos de ayuda como getHour() para obtener horas de la marca de tiempo, getMinute() para obtener minutos de la marca de tiempo, getNano() para obtener nanos de la marca de tiempo, etc ...

Noté que no tienen un método llamado getMillis() para obtener los milis de la marca de tiempo. En su lugar, uno tendría que llamar al método get(ChronoField.MILLI_OF_SECOND) . A mí me parece una inconsistencia en la biblioteca. ¿Alguien sabe por qué falta este método, o como Java 8 aún está en desarrollo, existe la posibilidad de que se agregue más adelante?

enlace

  

Las clases definidas aquí representan los principales conceptos de fecha y hora, incluidos instantes, duraciones, fechas, horas, zonas horarias y períodos. Se basan en el sistema de calendario ISO, que es el calendario mundial de facto que sigue las reglas gregorianas prolepticas. Todas las clases son inmutables y seguras para subprocesos.

     

Cada instancia de fecha y hora está compuesta por campos que las API facilitan convenientemente. Para acceder a los campos de nivel inferior, consulte el paquete java.time.temporal . Cada clase incluye soporte para imprimir y analizar todo tipo de fechas y horas. Consulte el paquete java.time.format para las opciones de personalización ...

Ejemplo de este tipo de clase:
enlace

  

Una fecha y hora sin una zona horaria en el sistema de calendario ISO-8601, como 2007-12-03T10: 15: 30.

     

LocalDateTime es un objeto de fecha y hora inmutable que representa una fecha y hora, a menudo visto como año-mes-día-hora-minuto-segundo. También se puede acceder a otros campos de fecha y hora, como día del año, día de la semana y semana del año. El tiempo está representado en nanosegundos de precisión. Por ejemplo, el valor "2 de octubre de 2007 a las 13: 45.30.123456789" se puede almacenar en un LocalDateTime ...

    
pregunta Tarmo 24.01.2014 - 16:17

3 respuestas

61

JSR-310 se basa en nanosegundos, no en milisegundos. Como tal, el conjunto mínimo de métodos sensibles se basa en hora, minutos, segundos y nanosegundos. La decisión de tener una base de nanosegundos fue una de las decisiones originales del proyecto, y creo que creo que es correcta.

Agregar un método para milis se superpondría al de nanosegundos no es una forma obvia. Los usuarios tendrían que pensar si el campo nano era nano-segundo o nano-milli, por ejemplo. Agregar un método adicional confuso no es deseable, por lo que se omitió el método. Como se señaló, la alternativa get(MILLI_OF_SECOND) está disponible.

FWIW, me opondría a agregar el método getMillis() en el futuro.

    
respondido por el JodaStephen 03.02.2014 - 11:51
20

Antes de ser parte de openJDK, threeten estaba en github y antes de eso estaba en sourceforge. En ese entonces, Stephen Colebourne, quien es un líder de especificación en jsr-310, hizo una encuesta que aún puede encontrar en el sitio de sourceforge .

The fourth question on the survey covered the method names for LocalTime:
1) getHourOfDay(), getMinuteOfHour(), getSecondOfMinute(), getNanoOfSecond()
2) getHour(), getMinute(), getSecond(), getNanoOfSecond()
3) getHour(), getMinute(), getSecond(), getNano()
4) another idea

solo el 6.23% eligió la respuesta # 4 y entre ellos aproximadamente el 15% pidió un getMillis() , es decir, menos del 1% del total de votos.

Probablemente esa es la razón por la cual no había getMillis en primer lugar y no pude encontrar nada relacionado en la lista de correo de openjdk, por lo que aparentemente no se trató el tema más adelante.

    
respondido por el assylias 25.01.2014 - 18:19
14

Las clases que representan tiempos UTC no ambiguos (que son Instant, OffsetDateTime, ZonedDateTime) tienen dos métodos de ayuda para acceder al desplazamiento absoluto de la época de Java, es decir, lo que se llama "tiempo de milisegundos" en java.util.Date, que podría utilizar para llegar a milisegundos

long getEpochSecond()
int getNano()

1000L*getEpochSecond() + getNano() / 1000000L;

Algunas razones de por qué se eligió esto en lugar de long getEpochMillis() se analizaron en la lista de correo jsr 310 , algunas de las cuales he extraído por conveniencia:

  

parece razonable suponer que   La precisión de milisegundos no será suficiente. Sin embargo, algo mayor   Que la precisión de nanosegundos parece excesiva

     

...

     

Para implementar esto, mi opción preferida sería de 64 bits de largo   segundos (con firma) + 32 bits en nanosegundos (sin firmar).

     

...

     

Prefiero que la división sea en el segundo nivel ya que ese es el oficial   La unidad de tiempo de SI en ciencia, y el estándar más universalmente aceptado.

     

La división en el nivel de días es problemática para los instantes, ya que no lo hace   manejar segundos de salto. Dividir a nivel de milisegundos, mientras que   Integrarse un poco mejor con el resto de Java, parece realmente bastante   impar. Además, pierde en el rango soportado.

     

Dividir en el segundo como se propone, da un rango de instantes de   Nanosegundos más de 290 mil millones de años. Mientras que nadie debería usar eso   precisión en ese rango de la línea de tiempo, sugeriría que es más fácil   lo soporta para bloquearlo. La división en el nivel de días es problemática para instantes como   no maneja segundos de salto

Tengo la sensación de que otra razón fue para hacer que, de manera intencional, sea difícil convertir las clases de java.util.Date a JSR310, con la esperanza de que los desarrolladores intenten comprender las diferencias entre las distintas opciones y no solo las utilicen a ciegas. nuevas clases.

En cuanto a por qué la clase LocalDateTime no tiene esos métodos, no es posible que existan allí porque LocalDateTime no está vinculado a la línea de tiempo UTC hasta que decida en qué zona se encuentra o qué compensación UTC Es decir, en qué punto tienes un OffsetDateTime o ZonedDateTime (ambos tienen los métodos necesarios).

Alternativamente, podrías definir tu propia constante LOCAL_EPOCH a 1970-01-01T00:00:00 y luego hacer un MILLIS.between(LOCAL_EPOCH, localTime) para obtener algún tipo de duración en milisegundos. Sin embargo, este valor no será compatible con ningún valor devuelto por System.currentTimeMilliseconds() o java.util.Date.getTime() , a menos que, por supuesto, defina que su hora local es la hora UTC; pero en este caso, también puede usar Instant directamente o OffsetDateTime con ZoneOffset.UTC.

    
respondido por el mkadunc 28.01.2014 - 01:34

Lea otras preguntas en las etiquetas