Módulo time

Intermedio
Python
Python
Actualizado: 06/05/2025

¡Desbloquea el curso de Python completo!

IA
Ejercicios
Certificado
Entrar

Mira la lección en vídeo

Accede al vídeo completo de esta lección y a más contenido exclusivo con el Plan Plus.

Desbloquear Plan Plus

Medición de tiempo

El módulo time de Python proporciona funciones para trabajar con tiempo a un nivel más cercano al sistema operativo, siendo especialmente útil para medir el rendimiento de código y crear temporizadores precisos. A diferencia del módulo datetime (que se enfoca en fechas y horas en formato calendario), time está orientado a operaciones de temporización de alta precisión.

La medición de tiempo es una de las aplicaciones más comunes del módulo time, permitiéndonos evaluar cuánto tarda en ejecutarse una porción de código. Esto resulta fundamental para optimización de rendimiento y análisis de algoritmos.

Funciones principales para medición de tiempo

Python ofrece varias funciones para medir tiempo con diferentes niveles de precisión:

  • time.time(): Devuelve el tiempo en segundos desde la "época" (1 de enero de 1970) como un número de punto flotante.
  • time.perf_counter(): Proporciona el valor de un contador de rendimiento de alta resolución, ideal para medir tiempos cortos.
  • time.process_time(): Devuelve la suma del tiempo de CPU del proceso actual y sus subprocesos.
  • time.monotonic(): Retorna un valor que siempre aumenta, no afectado por ajustes del reloj del sistema.

Veamos cada una con más detalle:

Usando time.time()

Esta es la función más básica para medir tiempo, pero puede ser menos precisa para intervalos muy cortos:

import time

inicio = time.time()
# Código a medir
for i in range(1000000):
    pass
fin = time.time()

tiempo_transcurrido = fin - inicio
print(f"Tiempo de ejecución: {tiempo_transcurrido:.6f} segundos")

Usando time.perf_counter()

Esta función proporciona la mayor precisión para medir el rendimiento del código y es la recomendada para benchmarking:

import time

inicio = time.perf_counter()
# Código a medir
resultado = sum(range(10000000))
fin = time.perf_counter()

print(f"La operación tardó {fin - inicio:.6f} segundos")
print(f"Resultado: {resultado}")

Usando time.process_time()

A diferencia de las anteriores, esta función solo mide el tiempo de CPU utilizado por el proceso, excluyendo el tiempo que el sistema operativo dedica a otras tareas:

import time

inicio = time.process_time()
# Operación intensiva de CPU
[i**2 for i in range(10000000)]
fin = time.process_time()

print(f"Tiempo de CPU utilizado: {fin - inicio:.6f} segundos")

Usando time.monotonic()

Esta función es útil cuando necesitamos un tiempo que siempre avanza independientemente de los ajustes del reloj del sistema:

import time

inicio = time.monotonic()
# Código a medir
time.sleep(1.5)  # Simulamos una operación
fin = time.monotonic()

print(f"Tiempo transcurrido: {fin - inicio:.6f} segundos")

Comparación de métodos de medición

Cada método tiene sus propias características y casos de uso:

| Función | Precisión | Afectado por ajustes del reloj | Mide solo CPU | Uso recomendado | |---------|-----------|--------------------------------|---------------|-----------------| | time.time() | Media | Sí | No | Intervalos largos, no críticos | | time.perf_counter() | Muy alta | No | No | Benchmarking, mediciones precisas | | time.process_time() | Alta | No | Sí | Análisis de rendimiento de CPU | | time.monotonic() | Alta | No | No | Mediciones que no deben retroceder |

Creando un decorador para medir tiempo

Una aplicación práctica es crear un decorador que mida automáticamente el tiempo de ejecución de cualquier función:

import time
from functools import wraps

def medir_tiempo(funcion):
    @wraps(funcion)
    def wrapper(*args, **kwargs):
        inicio = time.perf_counter()
        resultado = funcion(*args, **kwargs)
        fin = time.perf_counter()
        print(f"Función {funcion.__name__} ejecutada en {fin - inicio:.6f} segundos")
        return resultado
    return wrapper

