Curso
Trabajar con fechas y horas parece sencillo hasta que entran en juego los formatos, los husos horarios, el horario de verano o marcas de tiempo de varios sistemas; en ese punto, ya no es opción guardar el tiempo como cadenas o enteros sin procesar. El módulo datetime de Python existe para ayudarte a gestionar todas estas piezas de forma predecible.
Esta guía repasa las clases principales, cómo crear y trabajar con objetos datetime, cómo hacer operaciones aritméticas, dar formato y analizar valores, manejar husos horarios y más. Cada sección construye sobre la anterior para que pases de operaciones básicas a patrones más avanzados.
Clases principales del módulo datetime de Python
Antes de nada, conviene entender cómo modela Python las fechas y horas a nivel conceptual. El módulo datetime usa un conjunto pequeño de clases, cada una enfocada en una parte del problema. Saber para qué sirve cada clase facilita mucho el resto del flujo de trabajo.
date
Cuando solo necesitas una fecha de calendario sin preocuparte por la hora del día ni los husos horarios, la clase date es lo que necesitas. Representa año, mes y día mediante atributos familiares.
Estos son los atributos:
-
year -
month -
day
Y estos, los métodos:
-
today() -
fromisoformat() -
replace() -
isoformat() -
weekday() -
isoweekday()
from datetime import date
d = date(2025, 3, 1)
print(d)
Este código crea una fecha de calendario sencilla. Si introduces una combinación no válida (como February 30), Python lanza un ValueError.
time
Algunas tareas solo tienen en cuenta la hora del día, por ejemplo, un recordatorio que se ejecuta a las 14:30. La clase time es útil porque almacena horas, minutos, segundos y, si lo necesitas, microsegundos o datos de zona horaria.
Sus atributos son: hour, minute, second, microsecond, tzinfo
Y sus métodos: replace(), isoformat()
from datetime import time
t = time(14, 30, 15)
print(t)
Esto crea una hora de reloj sin fecha asociada. Los valores no válidos (como hour=27) generarán un error.
datetime
La mayoría de situaciones reales combinan fecha y hora, y ahí es donde entra datetime. Es la clase más versátil del módulo y la que usarás con más frecuencia para registrar, procesar y coordinar eventos.
Sus atributos son (además de todos los anteriores): tzinfo
Y sus métodos: now(), utcnow(), fromisoformat(), strptime(), strftime(), astimezone(). También admite aritmética con timedelta, que verás en detalle más adelante.
from datetime import datetime
dt = datetime(2025, 3, 1, 14, 30)
print(dt)
Esto produce una marca de tiempo completa con componentes de fecha y hora.
timedelta
Siempre que necesites medir tiempo transcurrido o desplazar una marca de tiempo hacia adelante o atrás, timedelta es la elección adecuada. Representa una duración, no un instante concreto.
Sus atributos son: days, seconds, microseconds. Se usa habitualmente para desplazamientos, diferencias temporales y lógica de programación de tareas.
from datetime import timedelta
delta = timedelta(days=7, hours=3)
print(delta)
Esto representa una duración de longitud fija. Es especialmente útil al sumarla o restarla a un datetime.
tzinfo
tzinfo define la interfaz de Python para husos horarios. No las crearás directamente, pero el sistema de datetime las usa siempre que adjuntas o conviertes zonas horarias.
timezone
timezone es una implementación integrada de tzinfo para desplazamientos UTC fijos como UTC o UTC+1. Es útil para casos sencillos donde no importan las reglas de horario de verano.
Crear y acceder a objetos datetime de Python
Una vez conoces las clases, el siguiente paso es aprender a crear instancias. Python te ofrece varias opciones según el origen de tus datos: entrada manual, hora del sistema, marcas de tiempo o texto.
Uso de constructores de clase
Los constructores te dan control total sobre los valores que creas. A menudo es la forma más explícita y resistente a errores de construir objetos de fecha, hora o datetime.
from datetime import date
d = date(2025, 3, 1)
print(d)
Esto construye directamente una fecha de calendario. Los valores no válidos generan un error de inmediato y ayudan a detectar fallos pronto.
from datetime import time
t = time(14, 30, 15)
print(t)
Esto produce un valor de hora del día. Úsalo cuando no necesites adjuntar la fecha.
from datetime import datetime
dt = datetime(2025, 3, 1, 14, 30)
print(dt)
Esto crea una marca de tiempo completa. Añadir un argumento tzinfo la hace consciente de la zona horaria.
Crear a partir de marcas de tiempo
Las marcas de tiempo Unix aparecen en registros, APIs y sistemas operativos. Python las convierte fácilmente a objetos datetime legibles.
datetime.fromtimestamp(1700000000)
datetime.utcfromtimestamp(1700000000)
La primera interpreta la marca de tiempo en hora local; la segunda la interpreta en UTC.
Métodos de clase para valores actuales
Cuando necesitas la fecha u hora actual, Python ofrece atajos sencillos. Son esenciales para registro, seguimiento de eventos y canalizaciones en tiempo real.
from datetime import datetime, date, timezone
print(date.today())
print(datetime.now())
print(datetime.now(tz=timezone.utc)) # Python 3.12+ preferido
Esto te da la hora actual del sistema en hora local o en UTC, según lo que necesites.
datetime.fromtimestamp(1700000000)
datetime.utcfromtimestamp(1700000000)
Estas funciones convierten marcas de tiempo del epoch en objetos datetime. Son muy habituales al analizar valores de APIs o bases de datos.
Análisis desde cadenas
En conjuntos de datos reales, las marcas de tiempo suelen guardarse como texto. Python ofrece herramientas fiables para convertir esas cadenas en valores estructurados.
strptime()
from datetime import datetime
dt = datetime.strptime("2025-03-01 14:30", "%Y-%m-%d %H:%M")
print(dt)
strptime() analiza una cadena usando un patrón de formato. Si la cadena no coincide exactamente, Python lanza ValueError.
from datetime import datetime
dt = datetime.strptime("not-a-date", "%Y-%m-%d")
Esto fallará porque la entrada no coincide con el patrón esperado.
fromisoformat()
datetime.fromisoformat("2025-03-01T14:30:00")
Las cadenas ISO 8601 se analizan sin problemas porque su estructura está estandarizada. A menudo es la forma más sencilla de cargar marcas de tiempo desde APIs o canalizaciones modernas de datos.
Realizar aritmética con fechas
Una vez puedes crear marcas de tiempo, el siguiente paso es trabajar con ellas. Puedes calcular duraciones, desplazar fechas o comparar intervalos.
Timedelta para cálculos temporales
timedelta modela periodos de duración fija como «5 horas» o «2 semanas». Son útiles para programación de tareas, registro y, si necesitas, una cuenta atrás sencilla.
from datetime import datetime, timedelta
dt = datetime(2025, 3, 1, 14, 30)
new_dt = dt + timedelta(days=5)
print(new_dt)
Este ejemplo desplaza la marca de tiempo cinco días hacia adelante.
start = datetime(2025, 3, 1, 9, 0)
end = datetime(2025, 3, 1, 14, 30)
duration = end - start
print(duration.total_seconds())
Aquí, restar dos datetime te da un timedelta, que puedes convertir a segundos, días u horas.
Duración fija vs. aritmética consciente del calendario
No todas las unidades de tiempo son iguales. Los meses varían en longitud, los años pueden tener días bisiestos y el comportamiento a fin de mes puede ser impredecible. Para estos casos, timedelta no basta.
dateutil.relativedelta gestiona la aritmética «consciente del calendario»:
from dateutil.relativedelta import relativedelta
from datetime import date
d = date(2025, 1, 31)
print(d + relativedelta(months=1))
Esto gestiona correctamente el caso sin «31 de febrero» desplazando la fecha de forma adecuada.
Dar formato y analizar fechas
El formateo de datetime está en todas partes: las APIs esperan formatos concretos, las personas prefieren texto legible y los registros dependen de cadenas de tiempo coherentes. Python admite formatos flexibles y representaciones estandarizadas.
Formato de cadenas con strftime
strftime() te permite convertir objetos datetime en cadenas con formato usando códigos predefinidos.
from datetime import datetime
dt = datetime(2025, 3, 1, 14, 30)
print(dt.strftime("%A, %B %d, %Y at %H:%M"))
Esto imprime una cadena legible con el día de la semana y el nombre completo del mes.
dt.strftime("%Y-%m-%dT%H:%M:%S")
Esto produce una cadena de estilo ISO adecuada para almacenamiento de datos o APIs.
Análisis de cadenas con strptime
from datetime import datetime
dt = datetime.strptime("2025-03-01 14:30", "%Y-%m-%d %H:%M")
print(dt)
Esto convierte texto en un objeto datetime. Cualquier discrepancia entre cadena y patrón lanza un error.
Trabajar con ISO 8601 y RFC 3339
ISO 8601 resuelve la ambigüedad de muchos formatos regionales de fecha. Python lo admite de forma nativa:
from datetime import datetime
dt = datetime.fromisoformat("2025-03-01T14:30:00")
print(dt.isoformat())
Es el formato más seguro al intercambiar datos entre sistemas, APIs o bases de datos.
Gestión de husos horarios
Los husos horarios introducen algunos de los retos más complejos en programación temporal. Python ayuda diferenciando entre objetos datetime ingenuos y conscientes, y ofreciendo herramientas para manejar zonas reales.
Objetos datetime ingenuos vs. conscientes
Un datetime ingenuo no tiene zona horaria:
from datetime import datetime
naive_dt = datetime(2025, 3, 1, 14, 30)
print(naive_dt.tzinfo) # None
Un datetime consciente incluye un desplazamiento de zona horaria:
from datetime import timezone, timedelta
aware_dt = naive_dt.replace(tzinfo=timezone(timedelta(hours=1)))
print(aware_dt)
Mezclar valores ingenuos y conscientes en comparaciones o aritmética suele causar errores.
Uso del módulo zoneinfo
El módulo zoneinfo de Python da acceso a zonas horarias IANA reales:
from zoneinfo import ZoneInfo
from datetime import datetime
dt = datetime(2025, 3, 1, 14, 30, tzinfo=ZoneInfo("Europe/Paris"))
print(dt)
Convertir la zona horaria es sencillo:
dt.astimezone(ZoneInfo("America/New_York"))
Esto expresa el mismo instante en una zona local diferente.
Convertir entre zonas horarias
Puedes convertir cualquier marca de tiempo consciente a otra zona con astimezone():
from zoneinfo import ZoneInfo
dt_ny = dt.astimezone(ZoneInfo("America/New_York"))
print(dt_ny)
Una buena práctica común es guardar las marcas de tiempo en UTC y convertir solo cuando haga falta mostrarlas.
Comparar y filtrar fechas
Las comparaciones aparecen en casi todos los flujos de trabajo. Piensa en ordenar registros, filtrar eventos o determinar si algo ocurrió antes o después de un umbral.
from datetime import datetime
a = datetime(2025, 3, 1, 12, 0)
b = datetime(2025, 3, 1, 15, 0)
print(a < b) # True
Las comparaciones con zonas horarias tienen en cuenta los desplazamientos:
from datetime import datetime
from zoneinfo import ZoneInfo
dt1 = datetime(2025, 3, 1, 12, 0, tzinfo=ZoneInfo("Europe/London"))
dt2 = datetime(2025, 3, 1, 7, 0, tzinfo=ZoneInfo("America/New_York"))
print(dt1 == dt2) # True — mismo instante en el tiempo
Filtrar colecciones es natural:
dates = [
datetime(2025, 3, 1, 10),
datetime(2025, 2, 20, 9),
datetime(2025, 3, 1, 8)
]
cutoff = datetime(2025, 3, 1)
filtered = [d for d in dates if d >= cutoff]
print(filtered)
La normalización a UTC es útil cuando trabajas entre zonas.
Casos de uso más avanzados
Datetime aparece en muchos flujos más allá del análisis y la aritmética básicos. Estos son algunos patrones que verás a menudo.
Marcas de tiempo Unix
Las marcas de tiempo Unix miden los segundos desde el 1 de enero de 1970 (UTC). Se usan ampliamente en programación de sistemas y APIs.
from datetime import datetime
dt = datetime.fromtimestamp(1700000000)
print(dt)
Milisegundos y microsegundos requieren escalar:
ts_ms = 1700000000000
dt_ms = datetime.fromtimestamp(ts_ms / 1000)
ts_us = 1700000000000000
dt_us = datetime.fromtimestamp(ts_us / 1_000_000)
Planificación y temporizadores
Librerías como schedule dependen de valores datetime para decidir cuándo deben ejecutarse las tareas. Tanto si disparas funciones cada pocos segundos como si programas un evento puntual más tarde ese día, datetime sienta las bases para esas comparaciones.
Patrones de análisis de datos
A menudo se extraen atributos de datetime para agrupar y analizar por tiempo:
dt = datetime(2025, 3, 1, 14, 30)
print(dt.year)
print(dt.isocalendar())
En pandas, el remuestreo por periodo es muy común:
import pandas as pd
df = pd.DataFrame({
"value": [10, 12, 15],
"timestamp": pd.to_datetime([
"2025-03-01",
"2025-03-02",
"2025-03-08"
])
}).set_index("timestamp")
print(df.resample("W").sum())
Conclusión
Para saber más sobre datetime, echa un vistazo a este vídeo de nuestro curso Working with Dates and Times in Python de Max Shrom y Data Types for Data Science in Python de Jason Myers.
También te puede interesar nuestro tutorial Converting Strings to Dates as datetime Objects si necesitas un poco de ayuda extra para convertir cadenas.
Redactor técnico especializado en IA, ML y ciencia de datos, que hace que las ideas complejas sean claras y accesibles.

