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