Especialização em Sistemas com Python 3.12+ • Capítulo 07


🎯 Demonstração Prática: Motor de SLA Global e Horário Comercial com ZoneInfo

O exemplo abaixo demonstra o tratamento corporativo de tempo em arquiteturas distribuídas:

  • Captura e tráfego em UTC padrão ISO 8601 com datetime.now(timezone.utc).
  • Conversão dinâmica para múltiplos fusos horários globais com o módulo nativo zoneinfo.ZoneInfo (PEP 615).
  • Algoritmo de cálculo de expiração de SLA pulando finais de semana (sábado e domingo).
  • Formatação regionalizada de datas para dashboards executivos.
"""
demonstracao_datas_e_zoneinfo.py
Motor de SLA Empresarial com ZoneInfo, Timedeltas e Conversão Global de Fusos.
Compatível com Python 3.12+ (PEP 615).
"""

from __future__ import annotations

from dataclasses import dataclass
from datetime import datetime, timedelta, timezone
from zoneinfo import ZoneInfo
from typing import Final

# ==============================================================================
# 1. CONSTANTES E FUSOS HORÁRIOS IANA
# ==============================================================================
FUSO_SP: Final[ZoneInfo] = ZoneInfo("America/Sao_Paulo")
FUSO_NY: Final[ZoneInfo] = ZoneInfo("America/New_York")
FUSO_LONDRES: Final[ZoneInfo] = ZoneInfo("Europe/London")
FUSO_TOQUIO: Final[ZoneInfo] = ZoneInfo("Asia/Tokyo")

@dataclass(slots=True)
class ChamadoSuporte:
    id_ticket: str
    cliente: str
    abertura_utc: datetime
    horas_sla_util: int
    vencimento_utc: datetime | None = None

# ==============================================================================
# 2. MOTOR DE CÁLCULO DE PRAZO DE SLA ÚTIL (DIAS DE SEMANA)
# ==============================================================================
def calcular_vencimento_sla_util(data_inicio_utc: datetime, horas_uteis: int) -> datetime:
    """
    Acrescenta horas de SLA considerando apenas dias úteis (segunda a sexta).
    Avança sobre sábados e domingos sem consumir a franquia de horas.
    """
    if data_inicio_utc.tzinfo is None:
        raise ValueError("A data deve ser Timezone-Aware (obrigatoriamente UTC).")

    cursor: datetime = data_inicio_utc
    horas_restantes: int = horas_uteis

    while horas_restantes > 0:
        cursor += timedelta(hours=1)
        # weekday(): 0=Segunda, 4=Sexta, 5=Sábado, 6=Domingo
        if cursor.weekday() < 5:
            horas_restantes -= 1

    return cursor

# ==============================================================================
# 3. CONVERSÃO E FORMATAÇÃO MULTIFUSO
# ==============================================================================
def gerar_painel_internacional(instante_utc: datetime) -> dict[str, str]:
    """Renderiza o mesmo instante temporal ajustado aos fusos das sedes globais."""
    return {
        "UTC (Referência Global)" : instante_utc.strftime("%Y-%m-%dT%H:%M:%SZ"),
        "São Paulo (BRT)"         : instante_utc.astimezone(FUSO_SP).strftime("%d/%m/%Y %H:%M:%S (%Z)"),
        "Nova York (EDT/EST)"     : instante_utc.astimezone(FUSO_NY).strftime("%m/%d/%Y %I:%M:%S %p (%Z)"),
        "Londres (BST/GMT)"       : instante_utc.astimezone(FUSO_LONDRES).strftime("%d/%m/%Y %H:%M:%S (%Z)"),
        "Tóquio (JST)"            : instante_utc.astimezone(FUSO_TOQUIO).strftime("%Y年%m月%d日 %H:%M:%S (%Z)"),
    }

# ==============================================================================
# 4. EXECUÇÃO PRINCIPAL
# ==============================================================================
if __name__ == "__main__":
    # Simulação de um ticket aberto na sexta-feira às 18:00 UTC com SLA de 16 horas úteis
    ticket_sexta = ChamadoSuporte(
        id_ticket="INC-2026-8801",
        cliente="Banco Internacional de Investimentos",
        abertura_utc=datetime(2026, 9, 25, 18, 0, 0, tzinfo=timezone.utc), # 25/09/2026 é sexta-feira
        horas_sla_util=16
    )

    ticket_sexta.vencimento_utc = calcular_vencimento_sla_util(
        ticket_sexta.abertura_utc,
        ticket_sexta.horas_sla_util
    )

    print("=" * 80)
    print("      SISTEMA DE GESTÃO DE SLA CORPORATIVO GLOBAL (ZONEINFO)")
    print("=" * 80)
    print(f"Ticket de Suporte : {ticket_sexta.id_ticket}")
    print(f"Cliente Corporativo: {ticket_sexta.cliente}")
    print(f"Franquia SLA      : {ticket_sexta.horas_sla_util} horas úteis (Segunda a Sexta)")
    print("-" * 80)

    print(">> MOMENTO DA ABERTURA DO CHAMADO:")
    for fuso_nome, data_formatada in gerar_painel_internacional(ticket_sexta.abertura_utc).items():
        print(f"  * {fuso_nome:<24} : {data_formatada}")

    print("\n" + "-" * 80)
    print(">> PRAZO FATAL DE VENCIMENTO DO SLA (PULOU O FIM DE SEMANA):")
    for fuso_nome, data_formatada in gerar_painel_internacional(ticket_sexta.vencimento_utc).items():
        print(f"  * {fuso_nome:<24} : {data_formatada}")

    # Cálculo da duração total decorrida (incluindo as 48h do fim de semana)
    delta_total: timedelta = ticket_sexta.vencimento_utc - ticket_sexta.abertura_utc
    print("-" * 80)
    print(f"Tempo Corrido Total (com fim de semana) : {delta_total.total_seconds() / 3600:.1f} horas físicas")
    print(f"Tempo Útil Efetivamente Contabilizado   : {ticket_sexta.horas_sla_util}.0 horas comerciais")
    print("=" * 80)