Diferencia entre UTC y GMT

❌ La Respuesta aceptada no es correcta ni útil.

✅ En cambio, la Respuesta de Ole V.V. resume correctamente las diferencias técnicas – para más detalles siga los enlaces a las páginas detalladas en Wikipedia.

Para los programadores que construyen aplicaciones orientadas a los negocios, el resultado es que UTC es el nuevo GMT. Se pueden utilizar los términos indistintamente, siendo la diferencia literalmente inferior a un segundo. Así que para todos los efectos prácticos en la mayoría de las aplicaciones, no hay ninguna diferencia.

Aquí hay algunos consejos más prácticos, con ejemplos de código.

Cadenas

Digamos que tengo la hora UTC como «02-01-2018 00:03» ¿significa eso que mi hora local de EEUU es «01-01-2018 18:00»?

Esa primera parte es un mal ejemplo, con la cadena de fecha-hora que carece de un indicador de su desplazamiento o zona.

Si una cadena indica un momento específico, debe indicar o bien una zona horaria (Continent/Region nombre con formato) y/o un offset-from-UTC como un número de horas-minutos-segundos. Si la cadena está destinada a representar un momento en el mismo UTC, eso significa un offset-from-UTC de cero.

Para escribir esa cadena con un offset, se pueden aplicar varias convenciones. La mejor en la práctica es con las horas y los minutos junto con dos puntos, como +00:00+05:30, o -08:00. El cero inicial y los dos puntos son opcionales, pero he visto que las bibliotecas se rompen al encontrar un valor como -0800 o -8.

Zulú

Como atajo para un desplazamiento de cero, la letra Z se utiliza comúnmente para significar el propio UTC. Se pronuncia Zulu.

ISO 8601

Además, la mejor práctica para formatear la fecha-hora textualmente para la informática es utilizar los formatos estándar ISO 8601. Para una fecha-hora se utiliza el formato AAAA-MM-DDTHH:MM:SS±HH:MM:SS. El T separa la parte de la fecha de la parte de la hora. Este formato tiene ventajas tales como ser ampliamente inequívoco, fácil de analizar por la máquina, fácil de leer por los seres humanos a través de las culturas. Otra ventaja es que la ordenación alfabética es también cronológica. El estándar acepta la abreviatura Z también.

Así que tu ejemplo UTC time as "02-01-2018 00:03" se expresa mejor como 2018-01-02T00:03Z.

java.time

Tenga muy en cuenta que la mayoría de los lenguajes de programación, bibliotecas y bases de datos tienen un soporte muy pobre para el manejo de la fecha-hora, generalmente basado en una pobre comprensión de los temas de fecha-hora. El manejo de la fecha-hora es sorprendentemente complicado y difícil de dominar.

La única biblioteca decente que he encontrado son las clases java.time (ver Tutorial) incluidas en Java 8 y posteriores, y su predecesor el proyecto Joda-Time (también vagamente portado de Java a .Net en el proyecto Noda Time).

En java.time, un momento se representa de tres maneras. Todos tienen una resolución de nanosegundos.

  • Instant
    Siempre en UTC. Técnicamente, una cuenta de nanosegundos desde la referencia de época del primer momento de 1970 (1970-01-01T00:00:00Z).
  • OffsetDateTime
    Una fecha con la hora del día en el contexto de un cierto número de horas-minutos-segundos por delante o por detrás de UTC.
  • ZonedDateTime
    Una fecha con la hora del día en el contexto de una determinada zona horaria.
    • Entonces, ¿cuál es la diferencia entre una zona horaria y un offset-from-UTC? Por qué necesitamos clases separadas? Un offset-from-UTC es simplemente un número de horas-minutos-segundos, tres números, ni más ni menos. Un huso horario es mucho más. Un huso horario es una historia de los cambios pasados, presentes y futuros del desfase utilizado por los habitantes de una determinada región.

      ¿Qué cambios? Cambios dictados por los caprichos o la sabiduría de sus políticos. Los políticos de todo el mundo han mostrado su predilección por cambiar el desfase utilizado por la zona o zonas horarias de su jurisdicción. El horario de verano (DST) es un patrón común de cambios, con su horario a menudo cambiado y la decisión de promulgar o revertir el DST a veces cambiada. También se producen otros cambios, como por ejemplo, en los últimos años, Corea del Norte ha cambiado su reloj en media hora para sincronizarlo con Corea del Sur, Venezuela ha retrasado su reloj media hora para volver a adelantarlo menos de una década después, Turquía ha cancelado este año el cambio programado del horario de verano a la hora estándar sin apenas avisar, y la Rusia contemporánea ha realizado múltiples cambios de este tipo en los últimos años.

      Volviendo a tu ejemplo en tu punto # 3, veamos un poco de código.

      Digamos que tengo la hora UTC como «02-01-2018 00:03» ¿significa eso que mi hora local de EEUU es «01-01-2018 18:00»?

      Tus cadenas de ejemplo tienen otro problema. Ese 03 minuto en la primera parte se ignora su segunda parte, una aparente errata. Lo sé porque no hay ningún ajuste de zona horaria en vigor en América en esa fecha que implique una hora fraccionada de 57 minutos.

      Ni un momento

      Primero, analizamos su cadena de entrada. Al carecer de cualquier indicador de zona o desplazamiento, debemos parsear utilizando el LocalDateTime. El nombre LocalDateTime puede ser engañoso, ya que no significa una localidad específica. Significa cualquiera o todas las localidades. Para más explicación, vea ¿Cuál es la diferencia entre Instant y LocalDateTime?

