Objetos date, time y datetime
El módulo datetime
de Python proporciona clases para manipular fechas y horas de manera sencilla y eficiente. Este módulo forma parte de la biblioteca estándar, por lo que no requiere instalación adicional. Las tres clases principales que ofrece son date
, time
y datetime
, cada una con un propósito específico.
La clase date
La clase date
representa una fecha en el calendario gregoriano, compuesta por año, mes y día. Es ideal cuando solo necesitamos trabajar con fechas sin componente horario.
Para crear un objeto date
, podemos utilizar su constructor:
from datetime import date
# Crear una fecha específica (año, mes, día)
fecha = date(2023, 10, 15)
print(fecha) # 2023-10-15
También podemos obtener la fecha actual mediante el método today()
:
from datetime import date
# Obtener la fecha actual
hoy = date.today()
print(hoy) # Muestra la fecha actual en formato AAAA-MM-DD
Los objetos date
tienen varios atributos útiles para acceder a sus componentes:
from datetime import date
fecha = date(2023, 10, 15)
# Acceder a los componentes individuales
print(fecha.year) # 2023
print(fecha.month) # 10
print(fecha.day) # 15
# Obtener el día de la semana (0=lunes, 6=domingo)
print(fecha.weekday()) # Devuelve el día de la semana (0-6)
# Formato alternativo para día de la semana (1=lunes, 7=domingo)
print(fecha.isoweekday()) # Devuelve el día de la semana (1-7)
La clase time
La clase time
representa una hora del día, independiente de cualquier fecha particular. Incluye hora, minuto, segundo y microsegundo.
Para crear un objeto time
:
from datetime import time
# Crear una hora específica (hora, minuto, segundo, microsegundo)
hora = time(14, 30, 15, 500000)
print(hora) # 14:30:15.500000
# También podemos crear una hora con menos parámetros
hora_simple = time(14, 30)
print(hora_simple) # 14:30:00
Al igual que con date
, podemos acceder a los componentes individuales:
from datetime import time
hora = time(14, 30, 15, 500000)
# Acceder a los componentes
print(hora.hour) # 14
print(hora.minute) # 30
print(hora.second) # 15
print(hora.microsecond) # 500000
La clase datetime
La clase datetime
combina la funcionalidad de date
y time
, permitiéndonos trabajar con fechas y horas simultáneamente. Es probablemente la clase más utilizada del módulo.
Para crear un objeto datetime
:
from datetime import datetime
# Crear un datetime específico (año, mes, día, hora, minuto, segundo, microsegundo)
fecha_hora = datetime(2023, 10, 15, 14, 30, 15, 500000)
print(fecha_hora) # 2023-10-15 14:30:15.500000
También podemos obtener el momento actual:
from datetime import datetime
# Obtener el datetime actual
ahora = datetime.now()
print(ahora) # Muestra la fecha y hora actuales
# Alternativa: datetime.today() (similar a now() pero sin zona horaria)
hoy = datetime.today()
print(hoy)
Los objetos datetime
combinan los atributos de date
y time
:
from datetime import datetime
fecha_hora = datetime(2023, 10, 15, 14, 30, 15)
# Componentes de fecha
print(fecha_hora.year) # 2023
print(fecha_hora.month) # 10
print(fecha_hora.day) # 15
# Componentes de hora
print(fecha_hora.hour) # 14
print(fecha_hora.minute) # 30
print(fecha_hora.second) # 15
Conversión entre tipos
Es posible convertir entre los diferentes tipos de objetos:
from datetime import date, time, datetime
# Obtener date y time a partir de un datetime
fecha_hora = datetime(2023, 10, 15, 14, 30)
solo_fecha = fecha_hora.date() # Extrae solo la parte de fecha
solo_hora = fecha_hora.time() # Extrae solo la parte de hora
print(solo_fecha) # 2023-10-15
print(solo_hora) # 14:30:00
# Combinar un date y un time para crear un datetime
fecha = date(2023, 10, 15)
hora = time(14, 30)
fecha_hora_combinada = datetime.combine(fecha, hora)
print(fecha_hora_combinada) # 2023-10-15 14:30:00
Casos de uso prácticos
Los objetos de fecha y hora son útiles en muchos escenarios cotidianos:
- Cálculo de edad:
from datetime import date
def calcular_edad(fecha_nacimiento):
hoy = date.today()
edad = hoy.year - fecha_nacimiento.year - ((hoy.month, hoy.day) < (fecha_nacimiento.month, fecha_nacimiento.day))
return edad
# Ejemplo de uso
fecha_nacimiento = date(1990, 5, 15)
edad = calcular_edad(fecha_nacimiento)
print(f"Tienes {edad} años") # Muestra la edad calculada
- Registro de tiempo de ejecución:
from datetime import datetime
# Registrar el tiempo de inicio
inicio = datetime.now()
# Simulación de una operación que lleva tiempo
for i in range(1000000):
pass
# Registrar el tiempo de finalización
fin = datetime.now()
# Calcular la duración
duracion = fin - inicio
print(f"La operación tardó {duracion.total_seconds()} segundos")
- Planificación de eventos:
from datetime import datetime, timedelta
# Supongamos que tenemos un evento programado
evento = datetime(2023, 12, 31, 23, 0) # Nochevieja a las 23:00
# Calcular cuánto tiempo falta para el evento
ahora = datetime.now()
tiempo_restante = evento - ahora
if tiempo_restante.total_seconds() > 0:
dias = tiempo_restante.days
horas = tiempo_restante.seconds // 3600
minutos = (tiempo_restante.seconds % 3600) // 60
print(f"Faltan {dias} días, {horas} horas y {minutos} minutos para el evento")
else:
print("El evento ya ha pasado")
Consideraciones importantes
-
Los objetos
date
,time
ydatetime
son inmutables, lo que significa que no podemos modificar sus valores después de crearlos. Para realizar cambios, debemos crear nuevos objetos. -
Por defecto, estos objetos no tienen información de zona horaria. Para trabajar con zonas horarias, podemos usar el parámetro
tzinfo
o el módulozoneinfo
(disponible desde Python 3.9) opytz
(para versiones anteriores). -
Para realizar operaciones aritméticas con fechas y horas (como sumar días o restar horas), necesitaremos la clase
timedelta
, que veremos en la siguiente sección.
Los objetos date
, time
y datetime
proporcionan la base para el manejo de fechas y horas en Python, permitiéndonos representar momentos específicos en el tiempo con precisión y claridad. En las siguientes secciones, exploraremos cómo realizar operaciones con estos objetos y cómo formatearlos para diferentes necesidades.
¿Te está gustando esta lección?
Inicia sesión para no perder tu progreso y accede a miles de tutoriales, ejercicios prácticos y nuestro asistente de IA.
Más de 25.000 desarrolladores ya confían en CertiDevs
Operaciones con fechas y horas
Trabajar con fechas y horas en Python va más allá de simplemente crear y mostrar estos valores. El módulo datetime
proporciona herramientas potentes para realizar cálculos y manipulaciones que son esenciales en aplicaciones del mundo real. En esta sección exploraremos cómo realizar operaciones aritméticas con fechas y horas, comparaciones, y otras manipulaciones útiles.
La clase timedelta
La clase timedelta
representa una duración o diferencia entre dos fechas u horas. Es fundamental para realizar operaciones aritméticas con objetos de fecha y hora.
from datetime import timedelta
# Crear un timedelta (días, segundos, microsegundos, milisegundos, minutos, horas, semanas)
un_dia = timedelta(days=1)
una_semana = timedelta(weeks=1) # Equivalente a 7 días
tres_horas = timedelta(hours=3)
dos_horas_y_media = timedelta(hours=2, minutes=30)
print(un_dia) # 1 day, 0:00:00
print(una_semana) # 7 days, 0:00:00
print(tres_horas) # 3:00:00
print(dos_horas_y_media) # 2:30:00
Suma y resta de fechas
Podemos sumar o restar objetos timedelta
a objetos date
o datetime
para obtener nuevas fechas:
from datetime import date, datetime, timedelta
# Sumar días a una fecha
hoy = date.today()
manana = hoy + timedelta(days=1)
ayer = hoy - timedelta(days=1)
proxima_semana = hoy + timedelta(weeks=1)
print(f"Hoy: {hoy}")
print(f"Mañana: {manana}")
print(f"Ayer: {ayer}")
print(f"Próxima semana: {proxima_semana}")
# Sumar horas a un datetime
ahora = datetime.now()
tres_horas_despues = ahora + timedelta(hours=3)
dos_horas_antes = ahora - timedelta(hours=2)
print(f"Ahora: {ahora}")
print(f"Tres horas después: {tres_horas_despues}")
print(f"Dos horas antes: {dos_horas_antes}")
Diferencia entre fechas
Podemos restar dos objetos date
o datetime
para obtener un timedelta
que representa la diferencia entre ellos:
from datetime import date, datetime
# Diferencia entre fechas
fecha_inicio = date(2023, 1, 1)
fecha_fin = date(2023, 12, 31)
duracion = fecha_fin - fecha_inicio
print(f"Días entre el 1 de enero y el 31 de diciembre: {duracion.days}") # 364
# Diferencia entre datetimes
inicio_evento = datetime(2023, 10, 15, 10, 0)
fin_evento = datetime(2023, 10, 15, 16, 30)
duracion_evento = fin_evento - inicio_evento
# Convertir la duración a horas y minutos
horas = duracion_evento.seconds // 3600
minutos = (duracion_evento.seconds % 3600) // 60
print(f"El evento duró {horas} horas y {minutos} minutos") # 6 horas y 30 minutos
Extracción de componentes de timedelta
Podemos extraer diferentes componentes de un objeto timedelta
:
from datetime import timedelta
# Crear un timedelta complejo
t = timedelta(days=2, hours=5, minutes=30, seconds=15)
# Extraer componentes
print(f"Días totales: {t.days}") # 2
print(f"Segundos totales (sin contar días): {t.seconds}") # 19815 (5h 30m 15s en segundos)
print(f"Microsegundos: {t.microseconds}") # 0
print(f"Segundos totales (incluyendo días): {t.total_seconds()}") # 192615.0
Operaciones con timedelta
Los objetos timedelta
también pueden combinarse entre sí:
from datetime import timedelta
# Sumar timedeltas
t1 = timedelta(hours=5)
t2 = timedelta(hours=3, minutes=30)
suma = t1 + t2
print(f"Suma: {suma}") # 8:30:00
# Restar timedeltas
diferencia = t1 - t2
print(f"Diferencia: {diferencia}") # 1:30:00
# Multiplicar por un número
doble = t1 * 2
print(f"Doble: {doble}") # 10:00:00
# Dividir por un número
mitad = t1 / 2
print(f"Mitad: {mitad}") # 2:30:00
Comparación de fechas y horas
Los objetos date
, time
y datetime
pueden compararse entre sí utilizando los operadores de comparación estándar:
from datetime import date, time, datetime
# Comparar fechas
fecha1 = date(2023, 5, 10)
fecha2 = date(2023, 5, 15)
print(fecha1 < fecha2) # True
print(fecha1 == fecha2) # False
print(fecha1 <= fecha2) # True
# Comparar horas
hora1 = time(14, 30)
hora2 = time(16, 45)
print(hora1 < hora2) # True
print(hora1 > hora2) # False
# Comparar datetimes
dt1 = datetime(2023, 5, 10, 14, 30)
dt2 = datetime(2023, 5, 10, 16, 45)
dt3 = datetime(2023, 5, 15, 9, 0)
print(dt1 < dt2) # True (mismo día, hora diferente)
print(dt1 < dt3) # True (día diferente)
Reemplazar componentes de fecha y hora
Los métodos replace()
permiten crear nuevos objetos con componentes específicos modificados:
from datetime import date, time, datetime
# Reemplazar componentes de una fecha
fecha = date(2023, 10, 15)
nueva_fecha = fecha.replace(year=2024, month=5)
print(f"Fecha original: {fecha}") # 2023-10-15
print(f"Fecha modificada: {nueva_fecha}") # 2024-05-15
# Reemplazar componentes de una hora
hora = time(14, 30, 45)
nueva_hora = hora.replace(hour=16, second=0)
print(f"Hora original: {hora}") # 14:30:45
print(f"Hora modificada: {nueva_hora}") # 16:30:00
# Reemplazar componentes de un datetime
dt = datetime(2023, 10, 15, 14, 30, 45)
nuevo_dt = dt.replace(year=2024, hour=16, minute=0)
print(f"Datetime original: {dt}") # 2023-10-15 14:30:45
print(f"Datetime modificado: {nuevo_dt}") # 2024-10-15 16:00:45
Casos de uso prácticos
Cálculo de plazos y vencimientos
from datetime import date, timedelta
def calcular_vencimiento(fecha_inicio, dias_plazo):
"""Calcula la fecha de vencimiento dado un plazo en días."""
return fecha_inicio + timedelta(days=dias_plazo)
# Ejemplo: Calcular vencimiento de una factura
fecha_emision = date(2023, 10, 15)
plazo_pago = 30 # días
fecha_vencimiento = calcular_vencimiento(fecha_emision, plazo_pago)
print(f"Fecha de emisión: {fecha_emision}")
print(f"Fecha de vencimiento: {fecha_vencimiento}")
# Verificar si una factura está vencida
hoy = date.today()
if hoy > fecha_vencimiento:
dias_retraso = (hoy - fecha_vencimiento).days
print(f"La factura está vencida por {dias_retraso} días")
else:
dias_restantes = (fecha_vencimiento - hoy).days
print(f"Quedan {dias_restantes} días para el vencimiento")
Cálculo de días laborables
from datetime import date, timedelta
def dias_laborables_entre(inicio, fin):
"""Calcula los días laborables (lunes a viernes) entre dos fechas."""
dias_laborables = 0
fecha_actual = inicio
while fecha_actual <= fin:
# weekday() devuelve 0-4 para lunes-viernes, 5-6 para sábado-domingo
if fecha_actual.weekday() < 5:
dias_laborables += 1
fecha_actual += timedelta(days=1)
return dias_laborables
# Ejemplo: Calcular días laborables en un mes
inicio_mes = date(2023, 10, 1)
fin_mes = date(2023, 10, 31)
dias = dias_laborables_entre(inicio_mes, fin_mes)
print(f"Días laborables en octubre 2023: {dias}")
Cálculo de edad preciso
from datetime import date
def calcular_edad_exacta(fecha_nacimiento):
"""Calcula la edad exacta en años, meses y días."""
hoy = date.today()
# Calcular años
años = hoy.year - fecha_nacimiento.year
# Ajustar si aún no ha llegado el mes/día de cumpleaños
if (hoy.month, hoy.day) < (fecha_nacimiento.month, fecha_nacimiento.day):
años -= 1
# Calcular la fecha del último cumpleaños
ultimo_cumpleaños = date(hoy.year, fecha_nacimiento.month, fecha_nacimiento.day)
if ultimo_cumpleaños > hoy:
ultimo_cumpleaños = date(hoy.year - 1, fecha_nacimiento.month, fecha_nacimiento.day)
# Calcular meses y días desde el último cumpleaños
meses = hoy.month - ultimo_cumpleaños.month
if hoy.day < ultimo_cumpleaños.day:
meses -= 1
# Ajustar meses si son negativos
if meses < 0:
meses += 12
# Calcular días
if hoy.day >= ultimo_cumpleaños.day:
dias = hoy.day - ultimo_cumpleaños.day
else:
# Retroceder al mes anterior y sumar los días
mes_anterior = hoy.replace(day=1) - timedelta(days=1)
dias = (hoy.day + mes_anterior.day) - ultimo_cumpleaños.day
return años, meses, dias
# Ejemplo de uso
fecha_nacimiento = date(1990, 5, 15)
años, meses, dias = calcular_edad_exacta(fecha_nacimiento)
print(f"Edad: {años} años, {meses} meses y {dias} días")
Cronómetro simple
from datetime import datetime
import time
def cronometrar_operacion(funcion, *args, **kwargs):
"""Mide el tiempo que tarda en ejecutarse una función."""
inicio = datetime.now()
resultado = funcion(*args, **kwargs)
fin = datetime.now()
tiempo_total = fin - inicio
print(f"La operación tardó {tiempo_total.total_seconds():.6f} segundos")
return resultado
# Ejemplo: Cronometrar una operación costosa
def operacion_costosa(n):
"""Una función que tarda tiempo en ejecutarse."""
time.sleep(1) # Simula una operación que tarda 1 segundo
return sum(i**2 for i in range(n))
# Usar el cronómetro
resultado = cronometrar_operacion(operacion_costosa, 1000000)
print(f"Resultado: {resultado}")
Consideraciones importantes
-
Las operaciones con
timedelta
son precisas, pero ten en cuenta que no manejan automáticamente ajustes por horario de verano o cambios de zona horaria. -
Para cálculos más complejos que involucren días laborables, feriados o calendarios específicos, considera usar bibliotecas especializadas como
workalendar
oholidays
. -
Al trabajar con fechas históricas muy antiguas, ten en cuenta que el calendario gregoriano (el que usa Python) no se adoptó universalmente al mismo tiempo. Para fechas anteriores a 1582, podrías necesitar ajustes adicionales.
-
Las operaciones aritméticas con
date
solo funcionan contimedelta
, no puedes sumar directamente dos objetosdate
(pero sí puedes restarlos para obtener untimedelta
). -
Cuando trabajes con duraciones muy largas, recuerda que
timedelta
tiene límites: puede representar hasta aproximadamente 290 millones de años en cualquier dirección.
Las operaciones con fechas y horas son fundamentales en muchas aplicaciones prácticas, desde sistemas de reservas hasta análisis de datos temporales. Dominar estas operaciones te permitirá resolver eficientemente problemas relacionados con el tiempo en tus proyectos de Python.
Formatos y representaciones
Trabajar con fechas y horas en Python no solo implica manipular estos valores internamente, sino también presentarlos de manera legible y adecuada para diferentes contextos. El módulo datetime
ofrece diversas formas de convertir objetos de fecha y hora en cadenas de texto con formatos específicos, así como interpretar cadenas de texto para convertirlas en objetos datetime
.
Métodos de formateo básicos
Los objetos date
, time
y datetime
incluyen métodos integrados para obtener representaciones en cadena:
from datetime import date, time, datetime
# Crear objetos de ejemplo
fecha = date(2023, 10, 15)
hora = time(14, 30, 45)
fecha_hora = datetime(2023, 10, 15, 14, 30, 45)
# Representaciones de cadena básicas
print(str(fecha)) # '2023-10-15'
print(str(hora)) # '14:30:45'
print(str(fecha_hora)) # '2023-10-15 14:30:45'
# Representación ISO 8601
print(fecha.isoformat()) # '2023-10-15'
print(hora.isoformat()) # '14:30:45'
print(fecha_hora.isoformat()) # '2023-10-15T14:30:45'
El método isoformat()
es especialmente útil cuando necesitamos una representación estándar internacional que sea fácilmente interpretable por diferentes sistemas.
Método strftime() para formateo personalizado
El método strftime()
(string format time) permite crear representaciones personalizadas utilizando códigos de formato:
from datetime import datetime
ahora = datetime(2023, 10, 15, 14, 30, 45)
# Formato español (día/mes/año)
print(ahora.strftime("%d/%m/%Y")) # '15/10/2023'
# Formato con nombre del mes
print(ahora.strftime("%d de %B de %Y")) # '15 de October de 2023'
# Formato con día de la semana
print(ahora.strftime("%A, %d de %B de %Y")) # 'Sunday, 15 de October de 2023'
# Formato de hora (12 horas)
print(ahora.strftime("%I:%M %p")) # '02:30 PM'
# Formato de hora (24 horas)
print(ahora.strftime("%H:%M")) # '14:30'
# Formato completo personalizado
print(ahora.strftime("%d/%m/%Y %H:%M:%S")) # '15/10/2023 14:30:45'
Códigos de formato más utilizados
Estos son los códigos de formato más comunes para usar con strftime()
:
-
Año:
-
%Y
- Año con 4 dígitos (ej. 2023) -
%y
- Año con 2 dígitos (ej. 23) -
Mes:
-
%m
- Mes como número con ceros iniciales (01-12) -
%B
- Nombre completo del mes (ej. October) -
%b
- Nombre abreviado del mes (ej. Oct) -
Día:
-
%d
- Día del mes con ceros iniciales (01-31) -
%j
- Día del año (001-366) -
%A
- Nombre completo del día de la semana (ej. Sunday) -
%a
- Nombre abreviado del día de la semana (ej. Sun) -
Hora:
-
%H
- Hora en formato 24 horas con ceros iniciales (00-23) -
%I
- Hora en formato 12 horas con ceros iniciales (01-12) -
%p
- AM/PM -
%M
- Minutos con ceros iniciales (00-59) -
%S
- Segundos con ceros iniciales (00-59) -
%f
- Microsegundos (000000-999999) -
Otros:
-
%Z
- Nombre de la zona horaria -
%z
- Desplazamiento UTC (+HHMM o -HHMM) -
%%
- Carácter literal '%'
Localización de fechas en español
Por defecto, los nombres de meses y días aparecen en inglés. Para mostrarlos en español, podemos usar el módulo locale
:
import locale
from datetime import datetime
# Configurar locale a español de España
locale.setlocale(locale.LC_TIME, 'es_ES.UTF-8') # En Windows podría ser 'Spanish_Spain'
ahora = datetime(2023, 10, 15, 14, 30)
# Ahora los nombres aparecerán en español
print(ahora.strftime("%A, %d de %B de %Y")) # 'domingo, 15 de octubre de 2023'
print(ahora.strftime("%a, %d/%m/%Y")) # 'dom, 15/10/2023'
Si el código anterior genera un error, es posible que el locale no esté instalado en el sistema. Una alternativa es crear diccionarios de traducción:
from datetime import datetime
# Diccionarios de traducción
DIAS = {
"Monday": "lunes",
"Tuesday": "martes",
"Wednesday": "miércoles",
"Thursday": "jueves",
"Friday": "viernes",
"Saturday": "sábado",
"Sunday": "domingo"
}
MESES = {
"January": "enero",
"February": "febrero",
"March": "marzo",
"April": "abril",
"May": "mayo",
"June": "junio",
"July": "julio",
"August": "agosto",
"September": "septiembre",
"October": "octubre",
"November": "noviembre",
"December": "diciembre"
}
def fecha_en_español(fecha):
"""Formatea una fecha en español."""
formato_ingles = fecha.strftime("%A, %d de %B de %Y")
# Traducir día y mes
for ingles, español in DIAS.items():
formato_ingles = formato_ingles.replace(ingles, español)
for ingles, español in MESES.items():
formato_ingles = formato_ingles.replace(ingles, español)
return formato_ingles
# Ejemplo de uso
ahora = datetime(2023, 10, 15, 14, 30)
print(fecha_en_español(ahora)) # 'domingo, 15 de octubre de 2023'
Método strptime() para análisis de cadenas
El método strptime()
(string parse time) realiza la operación inversa a strftime()
: convierte una cadena en un objeto datetime
según un formato especificado:
from datetime import datetime
# Analizar una cadena con formato específico
cadena_fecha = "15/10/2023 14:30:45"
formato = "%d/%m/%Y %H:%M:%S"
fecha_objeto = datetime.strptime(cadena_fecha, formato)
print(fecha_objeto) # 2023-10-15 14:30:45
print(type(fecha_objeto)) # <class 'datetime.datetime'>
# Otros ejemplos
fecha_texto = "15 de octubre de 2023"
fecha_objeto = datetime.strptime(fecha_texto, "%d de %B de %Y")
print(fecha_objeto) # 2023-10-15 00:00:00
hora_texto = "2:30 PM"
hora_objeto = datetime.strptime(hora_texto, "%I:%M %p")
print(hora_objeto.time()) # 14:30:00
Formatos para casos de uso específicos
Formato para bases de datos SQL
from datetime import datetime
ahora = datetime.now()
# Formato ISO para bases de datos SQL
formato_sql = ahora.strftime("%Y-%m-%d %H:%M:%S")
print(f"Formato SQL: {formato_sql}") # Ej: '2023-10-15 14:30:45'
Formato para nombres de archivo
from datetime import datetime
ahora = datetime.now()
# Formato seguro para nombres de archivo (sin caracteres especiales)
formato_archivo = ahora.strftime("%Y%m%d_%H%M%S")
nombre_archivo = f"backup_{formato_archivo}.zip"
print(nombre_archivo) # Ej: 'backup_20231015_143045.zip'
Formato para mostrar tiempo relativo
from datetime import datetime, timedelta
def tiempo_relativo(fecha):
"""Devuelve una representación amigable del tiempo relativo."""
ahora = datetime.now()
diferencia = ahora - fecha
segundos = diferencia.total_seconds()
if segundos < 60:
return "hace unos segundos"
elif segundos < 3600:
minutos = int(segundos // 60)
return f"hace {minutos} {'minuto' if minutos == 1 else 'minutos'}"
elif segundos < 86400: # 24 horas
horas = int(segundos // 3600)
return f"hace {horas} {'hora' if horas == 1 else 'horas'}"
elif segundos < 604800: # 7 días
dias = int(segundos // 86400)
return f"hace {dias} {'día' if dias == 1 else 'días'}"
else:
return fecha.strftime("%d/%m/%Y")
# Ejemplos
ahora = datetime.now()
print(tiempo_relativo(ahora)) # 'hace unos segundos'
print(tiempo_relativo(ahora - timedelta(minutes=5))) # 'hace 5 minutos'
print(tiempo_relativo(ahora - timedelta(hours=3))) # 'hace 3 horas'
print(tiempo_relativo(ahora - timedelta(days=2))) # 'hace 2 días'
print(tiempo_relativo(ahora - timedelta(days=10))) # '05/10/2023' (ejemplo)
Formato ISO 8601 y RFC 3339
Estos formatos son estándares internacionales ampliamente utilizados para intercambio de datos:
from datetime import datetime, timezone
# Crear un datetime con zona horaria UTC
ahora_utc = datetime.now(timezone.utc)
# Formato ISO 8601 completo
iso_formato = ahora_utc.isoformat()
print(f"ISO 8601: {iso_formato}") # Ej: '2023-10-15T14:30:45.123456+00:00'
# Formato RFC 3339 (variante de ISO 8601 usada en APIs)
rfc3339 = ahora_utc.strftime("%Y-%m-%dT%H:%M:%S%z")
# Insertar el ":" en la zona horaria para cumplir con RFC 3339
rfc3339 = f"{rfc3339[:-2]}:{rfc3339[-2:]}"
print(f"RFC 3339: {rfc3339}") # Ej: '2023-10-15T14:30:45+00:00'
Trabajando con timestamps (marcas de tiempo Unix)
Las marcas de tiempo Unix representan el número de segundos desde el 1 de enero de 1970:
from datetime import datetime
import time
# Obtener timestamp actual
timestamp_actual = time.time()
print(f"Timestamp actual: {timestamp_actual}") # Ej: 1697380245.123456
# Convertir timestamp a datetime
fecha_desde_timestamp = datetime.fromtimestamp(timestamp_actual)
print(f"Fecha desde timestamp: {fecha_desde_timestamp}")
# Convertir datetime a timestamp
ahora = datetime.now()
timestamp = ahora.timestamp()
print(f"Timestamp desde datetime: {timestamp}")
Aplicaciones prácticas
Generación de informes con fechas formateadas
from datetime import datetime
def generar_encabezado_informe():
"""Genera el encabezado de un informe con la fecha actual."""
ahora = datetime.now()
# Formato de fecha para el título
fecha_titulo = ahora.strftime("%d de %B de %Y")
# Formato para el nombre de archivo
nombre_archivo = f"informe_{ahora.strftime('%Y%m%d')}.pdf"
# Formato para el pie de página
pie_pagina = f"Generado el {ahora.strftime('%d/%m/%Y')} a las {ahora.strftime('%H:%M')}"
return {
"titulo": f"Informe mensual - {fecha_titulo}",
"archivo": nombre_archivo,
"pie_pagina": pie_pagina
}
# Ejemplo de uso
encabezado = generar_encabezado_informe()
print(f"Título: {encabezado['titulo']}")
print(f"Archivo: {encabezado['archivo']}")
print(f"Pie de página: {encabezado['pie_pagina']}")
Validación de fechas en formularios
from datetime import datetime
def validar_fecha(texto_fecha, formato="%d/%m/%Y"):
"""
Valida si una cadena representa una fecha válida en el formato especificado.
Devuelve el objeto datetime si es válida, None en caso contrario.
"""
try:
fecha = datetime.strptime(texto_fecha, formato)
return fecha
except ValueError:
return None
# Ejemplos de uso
fechas_a_validar = [
"15/10/2023", # Válida
"31/02/2023", # Inválida (febrero no tiene 31 días)
"25/12/2023", # Válida
"abc" # Formato inválido
]
for texto in fechas_a_validar:
resultado = validar_fecha(texto)
if resultado:
print(f"'{texto}' es una fecha válida: {resultado}")
else:
print(f"'{texto}' NO es una fecha válida")
Calendario simple de eventos
from datetime import datetime, timedelta
class Evento:
def __init__(self, nombre, fecha_str, formato="%d/%m/%Y %H:%M"):
self.nombre = nombre
self.fecha = datetime.strptime(fecha_str, formato)
def __str__(self):
return f"{self.nombre} - {self.fecha.strftime('%d/%m/%Y %H:%M')}"
def tiempo_restante(self):
ahora = datetime.now()
if self.fecha < ahora:
return "Ya ha pasado"
diferencia = self.fecha - ahora
dias = diferencia.days
horas = diferencia.seconds // 3600
minutos = (diferencia.seconds % 3600) // 60
if dias > 0:
return f"Faltan {dias} días y {horas} horas"
elif horas > 0:
return f"Faltan {horas} horas y {minutos} minutos"
else:
return f"Faltan {minutos} minutos"
# Ejemplo de uso
eventos = [
Evento("Reunión de equipo", "20/10/2023 10:00"),
Evento("Entrega de proyecto", "30/10/2023 18:00"),
Evento("Cumpleaños de Ana", "15/11/2023 00:00")
]
print("Calendario de eventos:")
for evento in eventos:
print(f"- {evento}: {evento.tiempo_restante()}")
Consideraciones importantes
-
Internacionalización: Al trabajar con fechas en diferentes idiomas, asegúrate de configurar correctamente el
locale
o utilizar diccionarios de traducción. -
Ambigüedad de formatos: Ten cuidado con formatos ambiguos como "01/02/2023", que podría interpretarse como 1 de febrero o 2 de enero dependiendo del país. Es recomendable usar formatos explícitos o con nombres de mes.
-
Zonas horarias: Los ejemplos anteriores no consideran zonas horarias. Para aplicaciones que operan en múltiples zonas, considera usar el módulo
zoneinfo
(Python 3.9+) o la bibliotecapytz
. -
Rendimiento: Si necesitas formatear o analizar grandes cantidades de fechas, considera utilizar bibliotecas optimizadas como
pandas
que ofrecen mejor rendimiento. -
Consistencia: Mantén un formato consistente en toda tu aplicación para evitar confusiones. Documenta los formatos utilizados, especialmente si intercambias datos con otros sistemas.
El formateo y análisis de fechas y horas es una tarea común en muchas aplicaciones. Dominar estas técnicas te permitirá presentar información temporal de manera clara y procesable, mejorando la experiencia del usuario y facilitando la integración con otros sistemas.
Aprendizajes de esta lección
- Comprender las clases principales del módulo datetime: date, time y datetime.
- Aprender a crear, acceder y manipular objetos de fecha y hora.
- Realizar operaciones aritméticas con fechas y horas usando timedelta.
- Formatear y analizar fechas y horas con métodos como strftime y strptime.
- Aplicar casos prácticos como cálculo de edad, plazos, y manejo de eventos temporales.
Completa Python y certifícate
Únete a nuestra plataforma y accede a miles de tutoriales, ejercicios prácticos, proyectos reales y nuestro asistente de IA personalizado para acelerar tu aprendizaje.
Asistente IA
Resuelve dudas al instante
Ejercicios
Practica con proyectos reales
Certificados
Valida tus conocimientos
Más de 25.000 desarrolladores ya se han certificado con CertiDevs