A Expressão 0 0 * * *
A expressão cron 0 0 * * * executa um trabalho no minuto 0 da hora 0 (meia-noite) todos os dias. Todos os cinco campos mapeiam para: minuto (0), hora (0), dia do mês (*), mês (*), dia da semana (*). Os curingas significam “qualquer valor”, então o trabalho dispara sempre que minuto=0 e hora=0, o que acontece uma vez a cada 24 horas às 00:00.
O Atalho @daily
A maioria das implementações cron suporta @daily como alias para 0 0 * * *. Também é equivalente a @midnight, que algumas implementações reconhecem como um alias adicional. O comportamento é idêntico, executando no início de cada dia calendário.
@daily # suportado em Vixie cron, cronie, fcron
@midnight # reconhecido por algumas implementações como equivalente a @daily
0 0 * * * # sempre funciona, portável entre todas as implementações cron
Se seu crontab é gerenciado por uma ferramenta (Ansible, Chef, Puppet, Kubernetes CronJob), verifique se a ferramenta suporta @daily ou apenas expressões padrão de 5 campos. Kubernetes CronJob suporta @daily; alguns sistemas antigos não.
Armadilhas de Fusó Horário
O padrão: fusó horário do sistema
O cron lê o fusó horário do sistema (/etc/localtime ou variável de ambiente TZ). Na maioria das VMs em nuvem, issó é UTC por padrão. Em servidores locais antigos, pode ser um fusó horário local. Nunca presuma em qual você está. Verifique com timedatectl ou date antes de confiar no comportamento da meia-noite.
Definindo TZ por crontab
Vixie cron e cronie suportam uma diretiva TZ no topo do crontab:
TZ=America/Sao_Paulo
0 0 * * * /opt/jobs/nightly-report
Issó faz o daemon cron interpretar todos os horários naquela entrada usando o fusó horário especificado, independentemente do fusó horário do sistema. Nem todas as implementações cron suportam isso. Verifique antes de usar em produção.
Melhor prática: executar cron em UTC
Configure seus servidores para UTC e faça a matemática de fusó horário na sua aplicação se necessário. Issó elimina surpresas de horário de verão e torna os timêstamps de log inequívocos.
Horário de Verão e Cron Diário
As transições de horário de verão afetam trabalhos cron agendados em horários que caem dentro da janela de mudança de relógio (tipicamente 02:00 em regiões que observam horário de verão). Meia-noite está fora desta janela, então um trabalho 0 0 * * * não é diretamente afetado pela maioria das transições.
No entanto, se você interpreta “meia-noite” como “meia-noite em um fusó horário local” e seu servidor executa em UTC, você precisa ajustar o campo de hora duas vezes por ano. Durante o Horário Padrão de Brasília (UTC-3), meia-noite BR é 0 3 * * * em UTC. Durante o Horário de Verão (UTC-2), meia-noite BR é 0 2 * * * em UTC. Usar qualquer valor fixo significa que o trabalho silenciosamente dispara no horário errado por metade do ano.
A solução limpa é a diretiva TZ (se suportada) ou servidores baseados em UTC com tratamento de fusó horário no nível da aplicação.
Casos de Usó Comuns para Cron Diário à Meia-Noite
Backups de banco de dados
Backups tipicamente executam quando a carga é mais baixa. Meia-noite evita sobreposição com tráfego de horário comercial, é o backup completa antes do dia de trabalho começar. Para bancos de dados grandes, distribua o início do backup alguns minutos após a meia-noite para evitar colisão com outros trabalhos noturnos.
Geração de relatórios
Resumos diários para dashboards, digests de email ou pipelines de análise são tipicamente computados após os dados do dia anterior serem totalmente coletados. Executar à meia-noite garante que o dia anterior esteja completo antes do relatório rodar.
Limpeza e arquivamento de dados
Purgar sessões expiradas, arquivar registros antigos ou rotacionar logs são tarefas de baixa urgência que funcionam bem à meia-noite. Se a limpeza afeta performance (locks de tabela, rebuilds de índice), fazê-la em horários de baixo pico reduz o impacto nos usuários.
Pipelines ETL
Trabalhos de extract transform load que puxam dados de fontes externas geralmente têm ciclos de atualização diários. Um cron à meia-noite alinha com o limite de dia típico usado pela maioria das fontes de dados e data warehouses.
Distribuindo Múltiplos Trabalhos Diários
Se você tem vários trabalhos diários, executar todos às 0 0 * * * pode causar contenção. Espaçe-os:
0 0 * * * /opt/jobs/backup-database
15 0 * * * /opt/jobs/generate-reports
30 0 * * * /opt/jobs/sync-external-data
45 0 * * * /opt/jobs/cleanup-temp-files
Cada trabalho começa 15 minutos após o anterior, dando ao trabalho anterior tempo para terminar antes do próximo começar.
Verificando a Execução
Para ver quando 0 0 * * * executará em seguida:
from croniter import croniter
from datetime import datetime
cron = croniter("0 0 * * *", datetime.now())
for _ in range(7):
print(cron.get_next(datetime))
Em um sistema Linux, verifique se o trabalho executou com:
grep CRON /var/log/syslog | grep "seu-job-name"
# ou com systemd:
journalctl -u cron --since "yesterday"