example convert java datetime time utc

convert - ¿Cómo sabe(Oracle) Java JVM que está ocurriendo un segundo intercalar?



utc format (4)

Un segundo intercalar ocurrirá el 30 de junio de 2015. Los diferentes sistemas operativos parecen manejar esta situación de manera diferente. En mi caso particular, estamos ejecutando un sistema Red Hat 6.4 con software Java (JDK 1.7) personalizado que depende mucho del tiempo. Según algunos datos recientes publicados por Red Hat , el daemon NTP de nuestro sistema garantizará que el SO maneje automáticamente el segundo intercalar repitiendo 23:59:59 dos veces.

Mi pregunta es: si tengo un proceso JDK 1.7 de larga ejecución, ¿cómo sabe que está ocurriendo un segundo intercalar? Lo que quiero decir es, ¿cómo sabe finalmente Java que las personas de IERS han decidido insertar un segundo intercalar? La documentación de Date parece indicar que está al tanto de los segundos intercalares, pero parece inútilmente vago. ¿Puedo suponer que el JDK, cuando se construye el objeto Date apropiado o se invoca Calendar.getInstance() , se transfiere al manejo de la fecha y hora del SO subyacente para obtener el valor de tiempo "real" apropiado? (Que, en mi caso, suena como si repitiera el segundo 23:59:59, porque así es como el sistema operativo lo manejará).


Depende de tu versión jdk. Si, por ejemplo, está ejecutando la actualización 80, puede consultar las notas de la versión :

JDK 7u80 contiene datos de la zona horaria IANA versión 2015a. Para obtener más información, consulte las versiones de datos de zona horaria en el software JRE.

A continuación, siga el enlace a las versiones de datos de la zona horaria y busque 2015a. Luego siga el enlace a TZ Updater versión 1.4.11 :

Nuevo salto de segundo 30/06/2015 23:59:60 UTC según el Boletín C 49 de IERS. (Gracias a Tim Parenti.)

No parece haberse incluido antes, por lo que si está ejecutando una versión anterior de JDK 7, probablemente no obtenga el ajuste. Aquí encontrará más información sobre cómo funciona internamente.

Para ser honesto, nunca he probado para ver cómo funciona en la práctica.


Estas son mis obervaciones reales, ejecutando un sistema en tiempo real en RHEL 6.3, con Oracle Java JDK 1.7.0_55-b13 (es decir, un JDK obsoleto). Agregué el código de depuración que inició, registrando un nuevo DateTime () cada 0.5 segundos por minuto antes del segundo bisiesto al 30 de junio de 2015 23:59 UTC, y luego se inició después de que el segundo intercalar había terminado. Log follows (para los curiosos, el doble número impreso es el número de segundos desde la época J2000 )

2015-06-30 23:59:59.316 18349217 [main] INFO - Leaper''s time is 488980799.316000 (Tue Jun 30 23:59:59 GMT-00:00 2015) 2015-06-30 23:59:59.817 18349718 [main] INFO - Leaper''s time is 488980799.816000 (Tue Jun 30 23:59:59 GMT-00:00 2015) 2015-07-01 00:00:00.317 18350218 [main] INFO - Leaper''s time is 488980800.317000 (Wed Jul 01 00:00:00 GMT-00:00 2015) 2015-07-01 00:00:00.817 18350718 [main] INFO - Leaper''s time is 488980800.817000 (Wed Jul 01 00:00:00 GMT-00:00 2015) 2015-07-01 00:00:01.318 18351219 [main] INFO - Leaper''s time is 488980801.318000 (Wed Jul 01 00:00:01 GMT-00:00 2015)

Desafortunadamente, eso no me dice mucho, excepto que no insertó el segundo salto canónico a las 23:59:60 (como indican las respuestas de Assylias y Basil Bourque). Mi esperanza era que ''nueva Fecha ()'' llegaría hasta el sistema operativo subyacente (RHEL 6.3, que supuestamente representa los segundos intercalares correctamente) para preguntar la hora actual. Ese no parece ser el caso.

No tenía los recursos para ejecutar otras combinaciones de versiones JDK y RHEL para probar los efectos. Mi mejor versión actual es que la documentación que Basil Bourque encontró sobre la distribución del segundo intercalar en los últimos 1000 segundos del día se aplica a JDK 1.8 y posteriores (ya que es parte de la documentación Instant , que es una característica de Java 8). En mi caso particular, dado que mi JDK 1.7.0_55 anterior no tenía el segundo ajuste de salto para 2015, creo que se aplica la observación de assylias. A saber, que nuestros procesos en tiempo real ahora se ejecutan 1 segundo más adelante, ajenos al segundo intercalar.

