Comprendiendo el Módulo Datetime de Python
Aprende a trabajar con fechas y horas en Python usando el módulo datetime: date, time, datetime, timedelta, strftime, strptime y zonas horarias.
Python no tiene un tipo de dato fecha incorporado y dedicado. En su lugar, el módulo datetime de la biblioteca estándar proporciona un conjunto de herramientas completo para crear, manipular, formatear y analizar fechas y horas. Este capítulo cubre todas las clases principales — date, time, datetime, timedelta y timezone — y muestra patrones prácticos que usarás con regularidad.
Importar el Módulo
El módulo datetime forma parte de la biblioteca estándar y no requiere instalación. Puedes importarlo de dos maneras comunes:
# Import the module and qualify every name
import datetime
today = datetime.date.today()
# Import specific classes directly
from datetime import date, time, datetime, timedelta, timezone
today = date.today()El estilo from datetime import ... es más corto en la práctica y se utiliza a lo largo de este capítulo.
La Clase date
date representa una fecha de calendario (año, mes, día) sin componente de hora del día.
Crear Objetos date
Acceder a los Atributos de date
Una vez que tienes un objeto date, puedes leer su año, mes y día como atributos enteros, y preguntar qué día de la semana corresponde:
from datetime import date
d = date(2024, 6, 15)
print(d.year) # 2024
print(d.month) # 6
print(d.day) # 15
# weekday(): Monday = 0, Sunday = 6
print(d.weekday()) # 5 (Saturday)
# isoweekday(): Monday = 1, Sunday = 7
print(d.isoweekday()) # 6 (Saturday)La Clase time
time representa una hora del día (hora, minuto, segundo, microsegundo) independiente de cualquier fecha concreta.
from datetime import time
# time(hour, minute, second) — all arguments optional, default to 0
t = time(14, 30, 0)
print(t) # 14:30:00
print(t.hour) # 14
print(t.minute) # 30
print(t.second) # 0La clase time es más útil cuando necesitas almacenar o comparar horas del reloj sin importar la fecha, por ejemplo "recuérdame a las 09:00 cada día".
La Clase datetime
datetime es la clase de uso más habitual. Combina una fecha completa y una hora del día en un único objeto y es lo que utilizarás en la mayoría de los programas reales.
Obtener la Fecha y Hora Actuales
from datetime import datetime
# Local system time (naive — no time zone)
now = datetime.now()
print(now) # e.g. 2024-06-15 14:30:45.123456
# UTC time
utc_now = datetime.utcnow()
print(utc_now) # e.g. 2024-06-15 18:30:45.123456Crear Objetos datetime
from datetime import datetime, date, time
# Constructor: datetime(year, month, day, hour=0, minute=0, second=0)
dt = datetime(2024, 6, 15, 14, 30, 45)
print(dt) # 2024-06-15 14:30:45
# From an ISO 8601 string
dt2 = datetime.fromisoformat("2024-06-15T14:30:45")
print(dt2) # 2024-06-15 14:30:45
# Combine a date and a time object
combined = datetime.combine(date(2024, 6, 15), time(14, 30, 0))
print(combined) # 2024-06-15 14:30:00Acceder a los Atributos de datetime
datetime expone todos los atributos tanto de date como de time:
from datetime import datetime
dt = datetime(2024, 6, 15, 14, 30, 45)
print(dt.year) # 2024
print(dt.month) # 6
print(dt.day) # 15
print(dt.hour) # 14
print(dt.minute) # 30
print(dt.second) # 45
# Extract just the date or time part
print(dt.date()) # 2024-06-15
print(dt.time()) # 14:30:45La Clase timedelta
timedelta representa una duración — la diferencia entre dos puntos en el tiempo. Se usa para sumar o restar intervalos de tiempo a objetos date y datetime.
Crear y Usar timedelta
from datetime import date, timedelta
today = date(2024, 6, 15)
# Add 30 days
future = today + timedelta(days=30)
print(future) # 2024-07-15
# Subtract 7 days
last_week = today - timedelta(weeks=1)
print(last_week) # 2024-06-08
# timedelta can express days, seconds, and microseconds
# Convenience arguments: days, seconds, microseconds, milliseconds, minutes, hours, weeks
delta = timedelta(hours=2, minutes=30)
print(delta) # 2:30:00Calcular la Diferencia Entre Dos Fechas
Restar un date o datetime de otro devuelve un timedelta:
from datetime import date
start = date(2024, 1, 1)
end = date(2024, 6, 15)
diff = end - start
print(diff) # 166 days, 0:00:00
print(diff.days) # 166Esta es la forma estándar de calcular cuántos días hay entre dos fechas. Usa .total_seconds() sobre un timedelta si necesitas el intervalo en segundos.
Formatear Fechas y Horas (strftime)
strftime ("string format time") convierte un objeto date o datetime en una cadena legible por humanos. Se pasa una cadena de formato que contiene directivas que comienzan con %.
from datetime import datetime
dt = datetime(2024, 6, 15, 14, 30, 45)
print(dt.strftime("%Y-%m-%d")) # 2024-06-15
print(dt.strftime("%d/%m/%Y")) # 15/06/2024
print(dt.strftime("%A, %B %d, %Y")) # Saturday, June 15, 2024
print(dt.strftime("%I:%M %p")) # 02:30 PM
print(dt.strftime("%Y-%m-%d %H:%M:%S")) # 2024-06-15 14:30:45Directivas Comunes de strftime
| Directiva | Significado | Ejemplo |
|---|---|---|
%Y | Año de 4 dígitos | 2024 |
%y | Año de 2 dígitos | 24 |
%m | Mes como número con cero inicial | 06 |
%B | Nombre completo del mes | June |
%b | Nombre abreviado del mes | Jun |
%d | Día del mes, con cero inicial | 15 |
%A | Nombre completo del día de la semana | Saturday |
%a | Nombre abreviado del día de la semana | Sat |
%H | Hora (reloj de 24 horas) | 14 |
%I | Hora (reloj de 12 horas) | 02 |
%M | Minuto | 30 |
%S | Segundo | 45 |
%p | AM o PM | PM |
%j | Día del año | 167 |
%W | Número de semana del año | 24 |
Analizar Fechas y Horas (strptime)
strptime ("string parse time") es el inverso de strftime: convierte una cadena en un objeto datetime. Debes proporcionar una cadena de formato que coincida con la entrada.
Un error común: strptime siempre devuelve un datetime, incluso cuando la cadena solo contiene una fecha. Llama a .date() sobre el resultado si necesitas un objeto date simple.
Formato ISO 8601
El estándar ISO 8601 (YYYY-MM-DDTHH:MM:SS) es la forma más portable de intercambiar valores de fecha y hora. Python tiene ayudantes integrados para ello:
from datetime import datetime
dt = datetime(2024, 6, 15, 14, 30, 45)
# Produce ISO 8601 string
print(dt.isoformat()) # 2024-06-15T14:30:45
# Parse ISO 8601 string (Python 3.7+)
dt2 = datetime.fromisoformat("2024-06-15T14:30:45")
print(dt2) # 2024-06-15 14:30:45Trabajar con Marcas de Tiempo
Una marca de tiempo Unix es el número de segundos transcurridos desde el 1 de enero de 1970 a las 00:00:00 UTC. Python puede convertir entre marcas de tiempo y objetos datetime:
Zonas Horarias
De forma predeterminada, datetime.now() devuelve un datetime naive (sin información de zona horaria). Adjuntar un objeto tzinfo lo convierte en aware (consciente). Los datetimes aware son esenciales cuando tu programa gestiona usuarios en múltiples zonas horarias o almacena marcas de tiempo en una base de datos.
Usar el timezone Integrado
datetime.timezone proporciona timezone.utc y permite crear zonas con desplazamiento fijo:
from datetime import datetime, timezone, timedelta
# Create an aware UTC datetime
utc_dt = datetime(2024, 6, 15, 14, 30, 45, tzinfo=timezone.utc)
print(utc_dt) # 2024-06-15 14:30:45+00:00
# Create a fixed +5:30 (India Standard Time) offset
ist_offset = timezone(timedelta(hours=5, minutes=30))
ist_dt = utc_dt.astimezone(ist_offset)
print(ist_dt) # 2024-06-15 20:00:45+05:30Usar zoneinfo (Python 3.9+)
Para zonas horarias IANA reales como America/New_York o Asia/Tokyo, usa el módulo integrado zoneinfo (Python 3.9+). Gestiona el horario de verano automáticamente.
from datetime import datetime, timezone
from zoneinfo import ZoneInfo
# UTC aware datetime
utc_dt = datetime(2024, 6, 15, 14, 30, 45, tzinfo=timezone.utc)
# Convert to Eastern Time (handles DST automatically)
eastern = ZoneInfo("America/New_York")
eastern_dt = utc_dt.astimezone(eastern)
print(eastern_dt) # 2024-06-15 10:30:45-04:00
# Convert to Tokyo time
tokyo = ZoneInfo("Asia/Tokyo")
tokyo_dt = utc_dt.astimezone(tokyo)
print(tokyo_dt) # 2024-06-15 23:30:45+09:00En Python 3.8 y versiones anteriores, instala la biblioteca de terceros pytz para soporte de zonas IANA.
Reemplazar Componentes
replace() devuelve un nuevo objeto con campos específicos modificados. El original nunca se muta.
from datetime import datetime
dt = datetime(2024, 6, 15, 14, 30, 45)
# Change only the year
dt2 = dt.replace(year=2025)
print(dt2) # 2025-06-15 14:30:45
# Change hour and minute
dt3 = dt.replace(hour=9, minute=0, second=0)
print(dt3) # 2024-06-15 09:00:00Comparar Fechas y Horas
Los objetos date y datetime soportan todos los operadores de comparación estándar:
from datetime import date
d1 = date(2024, 1, 1)
d2 = date(2024, 6, 15)
print(d1 < d2) # True
print(d1 == d2) # False
# Find the earliest date
earliest = min(d1, d2)
print(earliest) # 2024-01-01Solo compara datetimes aware con datetimes aware y naive con naive — mezclarlos lanza un TypeError.
Poniéndolo Todo Junto
Aquí hay un ejemplo práctico que combina varios conceptos: calcula cuántos días faltan para una fecha límite futura y formatea ambas fechas para su visualización.
from datetime import date
deadline = date(2024, 12, 31)
today = date(2024, 6, 15)
days_left = (deadline - today).days
print(f"Today: {today.strftime('%B %d, %Y')}") # June 15, 2024
print(f"Deadline: {deadline.strftime('%B %d, %Y')}") # December 31, 2024
print(f"Days remaining: {days_left}") # 199Referencia Rápida
| Tarea | Código |
|---|---|
| Fecha de hoy | date.today() |
| Fecha y hora actuales | datetime.now() |
| Fecha específica | date(2024, 6, 15) |
| Fecha desde cadena | datetime.strptime(s, fmt) |
| Fecha a cadena | dt.strftime(fmt) |
| Formato ISO | dt.isoformat() / datetime.fromisoformat(s) |
| Sumar/restar días | d + timedelta(days=N) |
| Días entre fechas | (d2 - d1).days |
| Convertir zona horaria | dt.astimezone(ZoneInfo("Zone/Name")) |