# Ejemplo de uso
@medir_tiempo
def algoritmo_ordenamiento(n):
    # Simulamos un algoritmo de ordenamiento
    lista = list(range(n))
    lista.sort(reverse=True)
    lista.sort()
    return len(lista)

# Probamos con diferentes tamaños
algoritmo_ordenamiento(10000)
algoritmo_ordenamiento(100000)
algoritmo_ordenamiento(1000000)

Midiendo bloques de código con contexto

También podemos crear un administrador de contexto para medir bloques específicos de código:

import time
from contextlib import contextmanager

@contextmanager
def temporizador(nombre="Operación"):
    inicio = time.perf_counter()
    try:
        yield
    finally:
        fin = time.perf_counter()
        print(f"{nombre} completada en {fin - inicio:.6f} segundos")

# Ejemplo de uso
with temporizador("Cálculo de primos"):
    # Encontrar números primos hasta 100000
    primos = []
    for num in range(2, 100000):
        es_primo = all(num % i != 0 for i in range(2, int(num**0.5) + 1))
        if es_primo:
            primos.append(num)
    print(f"Se encontraron {len(primos)} números primos")

Comparando rendimiento de algoritmos

Una aplicación común de la medición de tiempo es comparar diferentes implementaciones de un mismo algoritmo:

import time

def fibonacci_recursivo(n):
    if n <= 1:
        return n
    return fibonacci_recursivo(n-1) + fibonacci_recursivo(n-2)

def fibonacci_iterativo(n):
    a, b = 0, 1
    for _ in range(n):
        a, b = b, a + b
    return a

# Comparamos rendimiento
n = 30

inicio = time.perf_counter()
resultado1 = fibonacci_recursivo(n)
tiempo1 = time.perf_counter() - inicio

inicio = time.perf_counter()
resultado2 = fibonacci_iterativo(n)
tiempo2 = time.perf_counter() - inicio

print(f"Fibonacci recursivo: {tiempo1:.6f} segundos")
print(f"Fibonacci iterativo: {tiempo2:.6f} segundos")
print(f"La versión iterativa es {tiempo1/tiempo2:.1f} veces más rápida")

Consideraciones importantes

Al medir tiempos de ejecución, ten en cuenta estos factores:

  • Variabilidad: Las mediciones pueden variar según la carga del sistema. Para resultados más confiables, realiza múltiples mediciones.
  • Precisión: Para operaciones muy rápidas (microsegundos), considera ejecutar la operación miles de veces y dividir el tiempo total.
  • Overhead: La propia medición introduce un pequeño overhead que puede ser significativo para operaciones muy rápidas.
  • Optimizaciones del intérprete: El intérprete de Python puede optimizar código en ejecuciones repetidas, afectando las mediciones.
import time
import statistics

def medir_operacion_rapida():
    tiempos = []
    for _ in range(100):
        inicio = time.perf_counter()
        # Operación muy rápida
        sum(range(1000))
        fin = time.perf_counter()
        tiempos.append(fin - inicio)
    
    return {
        "min": min(tiempos),
        "max": max(tiempos),
        "promedio": statistics.mean(tiempos),
        "mediana": statistics.median(tiempos)
    }

estadisticas = medir_operacion_rapida()
print(f"Estadísticas de tiempo (segundos):")
for clave, valor in estadisticas.items():
    print(f"  {clave}: {valor:.9f}")

La medición precisa del tiempo de ejecución es una herramienta fundamental para la optimización de código y el análisis de rendimiento, permitiéndonos identificar cuellos de botella y validar mejoras en nuestros algoritmos.

Pausas y esperas

Guarda tu progreso

Inicia sesión para no perder tu progreso y accede a miles de tutoriales, ejercicios prácticos y nuestro asistente de IA.

Progreso guardado
Asistente IA
Ejercicios
Iniciar sesión gratis

Más de 25.000 desarrolladores ya confían en CertiDevs

El módulo time de Python no solo permite medir el tiempo de ejecución, sino que también ofrece funciones para introducir pausas controladas en nuestros programas. Estas pausas son fundamentales para muchas aplicaciones prácticas como la limitación de tasas de solicitudes, simulaciones, animaciones o simplemente para dar tiempo a que otros procesos completen sus tareas.

La capacidad de pausar la ejecución de un programa de manera precisa es una herramienta esencial en el desarrollo de software, especialmente en aplicaciones que interactúan con recursos externos o que necesitan sincronización temporal.

Función sleep() básica

La función principal para introducir pausas es time.sleep(), que suspende la ejecución del programa durante un número específico de segundos:

import time

print("Inicio del programa")
time.sleep(2)  # Pausa la ejecución durante 2 segundos
print("Mensaje después de 2 segundos")

Esta función acepta valores de punto flotante, lo que permite pausas de fracciones de segundo:

import time

print("Contando con pausas de medio segundo:")
for i in range(5):
    print(i + 1)
    time.sleep(0.5)  # Pausa de 500 milisegundos
print("¡Conteo finalizado!")

Creando temporizadores y contadores regresivos

Podemos combinar sleep() con otras funciones para crear temporizadores simples:

import time

def temporizador(segundos):
    """Temporizador simple que muestra una cuenta regresiva."""
    print(f"Temporizador iniciado: {segundos} segundos")
    
    for restante in range(segundos, 0, -1):
        print(f"Tiempo restante: {restante} segundos")
        time.sleep(1)
    
    print("¡Tiempo terminado!")

# Ejemplo de uso
temporizador(5)

Limitación de tasas (Rate limiting)

Una aplicación práctica común es la limitación de tasas para evitar sobrecargar servicios externos:

import time
import random

def obtener_datos_api(id_recurso):
    # Simulación de llamada a API
    print(f"Obteniendo datos para recurso {id_recurso}...")
    time.sleep(0.3)  # Simulamos tiempo de respuesta
    return {"id": id_recurso, "valor": random.randint(1, 100)}

def procesar_recursos_con_limite(lista_ids, solicitudes_por_segundo=2):
    """Procesa recursos respetando un límite de solicitudes por segundo."""
    intervalo = 1.0 / solicitudes_por_segundo
    resultados = []
    
    for id_recurso in lista_ids:
        inicio = time.perf_counter()
        
        # Realizar la solicitud
        datos = obtener_datos_api(id_recurso)
        resultados.append(datos)
        
        # Calcular tiempo a esperar para mantener la tasa deseada
        tiempo_proceso = time.perf_counter() - inicio
        tiempo_espera = max(0, intervalo - tiempo_proceso)
        
        if tiempo_espera > 0:
            time.sleep(tiempo_espera)
    
    return resultados

# Ejemplo: procesar 10 recursos a 2 solicitudes por segundo
ids_recursos = list(range(1, 11))
resultados = procesar_recursos_con_limite(ids_recursos)
print(f"Procesados {len(resultados)} recursos")

Implementando retroceso exponencial

El retroceso exponencial es una técnica que incrementa progresivamente el tiempo de espera entre reintentos, útil para manejar errores transitorios:

import time
import random

def operacion_con_posible_fallo():
    """Simula una operación que puede fallar aleatoriamente."""
    if random.random() < 0.7:  # 70% de probabilidad de fallo
        raise Exception("Error temporal en la operación")
    return "Operación exitosa"

def ejecutar_con_reintentos(max_intentos=5, retraso_inicial=1):
    """Ejecuta una operación con reintentos y retroceso exponencial."""
    intentos = 0
    retraso = retraso_inicial
    
    while intentos < max_intentos:
        try:
            resultado = operacion_con_posible_fallo()
            print(f"Éxito en el intento {intentos + 1}")
            return resultado
        except Exception as e:
            intentos += 1
            if intentos == max_intentos:
                print(f"Fallaron todos los intentos ({max_intentos})")
                raise
            
            print(f"Intento {intentos} falló: {e}")
            print(f"Esperando {retraso:.2f} segundos antes del siguiente intento...")
            time.sleep(retraso)
            
            # Incremento exponencial del tiempo de espera
            retraso *= 2
            # Añadimos un pequeño factor aleatorio para evitar sincronización
            retraso *= (0.9 + 0.2 * random.random())

# Ejemplo de uso
try:
    resultado = ejecutar_con_reintentos()
    print(f"Resultado final: {resultado}")
except Exception as e:
    print(f"Error final: {e}")

Implementando un throttle para funciones

Podemos crear un decorador que limite la frecuencia con la que se puede llamar a una función:

import time
from functools import wraps

def throttle(intervalo_segundos):
    """
    Decorador que limita la frecuencia de llamadas a una función.
    Si se llama antes del intervalo, espera el tiempo restante.
    """
    def decorador(funcion):
        ultima_llamada = 0
        
        @wraps(funcion)
        def wrapper(*args, **kwargs):
            nonlocal ultima_llamada
            tiempo_actual = time.monotonic()
            tiempo_transcurrido = tiempo_actual - ultima_llamada
            
            # Si no ha pasado suficiente tiempo, esperamos
            if tiempo_transcurrido < intervalo_segundos:
                tiempo_espera = intervalo_segundos - tiempo_transcurrido
                time.sleep(tiempo_espera)
            
            # Actualizamos el tiempo de la última llamada
            ultima_llamada = time.monotonic()
            return funcion(*args, **kwargs)
        
        return wrapper
    
    return decorador

# Ejemplo: función que no puede llamarse más de una vez cada 2 segundos
@throttle(2)
def funcion_costosa(parametro):
    print(f"Ejecutando operación costosa con {parametro}")
    return f"Resultado para {parametro}"

# Probamos llamadas consecutivas
for i in range(3):
    print(f"Llamada {i+1} iniciada en {time.strftime('%H:%M:%S')}")
    resultado = funcion_costosa(f"parámetro {i+1}")
    print(f"Llamada {i+1} completada en {time.strftime('%H:%M:%S')}")

Simulando operaciones asíncronas

Aunque Python tiene soporte para programación asíncrona con asyncio, podemos simular comportamientos asíncronos básicos con time.sleep():

import time
import threading

def tarea_larga(nombre, duracion):
    print(f"Iniciando tarea: {nombre}")
    time.sleep(duracion)  # Simulamos procesamiento
    print(f"Tarea completada: {nombre} (duración: {duracion}s)")
    return f"Resultado de {nombre}"

# Ejecutar tareas en paralelo usando hilos
def ejecutar_tareas_paralelas():
    tareas = [
        ("Tarea A", 3),
        ("Tarea B", 1),
        ("Tarea C", 2),
    ]
    
    hilos = []
    for nombre, duracion in tareas:
        hilo = threading.Thread(target=tarea_larga, args=(nombre, duracion))
        hilos.append(hilo)
        hilo.start()
    
    # Esperar a que todos los hilos terminen
    for hilo in hilos:
        hilo.join()
    
    print("Todas las tareas completadas")

# Ejecutamos las tareas en paralelo
ejecutar_tareas_paralelas()

Consideraciones sobre precisión

Es importante entender que time.sleep() no garantiza una precisión perfecta, especialmente para intervalos muy cortos:

import time
import statistics

def probar_precision_sleep():
    duraciones_reales = []
    duracion_objetivo = 0.01  # 10 milisegundos
    
    for _ in range(20):
        inicio = time.perf_counter()
        time.sleep(duracion_objetivo)
        fin = time.perf_counter()
        duracion_real = fin - inicio
        duraciones_reales.append(duracion_real)
    
    promedio = statistics.mean(duraciones_reales)
    desviacion = statistics.stdev(duraciones_reales)
    
    print(f"Duración objetivo: {duracion_objetivo * 1000:.2f} ms")
    print(f"Duración promedio: {promedio * 1000:.2f} ms")
    print(f"Desviación estándar: {desviacion * 1000:.2f} ms")
    print(f"Mínimo: {min(duraciones_reales) * 1000:.2f} ms")
    print(f"Máximo: {max(duraciones_reales) * 1000:.2f} ms")

