Files
controles/utils/date_utils.py

171 lines
5.3 KiB
Python
Raw Permalink Normal View History

from datetime import datetime, date
import logging
logger = logging.getLogger(__name__)
def validar_data(data_str: str, formato: str = '%Y-%m-%d') -> bool:
"""
Valida se uma string representa uma data válida no formato especificado.
Args:
data_str: String contendo a data
formato: Formato esperado da data (default: YYYY-MM-DD)
Returns:
bool: True se a data é válida, False caso contrário
"""
if not data_str:
return True
try:
datetime.strptime(data_str, formato)
return True
except ValueError as e:
logger.warning(f"Data inválida: {data_str} (formato esperado: {formato}). Erro: {e}")
return False
def converter_data(data_str: str, formato_entrada: str = '%Y-%m-%d', formato_saida: str = None) -> date:
"""
Converte uma string de data para um objeto date.
Args:
data_str: String contendo a data
formato_entrada: Formato da data de entrada (default: YYYY-MM-DD)
formato_saida: Se especificado, retorna a data como string neste formato
Returns:
date: Objeto date se formato_saida=None, string formatada caso contrário
Raises:
ValueError: Se a data for inválida
"""
if not data_str:
return None
try:
data = datetime.strptime(data_str, formato_entrada).date()
if formato_saida:
return data.strftime(formato_saida)
return data
except ValueError as e:
logger.error(f"Erro ao converter data '{data_str}': {e}")
raise ValueError(f"Data inválida: {data_str}. Use o formato {formato_entrada}")
def validar_sequencia_datas(data_nascimento: date = None,
data_entrada: date = None,
data_efetivacao: date = None) -> None:
"""
Valida a sequência lógica entre datas.
Args:
data_nascimento: Data de nascimento
data_entrada: Data de entrada na OCI
data_efetivacao: Data de efetivação na OCI
Raises:
ValueError: Se houver inconsistência entre as datas
"""
hoje = date.today()
# Validar datas futuras
for nome, data in [
("Data de nascimento", data_nascimento),
("Data de entrada", data_entrada),
("Data de efetivação", data_efetivacao)
]:
if data and data > hoje:
logger.warning(f"{nome} no futuro: {data}")
raise ValueError(f"{nome} não pode ser no futuro")
# Validar sequência
if data_nascimento and data_entrada and data_nascimento > data_entrada:
logger.warning(f"Data de entrada ({data_entrada}) anterior à data de nascimento ({data_nascimento})")
raise ValueError("Data de entrada na OCI não pode ser anterior à data de nascimento")
if data_entrada and data_efetivacao and data_entrada > data_efetivacao:
logger.warning(f"Data de efetivação ({data_efetivacao}) anterior à data de entrada ({data_entrada})")
raise ValueError("Data de efetivação não pode ser anterior à data de entrada")
def calcular_idade(data_nascimento: date) -> int:
"""
Calcula a idade com base na data de nascimento.
Args:
data_nascimento: Data de nascimento
Returns:
int: Idade em anos
"""
if not data_nascimento:
return None
hoje = date.today()
idade = hoje.year - data_nascimento.year
# Ajustar se ainda não fez aniversário este ano
if hoje.month < data_nascimento.month or \
(hoje.month == data_nascimento.month and hoje.day < data_nascimento.day):
idade -= 1
return idade
def converter_data_br(data_str):
"""Converte string de data no formato DD/MM/YYYY para objeto date"""
if not data_str:
return None
try:
dia, mes, ano = map(int, data_str.split('/'))
return date(ano, mes, dia)
except (ValueError, TypeError) as e:
return None
def converter_data_iso(data_str):
"""Converte string de data no formato YYYY-MM-DD para objeto date"""
if not data_str:
return None
try:
return datetime.strptime(data_str, '%Y-%m-%d').date()
except (ValueError, TypeError) as e:
return None
def formatar_data_br(data):
"""Formata objeto date para string no formato DD/MM/YYYY"""
if not data:
return ''
if isinstance(data, str):
data = converter_data_iso(data) or converter_data_br(data)
if not data:
return ''
return data.strftime('%d/%m/%Y')
def formatar_data_iso(data):
"""Formata objeto date para string no formato YYYY-MM-DD"""
if not data:
return ''
if isinstance(data, str):
data = converter_data_br(data) or converter_data_iso(data)
if not data:
return ''
return data.strftime('%Y-%m-%d')
def validar_data(data, data_maxima=None, data_minima=None):
"""Valida se a data está dentro do intervalo permitido"""
if not data:
return True
if isinstance(data, str):
data = converter_data_br(data) or converter_data_iso(data)
if not data:
return False
hoje = date.today()
if data_maxima and data > data_maxima:
return False
if data_minima and data < data_minima:
return False
if data > hoje:
return False
return True