String input = "2018-01-02T00:03" ; // Text of a date with time-of-day but without any context of time zore or offset-from-UTC. *Not* a moment, *not* a point on the timeline.LocalDateTime ldt = LocalDateTime.parse( input ) ; // Parsing the input as a `LocalDateTime`, a class representing a date with time but no zone/offset. Again, this does *not* represent a moment, is *not* a point on the timeline. 

UTC

Por los hechos dados en la Pregunta, sabemos que esta fecha y hora pretendía representar un momento en UTC. Así que podemos asignar el contexto de un offset-from-UTC de cero horas-minutos-segundos para el propio UTC. Aplicamos una ZoneOffset constante UTC para obtener un objeto OffsetDateTime.

OffsetDateTime odt = ldt.atOffset( ZoneOffset.UTC ); // We are certain this text was intended to represent a moment in UTC. So correct the faulty text input by assigning the context of an offset of zero, for UTC itself.

Zona horaria

La Pregunta pide ver este momento a través de un reloj de pared con seis horas de retraso respecto al UTC utilizado en Estados Unidos. Una zona horaria con dicho desfase es America/Chicago.

Especifica un nombre de zona horaria adecuado con el formato de continent/region, como America/MontrealAfrica/Casablanca, o Pacific/Auckland. Nunca utilices la abreviatura de 2 a 4 letras como CSTEST, o IST ya que no son verdaderas zonas horarias, no están estandarizadas, y ni siquiera son únicas(!).

ZoneId z = ZoneId.of( "America/Chicago" ) ; // Adjust from UTC to a time zone where the wall-clock time is six hours behind UTC.ZonedDateTime zdt = odt.atZoneSameInstant( z ) ;

Vea este código ejecutado en vivo en IdeOne.com.

odt.toString(): 2018-01-02T00:03Z

zdt.toString(): 2018-01-01T18:03-06:00

Mismo momento, diferente hora del reloj de pared

Este odt y zdt representan el mismo momento simultáneo, el mismo punto en la línea de tiempo. La única diferencia es la hora del reloj de pared.

Trabajemos con un ejemplo, usando Islandia donde su zona horaria usa un offset-from-UTC de cero horas-minutos-segundos. Así que la zona Atlantic/Reykjavik tiene un tiempo de reloj de pared idéntico al UTC. Al menos actualmente su hora de reloj de pared coincide con UTC; en el pasado o en el futuro puede ser diferente, por lo que es incorrecto decir «UTC es la zona horaria de Islandia». En cualquier caso, nuestro ejemplo… digamos que alguien en Reikiavik, Islandia, con 3 minutos después de la medianoche en el reloj que cuelga de su pared, hace una llamada telefónica a alguien en Estados Unidos. Esa persona de EE.UU. vive en un lugar que utiliza la zona horaria de la región de Chicago. Cuando la persona a la que se llama coge el teléfono, mira el reloj que cuelga de su pared y ve que la hora es justo después de las 6 de la tarde (18:03). Mismo momento, diferente hora del reloj de pared.

También los calendarios que cuelgan de sus paredes son diferentes, ya que es «mañana» en Islandia pero «ayer» en Estados Unidos. Mismo momento, diferentes fechas!

Tabla de tipos de fecha-hora en Java, tanto modernos como heredados.

Acerca de java.time

El framework java.time está incorporado en Java 8 y posteriores. Estas clases suplantan a las molestas y antiguas clases de fecha-hora heredadas como java.util.DateCalendar&SimpleDateFormat.

El proyecto Joda-Time, ahora en modo de mantenimiento, aconseja la migración a las clases java.time.

Para saber más, consulte el tutorial de Oracle. Y busca en Stack Overflow 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 que cumpla con JDBC 4.2 o posterior. No se necesitan cadenas, ni clases java.sql.*.

¿Dónde obtener las clases java.time?

  • Java SE 8, Java SE 9, Java SE 10, Java SE 11, y posteriores – Parte de la API estándar de Java con una implementación incluida.
    • Java 9 añade algunas características menores y correcciones.
  • Java SE 6 y Java SE 7
    • La mayor parte de la funcionalidad de java.time se ha retroportado a Java 6 & 7 en ThreeTen-Backport.
  • Android
    • Las versiones posteriores de Android agrupan implementaciones de las clases java.time classes.
    • Para Android anteriores (<26), el proyecto ThreeTenABP adapta ThreeTen-Backport (mencionado anteriormente). Ver Cómo usar ThreeTenABP….
  • Tabla de qué librería java.time usar con qué versión de Java o Android

    El proyecto ThreeTen-Extra extiende java.time con clases adicionales. Este proyecto es un campo de pruebas para posibles adiciones futuras a java.time. Puedes encontrar algunas clases útiles aquí como IntervalYearWeekYearQuarter, y más.

Deja una respuesta

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *