La mayoria de los problemas en el desarrollo de software suelen surgir de un conocimiento pobre e inconsistente del dominio en cuestion. Un tema aparentemente tan simple como la representacion, serializacion y gestion del tiempo puede causar facilmente una serie de problemas tanto al programador novato como al experimentado.
En este post, veremos que no hace falta ser un Senor del Tiempo para comprender los poquisimos conceptos simples necesarios para no caer en el infierno de la gestion del tiempo.

Representacion
Una pregunta tan simple como "Que hora es?" presupone una serie de sutilezas contextuales que son obvias para el cerebro humano, pero se convierten en un completo sinsentido para un ordenador.
Por ejemplo, si me estuvieras preguntando que hora es ahora mismo, podria decir: "Son las 15:39" y, si fueras un colega en mi oficina, esa seria informacion suficiente para deducir que son las 15:39 CEST. Esto se debe a que ya estarias en posesion de algunos bits de informacion contextual importantes como
- es por la tarde porque ya hemos almorzado
- estamos en Roma, por lo tanto nuestra zona horaria es la Hora Central Europea (CET) o la Hora de Verano de Europa Central (CEST)
- cambiamos al horario de verano hace unas semanas, asi que la zona horaria actual debe ser la Hora de Verano de Europa Central
15:39 es una representacion conveniente del tiempo siempre y cuando estemos en posesion de los bits contextuales. Para representar el tiempo de manera universal, deberian tener una idea de que son UTC y las zonas horarias.
Por favor, no confundan UTC con GMT: aunque su hora coincide, son dos cosas diferentes: uno es un estandar universal mientras que el otro es una zona horaria. Cuando alguien dice que usa GMT, a menos que esa persona tenga un divertido acento escoces, lo que realmente quiere decir es UTC.
Como radioaficionado, tengo contactos con personas de todo el mundo. Cada operador esta obligado a mantener un registro de sus contactos, y normalmente intercambiamos las llamadas tarjetas QSL, que son una confirmacion escrita del contacto. Por supuesto, una tarjeta QSL debe reportar la hora exacta del contacto de radio y por convencion es en UTC. Se que cuando recibo una tarjeta QSL de cualquier colega radioaficionado, sin importar donde este ubicado en todo el mundo, puedo buscar el contacto en mi registro y la informacion de fecha y hora va a coincidir, ya que ambos nos adherimos al mismo estandar: UTC.
Ahora, supongamos que tengo que programar un chat de Skype con un colega desarrollador en los Estados Unidos. Podria escribirle un correo y decir algo como "nos vemos el 2/3". En Italia, eso seria el segundo dia del mes de marzo, pero para una persona estadounidense, eso seria el tercer dia del mes de febrero. Como pueden ver, nuestro chat nunca va a ocurrir.
Estos son solo algunos ejemplos del tipo de problemas que podrian surgir al representar informacion de fecha y hora. Afortunadamente, hay una solucion a los enigmas de la representacion, a saber, el estandar ISO 8601 o, mejor aun, RFC 3339.
Solo para darles un ejemplo, en RFC 3339, 1994-11-05T08:15:30-05:00
corresponde al 5 de noviembre de 1994, 8:15:30 am, Hora Estandar del Este de
los Estados Unidos. 1994-11-05T13:15:30Z corresponde al mismo instante (la
Z significa UTC). Mismo instante, diferentes representaciones.
RFC 3339 tambien tiene el bonito efecto secundario de proporcionar ordenamiento natural en sistemas que utilizan el orden lexicografico (como los sistemas de archivos) porque la informacion esta organizada de la mas a la menos significativa, es decir, ano, mes, dia, hora, minuto, segundo, fraccion de segundo1.
Incluso si solo estan manejando horas locales en su software, deben saber que, a menos que tambien muestren la zona horaria, nunca pueden estar seguros de la hora. No puedo recordar cuantas veces un desarrollador me ha pedido que arregle la hora en el servidor, solo para descubrir que su software estaba imprimiendo la hora en UTC.
En el momento de la visualizacion, esta bien manejar representaciones parciales del tiempo porque la experiencia de usuario asi lo requiere. Solo asegurense, al depurar, de imprimir el conjunto completo de informacion, incluyendo la zona horaria, de lo contrario nunca pueden estar seguros de que lo que estan viendo es lo que realmente creen que es.
Aunque un momento dado en el tiempo es inmutable, hay un numero arbitrario de formas de expresarlo. Y ni siquiera hemos hablado de los calendarios juliano o indio o de cosas como expresar duraciones.
Permitanme resumir algunos puntos clave hasta ahora:
- conozcan las zonas horarias y UTC
- no confundan UTC y GMT
- RFC 3339 y ISO 8601 son sus amigos
- siempre impriman la zona horaria al depurar