probar_precision_sleep()

La precisión de sleep() puede verse afectada por:

  • Resolución del temporizador del sistema operativo
  • Carga del sistema y programación de tareas
  • Prioridad del proceso de Python
  • Virtualización (en entornos virtualizados o contenedores)

Alternativas para casos especiales

En situaciones donde necesitamos mayor precisión o comportamientos específicos:

  • Para esperas ocupadas (sin ceder el control al sistema operativo):
import time

def espera_ocupada(segundos):
    """Realiza una espera ocupada (sin ceder el control al SO)."""
    tiempo_final = time.perf_counter() + segundos
    
    while time.perf_counter() < tiempo_final:
        pass  # Bucle vacío que consume CPU

print("Iniciando espera ocupada de 1 segundo...")
espera_ocupada(1)
print("Espera ocupada finalizada")
  • Para esperas con comprobación periódica:
import time

def esperar_hasta_condicion(condicion_func, timeout=10, intervalo=0.1):
    """Espera hasta que una condición sea verdadera o se agote el tiempo."""
    inicio = time.monotonic()
    
    while time.monotonic() - inicio < timeout:
        if condicion_func():
            return True
        time.sleep(intervalo)
    
    return False

# Ejemplo: esperar a que un valor alcance cierto umbral
valor = 0

def incrementar_valor():
    global valor
    valor += 1
    print(f"Valor actual: {valor}")
    return valor >= 5

# Simulamos un proceso que incrementa el valor cada 0.3 segundos
def proceso_incremento():
    global valor
    while valor < 10:
        time.sleep(0.3)
        valor += 1
        print(f"Proceso: incrementado valor a {valor}")

# Iniciamos el proceso en un hilo
import threading
hilo = threading.Thread(target=proceso_incremento)
hilo.daemon = True
hilo.start()

# Esperamos a que el valor llegue a 5
resultado = esperar_hasta_condicion(
    lambda: valor >= 5,
    timeout=5,
    intervalo=0.2
)

print(f"Condición cumplida: {resultado}, valor final: {valor}")

Las pausas y esperas son herramientas fundamentales en la programación con Python, permitiéndonos controlar el flujo temporal de nuestras aplicaciones, desde simples retardos hasta sofisticados mecanismos de control de tasas y sincronización.

Conversión entre formatos de tiempo

El módulo time de Python proporciona diversas funciones para convertir entre diferentes representaciones de tiempo, permitiéndonos transformar marcas de tiempo (timestamps) en cadenas legibles por humanos y viceversa. Estas conversiones son esenciales cuando necesitamos presentar información temporal al usuario o cuando trabajamos con diferentes sistemas que utilizan distintos formatos de tiempo.

A diferencia del módulo datetime, que se centra en manipulaciones de fechas a alto nivel, time trabaja con representaciones más cercanas al sistema operativo, ofreciendo mayor rendimiento para ciertas operaciones.

Representaciones de tiempo en Python

Python maneja principalmente tres tipos de representaciones temporales a través del módulo time:

  • Epoch time (timestamp): Segundos transcurridos desde el 1 de enero de 1970 (época Unix).
  • Tiempo estructurado: Una tupla de 9 elementos que contiene año, mes, día, hora, minuto, segundo, día de la semana, día del año y bandera de horario de verano.
  • Cadenas de texto formateadas: Representaciones legibles de fechas y horas.

Conversión de timestamp a tiempo estructurado

La función time.localtime() convierte un timestamp en una estructura de tiempo local, mientras que time.gmtime() lo convierte a tiempo UTC:

import time

# Obtener el timestamp actual
timestamp_actual = time.time()
print(f"Timestamp actual: {timestamp_actual}")

# Convertir a tiempo estructurado local
tiempo_local = time.localtime(timestamp_actual)
print(f"Tiempo estructurado local: {tiempo_local}")

# Convertir a tiempo UTC (Greenwich Mean Time)
tiempo_utc = time.gmtime(timestamp_actual)
print(f"Tiempo estructurado UTC: {tiempo_utc}")

El resultado de estas funciones es un objeto struct_time, que contiene los siguientes atributos:

import time

timestamp = time.time()
t = time.localtime(timestamp)

# Accediendo a los componentes individuales
print(f"Año: {t.tm_year}")
print(f"Mes: {t.tm_mon}")
print(f"Día: {t.tm_mday}")
print(f"Hora: {t.tm_hour}")
print(f"Minuto: {t.tm_min}")
print(f"Segundo: {t.tm_sec}")
print(f"Día de la semana: {t.tm_wday}")  # 0 es lunes, 6 es domingo
print(f"Día del año: {t.tm_yday}")       # 1-366
print(f"Horario de verano: {t.tm_isdst}")  # 1 si está en horario de verano

Conversión de tiempo estructurado a timestamp

Para realizar la conversión inversa, utilizamos time.mktime():

import time

# Crear un tiempo estructurado (31 de diciembre de 2023, 23:59:59)
tiempo_struct = time.struct_time((2023, 12, 31, 23, 59, 59, 6, 365, 0))

# Convertir a timestamp
timestamp = time.mktime(tiempo_struct)
print(f"Timestamp: {timestamp}")

# Verificar la conversión
print(f"Fecha convertida: {time.ctime(timestamp)}")

Formateo de tiempo a cadenas de texto

Python ofrece varias funciones para convertir tiempos a cadenas legibles:

Usando time.ctime()

La forma más simple de obtener una representación de texto:

import time

timestamp = time.time()
cadena_tiempo = time.ctime(timestamp)
print(f"Tiempo actual: {cadena_tiempo}")

Usando time.strftime()

Para un control más preciso sobre el formato, utilizamos strftime() (string format time):

import time

ahora = time.localtime()

# Diferentes formatos de fecha y hora
formato_fecha = time.strftime("%d/%m/%Y", ahora)
formato_hora = time.strftime("%H:%M:%S", ahora)
formato_completo = time.strftime("%A, %d de %B de %Y - %H:%M:%S", ahora)

print(f"Fecha: {formato_fecha}")
print(f"Hora: {formato_hora}")
print(f"Formato completo: {formato_completo}")

Los códigos de formato más comunes para strftime() son:

  • %d: Día del mes (01-31)
  • %m: Mes (01-12)
  • %Y: Año con cuatro dígitos
  • %y: Año con dos dígitos
  • %H: Hora en formato 24h (00-23)
  • %I: Hora en formato 12h (01-12)
  • %M: Minutos (00-59)
  • %S: Segundos (00-59)
  • %A: Nombre completo del día de la semana
  • %a: Nombre abreviado del día de la semana
  • %B: Nombre completo del mes
  • %b: Nombre abreviado del mes
  • %p: AM/PM
  • %Z: Zona horaria

Conversión de cadenas de texto a tiempo estructurado

Para convertir una cadena de texto a una estructura de tiempo, usamos time.strptime() (string parse time):

import time

# Cadena de texto que representa una fecha y hora
fecha_texto = "21/09/2023 15:30:45"

# Convertir a tiempo estructurado especificando el formato
tiempo_struct = time.strptime(fecha_texto, "%d/%m/%Y %H:%M:%S")
print(f"Tiempo estructurado: {tiempo_struct}")

# Convertir a timestamp
timestamp = time.mktime(tiempo_struct)
print(f"Timestamp: {timestamp}")

Trabajando con zonas horarias

El módulo time tiene funcionalidades básicas para trabajar con zonas horarias:

import time

# Obtener la zona horaria local
zona_local = time.tzname
print(f"Zona horaria local: {zona_local}")

# Verificar si estamos en horario de verano
es_horario_verano = time.localtime().tm_isdst
print(f"¿Estamos en horario de verano? {'Sí' if es_horario_verano else 'No'}")

# Diferencia en segundos entre hora local y UTC
diferencia_utc = time.timezone
print(f"Diferencia con UTC (segundos): {diferencia_utc}")
print(f"Diferencia con UTC (horas): {diferencia_utc / 3600}")

Aplicaciones prácticas

Convertir timestamps de logs a formato legible

import time

# Simulación de timestamps de un archivo de log
log_timestamps = [1632215460, 1632215520, 1632215580, 1632215640]

print("Registro de eventos:")
for ts in log_timestamps:
    # Convertir a formato legible
    fecha_hora = time.strftime("%d-%m-%Y %H:%M:%S", time.localtime(ts))
    print(f"[{fecha_hora}] Evento registrado")

Calcular diferencias de tiempo entre zonas horarias

import time

def convertir_a_zona_horaria(timestamp, horas_diferencia):
    """Convierte un timestamp a una zona horaria con diferencia en horas."""
    # Convertir a tiempo estructurado UTC
    tiempo_utc = time.gmtime(timestamp)
    
    # Crear una cadena con el tiempo UTC
    tiempo_str = time.strftime("%Y-%m-%d %H:%M:%S", tiempo_utc)
    
    # Parsear de nuevo a tiempo estructurado
    tiempo_struct = time.strptime(tiempo_str, "%Y-%m-%d %H:%M:%S")
    
    # Convertir a timestamp y ajustar por la diferencia horaria
    nuevo_timestamp = time.mktime(tiempo_struct) + (horas_diferencia * 3600)
    
    return nuevo_timestamp

# Timestamp actual
ahora = time.time()

# Mostrar la hora actual en diferentes zonas horarias
print(f"Hora local: {time.strftime('%H:%M:%S', time.localtime(ahora))}")

# Nueva York (UTC-5 o UTC-4 en horario de verano)
ny_time = convertir_a_zona_horaria(ahora, -5)
print(f"Hora en Nueva York: {time.strftime('%H:%M:%S', time.localtime(ny_time))}")

# Tokio (UTC+9)
tokio_time = convertir_a_zona_horaria(ahora, 9)
print(f"Hora en Tokio: {time.strftime('%H:%M:%S', time.localtime(tokio_time))}")

Crear un formateador de fechas personalizado

import time

def formatear_fecha(timestamp, formato="completo", locale="es"):
    """
    Formatea un timestamp en diferentes estilos según el locale.
    
    Formatos disponibles:
    - corto: DD/MM/YYYY
    - medio: DD de Mes, YYYY
    - completo: Día, DD de Mes de YYYY a las HH:MM
    """
    tiempo = time.localtime(timestamp)
    
    # Nombres de días y meses en español
    if locale == "es":
        dias = ["Lunes", "Martes", "Miércoles", "Jueves", "Viernes", "Sábado", "Domingo"]
        meses = ["enero", "febrero", "marzo", "abril", "mayo", "junio", 
                "julio", "agosto", "septiembre", "octubre", "noviembre", "diciembre"]
    else:  # inglés por defecto
        dias = ["Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday", "Sunday"]
        meses = ["January", "February", "March", "April", "May", "June", 
                "July", "August", "September", "October", "November", "December"]
    
    dia_semana = dias[tiempo.tm_wday]
    mes = meses[tiempo.tm_mon - 1]
    
    if formato == "corto":
        return time.strftime("%d/%m/%Y", tiempo)
    elif formato == "medio":
        return f"{tiempo.tm_mday} de {mes}, {tiempo.tm_year}"
    else:  # completo
        return f"{dia_semana}, {tiempo.tm_mday} de {mes} de {tiempo.tm_year} a las {tiempo.tm_hour}:{tiempo.tm_min:02d}"

# Probar con el timestamp actual
ahora = time.time()

print("Formatos en español:")
print(f"Corto: {formatear_fecha(ahora, 'corto')}")
print(f"Medio: {formatear_fecha(ahora, 'medio')}")
print(f"Completo: {formatear_fecha(ahora, 'completo')}")