Lección aprendida aquí? Asegúrate de que tus sistemas en tiempo real estén completamente actualizados con las últimas actualizaciones, si quieres estar seguro de que representan los próximos segundos intercalares. Tendré que hacer algunas observaciones y un análisis de registro, pero nuestro sistema particular ahora probablemente se ejecute 1 segundo antes que el tiempo real, y tendremos que reiniciar nuestros servicios para volver a la cola.


No olvides que el segundo intercalar ocurre a las 23:59:59 en UT0 esto se aplica en el mismo instante en todas las zonas horarias del mundo, por lo que si estás en zona horaria más 8 ocurrirá a las 23:59:59 - 8 = 15:59:59.

Cualquier cambio de hora local debido a ''horario de verano'' se ignora.

El siguiente segundo es 23:59:60 y luego 00:00:00.

Tenga en cuenta que la especificación de segundos intercalares permite insertar + - 1 o 2 segundos a fines de diciembre o junio.


La respuesta por es correcta. Esta respuesta agrega algunos pensamientos desencadenados por un comentario en esa respuesta. El comentario se refería al cálculo del tiempo transcurrido durante la medianoche cuando está programado un Leap Second.

Esta respuesta también aborda la pregunta original al señalar que para el uso práctico, el tema de Leap Second es discutible, ignorado por los marcos de fecha y hora.

Leap Seconds Ignored

Todos los frameworks comunes de fecha y hora de Java ignoran segundos intercalares, según tengo entendido. Éstas incluyen:

  • java.time
  • Joda-Time
  • java.util.Date/.Calendar (ahora pasado de moda por java.time y Joda-Time)

Doc

Aquí hay extractos de cada documentación de frameworks que muestran que efectivamente ignoran segundos Leap. El énfasis en negrita es mío.

El doc de java.time para la clase Instant :

... Dada la complejidad del cronometraje preciso descrito anteriormente, esta API de Java define su propia escala de tiempo, la Java Time-Scale.

Java Time-Scale divide cada día calendario en exactamente 86400 subdivisiones, conocidas como segundos. Estos segundos pueden diferir del segundo SI. Se aproxima mucho a la escala de tiempo civil internacional de facto, cuya definición cambia de vez en cuando.

Java Time-Scale tiene definiciones ligeramente diferentes para diferentes segmentos de la línea de tiempo, cada una basada en la escala de tiempo internacional de consenso que se utiliza como base para el tiempo civil. Siempre que se modifique o reemplace la escala de tiempo acordada internacionalmente, se debe definir un nuevo segmento de la escala de tiempo de Java. Cada segmento debe cumplir con estos requisitos:

  • la escala de tiempo de Java coincidirá estrechamente con la escala de tiempo civil internacional subyacente;
  • la escala de tiempo de Java coincidirá exactamente con la escala de tiempo civil internacional al mediodía de cada día;
  • Java Time-Scale tendrá una relación definida con precisión a la escala de tiempo civil internacional.

Actualmente, a partir de 2013, hay dos segmentos en la escala de tiempo de Java.

Para el segmento de 1972-11-03 (límite exacto discutido a continuación) hasta nuevo aviso, la escala de tiempo internacional de consenso es UTC (con segundos intercalares). En este segmento, Java Time-Scale es idéntica a UTC-SLS. Esto es idéntico al UTC en días que no tienen un segundo intercalar. En los días que tienen un segundo intercalar, el segundo intercalar se distribuye por igual durante los últimos 1000 segundos del día, manteniendo la apariencia de exactamente 86400 segundos por día .

Para el segmento anterior a 1972-11-03, que se extiende hacia atrás arbitrariamente, la escala de tiempo internacional de consenso se define como UT1, aplicada de forma proéptica, que es equivalente al tiempo solar (medio) en el meridiano principal (Greenwich). En este segmento, Java Time-Scale es idéntica a la escala de tiempo internacional de consenso. El límite exacto entre los dos segmentos es el instante donde UT1 = UTC entre 1972-11-03T00: 00 y 1972-11-04T12: 00.

Las implementaciones de la escala de tiempo de Java utilizando la API JSR-310 no son necesarias para proporcionar ningún reloj que tenga una precisión de segundos o que progrese monótona o sin problemas. Por lo tanto, no se requieren implementaciones para realizar realmente el cambio de UTC-SLS o, de lo contrario, estar al tanto de los segundos intercalares. JSR-310, sin embargo, requiere que las implementaciones deben documentar el enfoque que utilizan al definir un reloj que representa el instante actual. Ver reloj para obtener detalles sobre los relojes disponibles.

