171 lines
5.3 KiB
Python
171 lines
5.3 KiB
Python
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 |