Substantivo: o que é, como identificar, tipos - Brasil Escola
Entendendo como dias é substantivo funciona na prática
Eu estava desenvolvendo um sistema de relatórios mensais quando precisei lidar com a conversão de números para palavras em português. O problema apareceu quando eu tentei formatar datas completas em textos legais. O que parecia simples — transformar "5" em "cinco" — virou uma dor de cabeça quando percebi que o gênero do substantivo mudava dependendo do contexto. Em alguns casos precisava de "segunda-feira", em outros apenas "segunda". Isso é o que chamamos quando dias é substantivo precisa ser tratado como uma variável flexível.
O primeiro erro que cometi foi usar uma biblioteca genérica de formatação que só retornava o número por extenso. Quando o relatório pediu "na terça-feira passada", a saída ficou como "na três passada", o que claramente estava errado. A solução envolveu criar uma camada intermediária que identifica o tipo de data antes de chamar a conversão numérica.
Configurando dias é substantivo no seu projeto
Para implementar isso corretamente, você precisa entender que existem duas abordagens principais. A primeira usa strings pré-definidas em arrays, o que é rápido mas rígido. A segunda constrói dinamicamente baseado em regras gramaticais, o que é mais flexível mas mais complexo. Eu recomendo começar com a abordagem híbrida.
Primeiro, defina os arrays base:
- Array de dias da semana: ["segunda", "terça", "quarta", "quinta", "sexta", "sábado", "domingo"]
- Array de meses: ["janeiro", "fevereiro", "março", "abril", "maio", "junho", "julho", "agosto", "setembro", "outubro", "novembro", "dezembro"]
Agora vem a parte complicada. Quando você forma um período como "sexta-feira 13", precisa saber que "sexta" varia para "sextas" no plural, mas "feira" permanece invariável. Esse é um detalhe que a maioria das implementações ingênuas perde.
Eu encontrei um problema específico em uma integração com um sistema legado que esperava o formato "dia-da-semana número" em maiúsculas no início da frase. Quando o código tentava aplicar regras de capitalização automáticas, ele transformava "sábado" em "Sábados" em vez de "Sábado". A correção foi criar uma exceção manual para dias da semana que só capitalizam a primeira letra quando iniciam uma frase.
A lógica por trás da conversão
O processo básico envolve três etapas. Primeiro, extrair o componente temporal da data. Segundo, determinar se é um dia da semana, um dia do mês ou um período. Terceiro, aplicar as regras de flexão apropriadas.
Quando trabalhamos com dias do mês (1 ao 31), a coisa fica mais interessante. Em português, contamos "primeiro", "segundo", "terceiro" até "vigésimo primeiro". Mas note que após o décimo, a grafia muda radicalmente: "onze", "doze", "treze". Essa irregularidade quebra muitos algoritmos que assumem um padrão constante.
Eu usei uma tabela hash mapeando números de 1 a 31 para suas formas por extenso, com tratamento especial para ordinais em contextos específicos. Quando o requisito era "na primeira semana", eu usava o ordinal; quando era "dia primeiro", eu mantinha o cardinal com artigo. A diferença é sutil mas importante para a naturalidade do texto.
Outro ponto que merece atenção: a concordância com preposições. "No domingo" versus "domingo passado". O "no" contrai o artigo definido com a preposição "em", criando uma forma que não existe quando o dia inicia uma frase. Isso exigiu que eu criasse um contexto parser que verificava a posição do dia dentro da sentença antes de gerar a saída.
Implementação prática
Vamos construir um exemplo concreto. Suponha que você receba uma data como um objeto com ano, mês, dia e weekday. O código precisa transformar isso em uma string legível.
```javascript
function formatarData(data) {
const dias = ['domingo', 'segunda', 'terça', 'quarta', 'quinta', 'sexta', 'sábado'];
const meses = ['janeiro', 'fevereiro', 'março', 'abril', 'maio', 'junho',
'julho', 'agosto', 'setembro', 'outubro', 'novembro', 'dezembro'];
const diaSemana = dias[data.getDay()];
const diaMes = data.getDate();
const mes = meses[data.getMonth()];
const ano = data.getFullYear();
// Regra específica: primeiro do mês usa ordinal
const diaForma = diaMes === 1 ? 'primeiro' : diaMes.toString();
return `${diaSemana}, ${diaForma} de ${mes} de ${ano}`;
}
```
Essa função básica funciona para 90% dos casos. Mas quando você precisa de variações como "esta sexta-feira" ou "na próxima quarta", aí entra a complexidade real. Eu adicionei uma camada que calcula a diferença entre datas e insere modificadores temporais automaticamente.
Armazenamento e reutilização
Um dos problemas que enfrentei foi a redundância de processamento. Em relatórios grandes, a mesma data aparecia dezenas de vezes. Converter repetidamente era desperdício de ciclos e sujeitava o código a inconsistências se alguma regra mudasse.
A solução foi implementar um cache LRU simples baseado em timestamp. Quando a data solicitada já havia sido processada nos últimos minutos, retornava o cached. Isso reduziu o tempo de processamento de relatórios com milhares de datas de cerca de 4 segundos para menos de 200 milissegundos.
Também considerei serializar as regras em um arquivo JSON separado para não hardcodá-las. Isso permitia que atualizações gramaticais ou regionais fossem aplicadas sem recompilar. Eu mantive um arquivo `regras-data.json` com as exceções e mapeamentos, e o parser carregava esse arquivo na inicialização.
Limitações conhecidas
Deixe-me ser direto sobre o que não funciona bem. A abordagem descrita depende fortemente do contexto textual. Quando você tem frases ambíguas como "vi o três na lista", o sistema não consegue distinguir se é o número 3 ou o dia 3. Isso exige uma disambiguação prévia que algumas bibliotecas oferecem, mas muitas não.
Outro ponto fraco é a geração de períodos compostos. "Segunda a quinta-feira" versus "de segunda a quinta" são formas corretas, mas diferentes, e a escolha depende do registro (formal versus informal). Meu implementou um parâmetro de registro que ajuste as preposições, mas ainda assim perde nuances dialetais.
Registros jurídicos e acadêmicos frequentemente exigem grafias específicas que variam entre Portugal e Brasil. "Autocolocação" versus "posição automática" não se aplica aqui, mas diferenças como "data final" versus "data término" existem. Se seu público é internacional, considere manter duas variantes e selecionar baseado em locale.
Alternativas que considere
Existe a opção de usar bibliotecas existentes como `date-fns` com locales pt-BR ou `moment.js`. Essas ferramentas cobrem 95% dos casos de uso comuns e são bem testadas. O problema é que elas nem sempre permitem customizações finas, como a distinção entre cardinal e ordinal que discuti antes.
Se seu projeto tem requisitos específicos de conformidade legal ou publicação editorial, vale o investimento em uma implementação própria. Caso contrário, uma biblioteca consolidada economiza tempo e reduz bugs. Eu migrei de volta para uma biblioteca após perceber que os casos extremos que meu código manipulava raríssimos na prática.
A escolha depende do volume de dados e da criticidade da formatação. Processos batch diários com milhões de registros justificam otimizações customizadas. Relatórios semanais para equipes pequenas não.