La escala de tiempo de Java se utiliza para todas las clases de fecha y hora. Esto incluye Instant, LocalDate, LocalTime, OffsetDateTime, ZonedDateTime y Duration.

Preguntas frecuentes sobre Joda-Time :

Joda-Time no es compatible con los segundos intercalares . Los segundos intercalares se pueden respaldar escribiendo una nueva cronología especializada o realizando algunas mejoras a la clase ZonedChronology existente. En cualquier caso, las versiones futuras de Joda-Time no habilitarán los segundos intercalares por defecto. La mayoría de las aplicaciones no lo necesitan y puede tener costos de rendimiento adicionales.

El documento de la clase java.util.Date :

Un segundo está representado por un número entero de 0 a 61; los valores 60 y 61 ocurren solo por segundos intercalares e incluso solo en implementaciones Java que realmente rastrean los segundos intercalares correctamente .

Hasta donde yo sé, las implementaciones OpenJDK y Oracle no hacen un seguimiento de los segundos intercalares. Por favor, publique tal documentación si la encuentra.

Sin salto segundo al calcular el tiempo transcurrido

En consecuencia, estos marcos no informarán el segundo intercalar adicional al calcular el tiempo transcurrido.

Aquí hay un código de ejemplo que calcula el tiempo transcurrido desde el minuto anterior a la medianoche hasta el minuto posterior, del 30 de junio al 1 de julio de 2015, cuando está programado un Leap Second . Este código prueba Joda-Time 2.8.1 y java-time en la java version "1.8.0_45" . Ignore java.util.Date/.Calendar porque evito esas clases siempre que sea posible; siéntase libre de agregar código aquí para ese caso si así lo desea.

Primero Joda-Time .

// Joda-Time 2.8.1 DateTime startJoda = new DateTime( 2015, 06, 30, 23, 59, 00, DateTimeZone.UTC ); DateTime stopJoda = new DateTime( 2015, 07, 01, 00, 01, 00, DateTimeZone.UTC ); long elapsedMillisJoda = ( stopJoda.getMillis( ) - startJoda.getMillis( ) ); System.out.println( "startJoda: " + startJoda + " stopJoda: " + stopJoda + " = elapsedMillisJoda: " + elapsedMillisJoda );

... y java.time ...

// java.time ZonedDateTime startZdt = ZonedDateTime.of( 2015, 06, 30, 23, 59, 00, 00, ZoneOffset.UTC ); ZonedDateTime stopZdt = ZonedDateTime.of( 2015, 07, 01, 00, 01, 00, 00, ZoneOffset.UTC ); long elapsedMillisZdt = startZdt.until( stopZdt, ChronoUnit.MILLIS ); System.out.println( "startZdt: " + startZdt + " stopZdt: " + stopZdt + " = elapsedMillisZdt: " + elapsedMillisZdt );

Cuando se ejecuta, vemos un resultado de números pares, exactamente dos minutos, 120 segundos o 120,000 milisegundos.

startJoda: 2015-06-30T23:59:00.000Z stopJoda: 2015-07-01T00:01:00.000Z = elapsedMillisJoda: 120000 startZdt: 2015-06-30T23:59Z stopZdt: 2015-07-01T00:01Z = elapsedMillisZdt: 120000

Acerca de java.time

El marco java.time está integrado en Java 8 y posterior. Estas clases suplantan a las problemáticas antiguas clases legacy 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 busque para obtener muchos ejemplos y explicaciones. La especificación es JSR 310 .

Usando un controlador JDBC que cumpla con JDBC 4.2 o posterior, puede intercambiar objetos java.time directamente con su base de datos. No necesita cadenas ni clases java.sql. *.

¿Dónde obtener las clases de java.time?

  • Java SE 8 , Java SE 9 y posterior
    • Incorporado.
    • Parte de la API Java estándar con una implementación integrada.
    • Java 9 agrega algunas características y correcciones menores.
  • Java SE 6 y Java SE 7
    • Gran parte de la funcionalidad de java.time se transfiere a Java 6 y 7 en ThreeTen-Backport .
  • Android
    • Versiones posteriores de las implementaciones del paquete de Android de las clases java.time.
    • Para Android anterior, 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 terreno de prueba para posibles adiciones futuras a java.time. Puede encontrar algunas clases útiles aquí, como Interval , YearWeek , YearQuarter y more .