print("\nFormatos en inglés:")
print(f"Corto: {formatear_fecha(ahora, 'corto', 'en')}")
print(f"Medio: {formatear_fecha(ahora, 'medio', 'en')}")
print(f"Completo: {formatear_fecha(ahora, 'completo', 'en')}")

Convertir entre formatos de tiempo ISO 8601 y timestamp

import time
import re

def iso8601_a_timestamp(iso_string):
    """Convierte una cadena ISO 8601 (YYYY-MM-DDTHH:MM:SS) a timestamp."""
    # Extraer componentes con expresión regular
    pattern = r"(\d{4})-(\d{2})-(\d{2})T(\d{2}):(\d{2}):(\d{2})"
    match = re.match(pattern, iso_string)
    
    if not match:
        raise ValueError("Formato ISO 8601 inválido")
    
    # Crear tiempo estructurado
    year, month, day, hour, minute, second = map(int, match.groups())
    tiempo_struct = time.struct_time((year, month, day, hour, minute, second, 0, 0, -1))
    
    # Convertir a timestamp
    return time.mktime(tiempo_struct)

def timestamp_a_iso8601(timestamp):
    """Convierte un timestamp a formato ISO 8601."""
    return time.strftime("%Y-%m-%dT%H:%M:%S", time.localtime(timestamp))

# Ejemplos de uso
iso_fecha = "2023-09-21T15:30:00"
print(f"ISO 8601: {iso_fecha}")

# Convertir a timestamp
ts = iso8601_a_timestamp(iso_fecha)
print(f"Timestamp: {ts}")

# Convertir de nuevo a ISO 8601
iso_reconvertido = timestamp_a_iso8601(ts)
print(f"ISO 8601 reconvertido: {iso_reconvertido}")

Consideraciones importantes

Al trabajar con conversiones de tiempo, ten en cuenta:

  • Localización: Las funciones localtime() y strftime() dependen de la configuración regional del sistema.
  • Año 2038: En sistemas de 32 bits, los timestamps tienen un límite (problema del año 2038).
  • Precisión: Los timestamps en time tienen precisión de segundos; para mayor precisión, considera usar datetime.
  • Zonas horarias: Para manejo avanzado de zonas horarias, el módulo datetime junto con pytz ofrece más funcionalidades.
import time

# Demostración del formato de 12 horas vs 24 horas
ahora = time.localtime()

formato_12h = time.strftime("%I:%M:%S %p", ahora)  # 12 horas con AM/PM
formato_24h = time.strftime("%H:%M:%S", ahora)     # 24 horas

print(f"Formato 12 horas: {formato_12h}")
print(f"Formato 24 horas: {formato_24h}")

# Demostración de formatos internacionales
formato_us = time.strftime("%m/%d/%Y", ahora)      # MM/DD/YYYY (EE.UU.)
formato_eu = time.strftime("%d/%m/%Y", ahora)      # DD/MM/YYYY (Europa)
formato_iso = time.strftime("%Y-%m-%d", ahora)     # YYYY-MM-DD (ISO)

print(f"Formato EE.UU.: {formato_us}")
print(f"Formato europeo: {formato_eu}")
print(f"Formato ISO: {formato_iso}")

El dominio de las conversiones entre formatos de tiempo es fundamental para desarrollar aplicaciones que manejen datos temporales de manera efectiva, ya sea para presentación al usuario, almacenamiento en bases de datos o comunicación entre sistemas con diferentes convenciones de formato.

Aprendizajes de esta lección de Python

  • Comprender las funciones principales del módulo time para medir tiempos de ejecución y rendimiento.
  • Aprender a implementar pausas y temporizadores precisos en programas Python.
  • Conocer cómo convertir entre diferentes formatos de tiempo: timestamps, tiempo estructurado y cadenas formateadas.
  • Aplicar técnicas prácticas como decoradores y administradores de contexto para medir tiempos.
  • Entender consideraciones sobre precisión, variabilidad y limitaciones del módulo time.

Completa este curso de Python y certifícate

Únete a nuestra plataforma de cursos de programación 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

⭐⭐⭐⭐⭐
4.9/5 valoración