Tradutor de Cron: a armadilha do "OU" entre dia-do-mês e dia-da-semana
Uma expressão cron tem 5 campos — minuto, hora, dia-do-mês, mês,
dia-da-semana — cada um aceitando um valor específico, uma lista
(1,15), um intervalo (1-5), um passo
(*/5, "a cada 5 unidades") ou o curinga *
("qualquer valor"). A leitura intuitiva de "todos os campos precisam
bater" está certa para minuto, hora e mês — mas quebra especificamente
entre dia-do-mês e dia-da-semana, o par de campos mais mal compreendido
da sintaxe cron.
Por que dia-do-mês e dia-da-semana são "OU", não "E"
Quando ambos os campos de dia-do-mês e dia-da-semana
são restritos (diferentes de * nos dois), o cron executa
se qualquer um dos dois for satisfeito — não exige que
os dois sejam verdadeiros simultaneamente. Uma expressão como
0 9 15 * 1 (9h do dia 15 do mês, OU 9h de toda
segunda-feira) não significa "só quando o dia 15 cair numa segunda" —
significa "todo dia 15, e também toda segunda, independentemente de
coincidirem". Esse comportamento é definido explicitamente pela
especificação cron original e é consistente entre a maioria das
implementações (cron do Unix, muitos schedulers de CI/CD), mas
surpreende sistematicamente quem espera lógica "E" por padrão — um erro
de agendamento que só é percebido quando o job roda em dias inesperados.
Este tradutor explica a expressão, não calcula a próxima execução
Vale uma distinção de escopo explícita: esta ferramenta traduz cada campo da expressão para uma descrição em português (o que ela significa), mas não calcula a data/hora exata da próxima execução — esse é um problema diferente (e mais complexo, envolvendo fuso horário do servidor, tratamento de horário de verão quando aplicável, e a semântica de OU descrita acima) que exigiria uma implementação de calendário completa, não só um interpretador da sintaxe dos 5 campos.