Serializacion
Hablando de software, la serializacion es un proceso donde se toma el estado de un objeto y se detalla de tal manera que pueda ser posteriormente reconstruido por completo, exactamente como el original, utilizando la informacion detallada (serializada). Piensen en un archivo xml o json:
{
"person": {
"name": "Mirko",
"surname": "Caserta",
"class": "nerd"
}
}
Esta es la forma serializada de una peculiar instancia imaginaria de la clase persona.
En el mundo binario de los ordenadores, el tiempo se serializa y almacena
normalmente utilizando la convencion del
tiempo Unix. Mientras escribo esto,
mi tiempo Unix es 1366191727. Es decir: 1366191727 segundos han pasado
desde el 1 de enero de 1970 a las 00:00 UTC. No es una forma bastante
inteligente, consistente y compacta de representar una pletora de informacion,
como 17 de abril de 2013 @ 11:42:07am CEST?
El tiempo Unix es solo otra representacion arbitraria de un momento dado en el tiempo, aunque no muy legible para los humanos. Pero pueden tomar ese numero, escribirlo en un trozo de papel, pegarlo a una paloma mensajera, y su destinatario seria capaz de descifrar su mensaje vital simplemente recurriendo a Internet y visitando un sitio como unixtimestamp.com o currentmillis.com.
Si son adictos a la linea de comandos como yo, en sistemas Linux pueden usar:
$ date -d @1366191727
Wed Apr 17 11:42:07 CEST 2013
Sin embargo, en sistemas derivados de BSD como Mac OS X, date -d no funciona asi que tienen que usar en su lugar:
$ date -r 1366191727
Wed Apr 17 11:42:07 CEST 2013
Igual que pueden escribir ese numero en un trozo de papel y despues devolver el instante completo a la vida, pueden almacenarlo en un archivo o en una fila de su RDBMS favorito. Aunque puede que quieran comunicarse con su RDBMS usando un driver apropiado y pasandole una instancia de fecha simple; su driver se encargara entonces de la conversion al formato de serializacion subyacente de la base de datos para instancias de tiempo nativas.
Al almacenar el tiempo usando un formato nativo, obtienen gratuitamente las excelentes funcionalidades de formateo, ordenamiento, consulta, etc. de su RDBMS para el tiempo, asi que puede que quieran pensarlo dos veces antes de almacenar timestamps Unix simples en, digamos, Oracle.
Solo asegurense de saber a que zona horaria se refiere su timestamp Unix, o podrian confundirse despues en el momento de la deserializacion. Por defecto, un timestamp Unix esta en UTC. Si usan las librerias de su sistema, deberian estar bien.
Cuando trabajen con bases de datos, usen los tipos de datos mas apropiados. Por
ejemplo en Oracle, hay
cuatro tipos de datos diferentes:
DATE, TIMESTAMP, TIMESTAMP WITH TIME ZONE y
TIMESTAMP WITH LOCAL TIME ZONE. Ademas, las bases de datos normalmente tienen
un concepto de zona horaria de la base de datos y zona horaria de la sesion, asi
que asegurense de entender como su base de datos especifica los esta usando. Un
usuario que abre una sesion con zona horaria A va a ver valores diferentes que
un usuario que se conecta con zona horaria B.
ISO 8601 tambien es un favorito para la serializacion. De hecho, se usa en el
estandar XML Schema. La mayoria
de los frameworks xml son nativamente capaces de serializar y deserializar de
ida y vuelta entre xs:date, xs:time y xs:dateTime y el formato nativo de
su lenguaje de programacion (y viceversa). Lo mismo aplica para json. Solo
tengan cuidado al manejar representaciones parciales: por ejemplo, si omiten la
zona horaria, asegurense de acordar previamente una por defecto con su
contraparte comunicante (normalmente UTC o su zona horaria local si ambos estan
en la misma).
Gestion
Antes que nada, si creen que pueden escribir su propia libreria de software para la gestion del tiempo, o incluso escribir una pequena rutina que sume o reste valores arbitrarios de la hora del dia, permitanme mostrarles el codigo fuente de las clases java.util.Date y java.util.GregorianCalendar del JDK 7, que pesan respectivamente 1331 y 3179 lineas de codigo.
De acuerdo, estos probablemente no son los mejores ejemplos de rutinas de software que manejan el tiempo, lo admito. Por eso se escribieron librerias Java como Joda Time. De hecho, Joda Time se hizo tan popular que dio origen a JSR-310 y ahora es parte del JDK 8.
El uso de frameworks de tiempo populares, bien disenados e implementados les salvara la vida. En serio. Tomense el tiempo para familiarizarse con la API de su eleccion.
Tareas Comunes de Tiempo en Java
Veamos como todo esto se traduce en codigo java. Cualquier lenguaje sera por supuesto diferente pero todo lo que estoy haciendo aqui deberia ser posible en el lenguaje de su eleccion.
Por favor, no usen java.util.Date ni java.util.Calendar. Ya no usamos esas
clases. La nueva API de tiempo esta en el paquete java.time.
import java.time.*;
import java.time.format.DateTimeFormatter;
import java.time.format.FormatStyle;
class Main {
public static void main(String[] args) {
ZoneId systemDefault = ZoneId.systemDefault();
System.out.println("systemDefault = " + systemDefault);
long now = System.currentTimeMillis();
System.out.println("now = " + now);
LocalDate localDate = LocalDate.now();
System.out.println("localDate = " + localDate);
LocalDateTime localDateTime = LocalDateTime.now();
System.out.println("localDateTime = " + localDateTime);
LocalDateTime utc = LocalDateTime.now(ZoneId.of("UTC"));
System.out.println("utc = " + utc);
ZonedDateTime zonedDateTime1 = ZonedDateTime.now();
System.out.println("zonedDateTime1 = " + zonedDateTime1);
ZonedDateTime zonedDateTime2 = ZonedDateTime.now(ZoneId.of("UTC"));
System.out.println("zonedDateTime2 = " + zonedDateTime2);
String iso8601 = zonedDateTime2.format(DateTimeFormatter.ISO_INSTANT);
System.out.println("iso8601 = " + iso8601);
ZonedDateTime zonedDateTime3 = zonedDateTime2.plus(Duration.ofDays(7));
System.out.println("zonedDateTime3 = " + zonedDateTime3);
Instant nowAsInstant = Instant.ofEpochMilli(now);
System.out.println("nowAsInstant = " + nowAsInstant);
ZonedDateTime nowAsInstantInRome = nowAsInstant.atZone(ZoneId.of("Europe/Rome"));
System.out.println("nowAsInstantInRome = " + nowAsInstantInRome);
LocalDateTime romeLocalTime = nowAsInstantInRome.toLocalDateTime();
System.out.println("romeLocalTime = " + romeLocalTime);
LocalDate localDateInRome = nowAsInstantInRome.toLocalDate();
System.out.println("localDateInRome = " + localDateInRome);
LocalTime localTimeInRome = nowAsInstantInRome.toLocalTime();
System.out.println("localTimeInRome = " + localTimeInRome);
String shortTimeInRome = nowAsInstantInRome.format(DateTimeFormatter.ofLocalizedTime(FormatStyle.SHORT));
System.out.println("shortTimeInRome = " + shortTimeInRome);
String evenShorterTimeInRome = nowAsInstantInRome.format(DateTimeFormatter.ofPattern("HH:mm"));
System.out.println("evenShorterTimeInRome = " + evenShorterTimeInRome);
}
}
Si ejecutan este codigo con java Main.java, deberian ver algo como esto:
systemDefault = Europe/Rome
now = 1753718631998
localDate = 2025-07-28
localDateTime = 2025-07-28T10:03:51.999991
utc = 2025-07-28T16:03:52.000089
zonedDateTime1 = 2025-07-28T10:03:52.000532-06:00[Europe/Rome]
zonedDateTime2 = 2025-07-28T16:03:52.000620Z[UTC]
iso8601 = 2025-07-28T16:03:52.000620Z
zonedDateTime3 = 2025-08-04T16:03:52.000620Z[UTC]
nowAsInstant = 2025-07-28T16:03:51.998Z
nowAsInstantInRome = 2025-07-28T18:03:51.998+02:00[Europe/Rome]
romeLocalTime = 2025-07-28T18:03:51.998
localDateInRome = 2025-07-28
localTimeInRome = 18:03:51.998
shortTimeInRome = 6:03PM
evenShorterTimeInRome = 18:03Pruebas
En Java hay una clase Clock que permite conectar una implementacion de reloj
arbitrariamente configurable para su uso en la API de tiempo. Esto es
especialmente util en pruebas unitarias y depuracion. Otros lenguajes deberian
tener una funcionalidad equivalente.
https://docs.oracle.com/javase/8/docs/api/java/time/Clock.html
Recursos Adicionales
Aqui hay algunos enlaces utiles que he acumulado con el tiempo:
- How to Think About Time in Programming
- UTC is enough for everyone... right?
- The Problem with Time & Timezones - Computerphile
- Falsehoods programmers believe about time
- Storing UTC is not a silver bullet
- The 5 laws of API dates and times
- Storing Date/Times in Databases
- 5 Levels of Handling Date and Time in Python
- Timezone Bullshit
- ISO 8601: the better date format
- A summary of the international standard date and time notation
- A Short History of the Modern Calendar
- Should We 'Heed the Science and Abolish Daylight Saving Time'?
- When a Calendar Defeated Russia in the 1908 Olympics
- Why does China Have Only One Time Zone?
- First day meme
- Glory to ISO8601 Subreddit
- Time.is
- How Ancient Romans Kept Time
- rtc: rk808: Compensate for Rockchip calendar deviation on November 31st
- Daylight saving time is 'not helpful' and has 'no upsides' experts say
- Neil deGrasse Tyson Reminds Us Daylight Saving Time is Ridiculous
- A "Day" Isn't What It Used To Be
- Why Time Zones Exist
- xkcd: Dailight Calendar
- xkcd: Edge Cake
- How does Britain know what time it is?
- Clockwork raises $21M to keep server clocks in sync
- How to Fix Daylight Saving Time
- US Senate Unanimously Passes Bill to Make Daylight Saving Time Permanent
- The Daily WTF: Starting your Date
- Tech Giants Want To Banish the Leap Second To Stop Internet Crashes
- Meta calls for the death of the leap second
- Satellites Keep the World's Clocks on Time. What if They Fail?
- Stop using utcnow and utcfromtimestamp
- Dall'ora legale all'ora solare: i pro e contro del cambio orario e perche si parla di abolizione
- Deer-vehicle collisions spike when daylight saving time ends
- The Falling Dates
- Scientists Don't Want to Count Leap Seconds, so They're Going Away
- What time is it on the Moon?
- What time is it on the moon? Europe pushing for lunar time zone
- What time is it? A simple question with a complex answer. How computers synchronize time
- The Daylight Saving Time Mess Just Won't Go Away
- The best way to handle time zones in a Java web application
- Your Calendrical Fallacy Is...
- Greenland Solves the Daylight Saving Time Debate
- Time Zone and Currency Database in JDK
- (There Ought To Be A) Moonlight Saving Time
- We don't do DST at this company
- Daylight Savings Time be like
- List of 2024 leap day bugs
- California State Legislator Proposes Ending DST
- The science behind why people hate Daylight Saving Time so much
- Storing UTC is not a silver bullet
- JS Dates Are About to Be Fixed
- Researchers Figure Out How To Keep Clocks On the Earth, Moon In Sync 13
- NASA confirms it's developing the Moon's new time zone
- Storing time for human events
- Date and Time Mappings with Hibernate and JPA
- I Found the Dumbest Time Zone
- A Server for Matching Long/Lat to Timezone
- Ianto Cannon's clock graphics
- AlphaDec, a timezone-agonistic time format for humans, machines, and AI
- RFC 3339 vs ISO 8601
- How the tz database works
- A literary appreciation of the Olson/Zoneinfo/tz database
- Benjamin Franklin's Essay on Daylight Saving
- How England Colonized Time
- Cheatsheet & Examples: date
- timekeep.cc
Memes




















asumiendo que se usa la misma zona horaria en todas partes