Continuamos desentrañando el misterio de las horas, orientando la explicación principalmente a programadores.
Hemos establecido qué sistemas de medición de la hora existen. También hemos visto que el estandard de facto es UTC, y por buenas razones.
Y ahora vamos a ver como se pueden representar esas horas en una aplicación.
A efectos prácticos, en este artículo voy a llamar “hora” al conjunto de “fecha+hora“.
Quedabamos en que UTC es una hora universal, que trata de indicar la hora del planeta Tierra en general. No está ligado a ningún país en concreto, ni a ningún continente, sino al planeta entero: España no tiene horas UTC. Argentina no tiene horas UTC. El planeta Tierra sí que tiene horas UTC.
Si en una hora UTC particular es pleno día en España, entonces en esa misma hora UTC será noche cerrada en sus antípodas; y será el amanecer o el anochecer si nos quedamos a medio camino entre ambos puntos.
UTC no sufre saltos [*], sino que avanza siempre a una velocidad constante. Porque el planeta Tierra tampoco sufre saltos ni rotaciones bruscas en ningún momento (menos mal :-D).
[*] Técnicamente sí (tiene saltos por debajo del segundo), pero se puede ignorar perfectamente para este artículo.
Los habitantes de este planeta estamos acostumbrados a hablar en términos locales. Yo, como habitante de Madrid, puedo decir “Me levanto a trabajar a las 07:00”. Un japonés, a su vez, puede decir “Yo también me levanto a trabajar a las 07:00”. Pero obviamente no hablamos de la misma hora UTC, sino de una hora “local”.
Trabajar con horas locales puede ser complicado, por ejemplo cuando el locutor se desplaza de sitio. Si despegas de Madrid a las 10:00 (hora local madrileña), vuelas 10 horas, y aterrizas en Miami, la hora local de Miami no serán las 20:00, sino otra, que hay que calcular en base a unos cuantos factores.
En cambio, si despegas a las 10:00 UTC, sí que aterrizas a las 20:00 UTC.
El offset es, literalmente, la siguiente resta matemática: hora local – hora UTC.
Por ejemplo: La hora local actual en Madrid es finales de Enero a las 20:00. La hora UTC actual en el planeta es finales de Enero a las 19:00 UTC. Por tanto, 20:00 – 19:00 = 01:00 de offset.
Inciso sobre el Horario de Verano:
El Horario de Verano, como sabeis, tiene como objetivo reducir el consumo eléctrico, tener más luz durante las horas laborales, etc (al margen de que se consigan o no dichos propósitos :-P).
Consiste en mover las manecillas de los relojes locales de un país, para atrasar o adelantar la hora local durante unos meses determinados, cada año.
- Lo típico es atrasar o adelantarlo 1h, pero en algunos paises es 30 minutos.
- Cada país lo puede aplicar durante unos meses diferentes: de marzo a octubre, de abril a septiembre… Los días exactos también pueden variar.
- En muchos países ni siquiera se aplica el Horario de Verano.
En cualquier caso, el offset ya lleva incluído el horario de verano cuando se usa, puesto que el offset se obtiene restando la hora local (que ya lleva aplicado el cambio horario) y la hora UTC.
Otro ejemplo: En Agosto de este año se habrá aplicado el horario de verano en Madrid, por lo que el offset no será 01:00h sino 02:00h.
El offset de una localización geográfica puede variar tanto a lo largo de un mismo año, como hemos visto, pero también a lo largo de varios años. Por ejemplo:
Por tanto, es perfectamente posible que dos países tengan el mismo offset durante algunos meses del año, pero difieran durante otros.
Dicho de otra forma: a partir de un offset, no se puede deducir en qué localización te encuentras, ni por tanto qué otros offsets existirán en otros momentos del año.
Por ejemplo: Si no sabes si tu +01:00h actual es de Madrid o del Congo, no puedes saber si en Agosto será un +02:00h (caso de Madrid), o se mantendrá en +01:00h (caso de Congo, sin horario de verano).
Se dice que varias poblaciones están en una misma Zona Horaria, cuando desde el año 1970 han compartido siempre la misma hora local. La nomenclatura es “Area/Localización”.
No hay que confundir con los husos horarios, meridianos ni offsets. Son conceptos diferentes: “UTC+02:00” no es realmente una Zona Horaria, es un Offset respecto de UTC.
Por ejemplo: En España, desde el 1970 hasta ahora, han existido tres regiones que no siempre han compartido completamente las horas locales en todo momento. Las tres zonas horarias (o TZs) son:
Actualmente, esas 3 timezones usan horario de verano, por lo que actualmente sus offsets respectivos de invierno son 1h, 0h y 1h; y los de verano 2h, 1h y 2h.
Cada TZ ha tenido un pasado diferente: algunos aplicaron el horario de verano durante 20 años, otros no lo aplicaron; unos tenian un offset de 5h, otros de 10h, etc.
Toda esa información se almacena en lo que se llama tz database (en castellano, base de datos de zonas horarias).
La tz database debe ser actualizada constantemente, reflejando los cambios horarios que se pueden producir a lo largo de los años.
Una vez que conocemos los conceptos básicos, podemos pasar a la acción:
¿En qué me influye todo eso a la hora de diseñar mi software?
¿Cómo gestiono las horas correctamente?
¿Y si mi usuario vuela de España a la India y cambia el reloj de su portatil?
¿Y si mi usuario quiere introducir la hora local de despegue y la hora local de aterrizaje en mi software de calendario?
¿Y si mi software tiene varios usuarios simultáneos en diferentes zonas del mundo?
Una política habitual en el mundo de la programación es:
“Almacena y procesa globlamente, muestra localmente“.
Dicho de otra forma: elige un formato neutro para almacenar y operar sobre los datos, y preocúpate de las particularidades culturales cuando debas mostrar o recoger los datos de un usuario final.
Recordemos que en este post se usa la palabra “hora” como abreviación de “fecha+hora“.
Empecemos con un ejemplo sencillote:
Tenemos una variable tipo entero, cuyo valor es 7 millones.
- El ordenador almacena y opera globalmente. Concretamente, usa el binario: 00000000011010101100111111000000.
- En cambio al mostrarlo en una hoja de cálculo, nos puede mostrar “7.000.000“, o bien “7,000,000“, o tal vez “7e6“, o incluso “######“, según el contexto local (dónde vivimos, tamaño de la celda, formato del número…).
Tenemos una Hora Local, las 15:00 de un día de Enero. Se le quiere sumar casi medio año (24h*180días=4320h) a esa hora. ¿Cuál será la Hora Local resultante?:
- Las 15:00 hora local, como en la hora de partida.
- Las 16:00 hora local, porque hay que aplicar el Horario de Verano.
- Ninguna de las 2 anteriores.
- Cualquiera de las 3 anteriores.
Y la solución es 4) Cualquiera de las tres anteriores, puesto que depende de la zona horaria:
- En el Moscú actual o el Madrid del año 1910, no hay horario de verano, luego sería 1) Las 15:00.
- En el Madrid actual hay horario de verano, luego sería 2) Las 16:00.
- En la Isla de Lord Howe hay horario de verano de 30m, en vez de la hora típica, luego sería 3) Las 15:30.
Queda claro entonces que la única forma de operar correctamente con horas es pasarlas a UTC, operar sobre ellas y finalmente (si hace falta), convertirlas a la Hora Local de nuestra elección para mostrárselo al usuario final.
Hemos establecido que, para la interfaz con el usuario final, necesitamos conversiones de UTC a Hora Local (al renderizar en pantalla) y viceversa (al aceptar datos del usuario)
Si habéis entendido perfectamente todo lo explicado hasta hora, se pueden deducir cuáles son las posibles conversiones inequívocas que podemos hacer:
[table id=3 /]
January 29th, 2012 at 14:49
[…] (function() { var po = document.createElement('script'); po.type = 'text/javascript'; po.async = true; po.src = 'https://apis.google.com/js/plusone.js'; var s = document.getElementsByTagName('script')[0]; s.parentNode.insertBefore(po, s); })();Tweet[ Ir a la parte 2 de 2: "Zonas horarias, DST, Desplazamientos y otras zarandajas" ] […]
January 30th, 2012 at 11:26
Muy interesante. Me gustaría hacer una puntualización muy sutil, y es que ¡UTC si salta! aunque a efectos práticos es como si no lo hiciese:
http://es.wikipedia.org/wiki/Segundo_intercalar
January 30th, 2012 at 11:34
Efectivamente crc, lo explico en la Parte 1 [*], pero voy a puntualizarlo para dejarlo más claro en este post.
[*] http://www.stenyak.com/archives/1004/sobre-la-hora-universal-y-los-relojes-atomicos-o-que-tienen-en-comun-el-tomtom-y-unos-trigales/
January 30th, 2012 at 16:46
Muy didácticos e ilustrativos ambos blogs sobre el tiempo, muchas gracias.
Por fin sabemos cómo es un cuásar!… 😉