Agendamento cron
Cron todo dia útil às 9h
A expressão cron para todo dia útil às 9h é 0 9 * * 1-5: 09:00 de segunda a sexta, cinco execuções por semana. É o agendamento padrão para lembretes de daily e relatórios matinais.
| Expressão | 0 9 * * 1-5 |
|---|---|
| Execuções | 261 vezes em 2027 |
| OnCalendar do systemd | Mon..Fri *-*-* 09:00:00 |
Como funciona
Três campos carregam o significado: minuto 0, hora 9, dia da semana 1-5. Dia do mês e mês ficam *. A própria documentação do GitHub usa um primo próximo, 30 5 * * 1-5 com timezone: "America/New_York", como exemplo de fuso horário.
Uma tarefa das 9h só serve às 9h de quem recebe. Em plataformas só UTC, 9h no horário de Brasília é 0 12 * * 1-5, o ano todo, já que o Brasil não tem mais horário de verão. Para Lisboa, é 0 8 * * 1-5 no verão europeu e 0 9 * * 1-5 no inverno.
No Kubernetes defina spec.timeZone, no GitHub adicione timezone, no cronie use CRON_TZ, e a expressão continua 0 9 * * 1-5 em todo lugar.
| Campo | Valor | Significado |
|---|---|---|
| Minuto | 0 | minuto 0 (hora cheia) |
| Hora | 9 | hora 9 (9h) |
| Dia do mês | * | todo dia do mês |
| Mês | * | todo mês |
| Dia da semana | 1-5 | de segunda-feira a sexta-feira |
Próximas execuções
Como no GitHub Actions sem timezone, na Vercel, na Cloudflare e no Kubernetes com timeZone "Etc/UTC".
| Execução | Seu horário | UTC |
|---|---|---|
| 1 | Calculando… | |
| 2 | ||
| 3 | ||
| 4 | ||
| 5 |
Versões prontas para colar
O mesmo agendamento em cada agendador, com o que muda em cada um.
crontab (Linux, macOS, BSD)
# m h dom mon dow command
0 9 * * 1-5 /usr/local/bin/job.sh >> /var/log/job.log 2>&1- O cron usa o fuso horário do servidor. No cronie (Fedora, RHEL),
CRON_TZ=America/Sao_Paulonuma linha acima muda o fuso das linhas seguintes.
GitHub Actions
on:
schedule:
- cron: '0 9 * * 1-5'
# timezone: 'America/Sao_Paulo' # opcional; sem ele, UTC
workflow_dispatch: {}- Roda em UTC, a menos que você defina
timezone, e só no branch padrão. A documentação do GitHub avisa que execuções agendadas podem atrasar em horários de pico e que, em repositórios públicos, o agendamento é desativado após 60 dias sem atividade. - O início de cada hora é o horário de maior fila no GitHub. Se o minuto exato não importa, troque o
0por outro minuto, como17, para atrasar menos. - Com
timezonenum fuso que tem horário de verão, um horário que não existe no dia da mudança é adiado para o próximo horário válido (2:30 vira 3:00, segundo a documentação).
CronJob do Kubernetes
apiVersion: batch/v1
kind: CronJob
metadata:
name: scheduled-job
spec:
schedule: "0 9 * * 1-5"
timeZone: "Etc/UTC"
concurrencyPolicy: Forbid
jobTemplate:
spec:
template:
spec:
restartPolicy: OnFailure
containers:
- name: job
image: busybox:1.36
command: ["/bin/sh", "-c", "date; echo running"]spec.timeZoneé estável desde o Kubernetes 1.27; sem ele, vale o fuso do kube-controller-manager.concurrencyPolicy: Forbidpula uma execução se a anterior ainda estiver rodando.
Cron Jobs da Vercel
{
"crons": [
{ "path": "/api/cron", "schedule": "0 9 * * 1-5" }
]
}- A Vercel sempre usa UTC, não aceita nomes como
MONouJANe não deixa definir dia do mês e dia da semana ao mesmo tempo. - Cabe no plano Hobby, mas lá a precisão é por hora: o disparo pode acontecer em qualquer minuto dentro da hora agendada.
Cloudflare Workers
[triggers]
crons = ["0 9 * * MON-FRI"]- Cron Triggers rodam em UTC. Mudanças podem levar até 15 minutos para se propagar pela rede da Cloudflare.
- Na Cloudflare, os dias da semana vão de 1 = domingo a 7 = sábado, diferente do cron comum. Por isso o exemplo usa nomes (
MON,SUN), que não têm ambiguidade.
node-cron (Node.js)
import cron from 'node-cron';
// 6 campos: o primeiro (segundos) é opcional
cron.schedule('0 0 9 * * 1-5', async () => {
await runJob();
}, { timezone: 'UTC', noOverlap: true });- O agendamento vive dentro do processo Node: se ele cair, nada roda; se houver três réplicas, a tarefa roda três vezes.
noOverlappula um disparo enquanto o anterior não terminou.
Timer do systemd
# /etc/systemd/system/job.timer
[Unit]
Description=Run job.service at 09:00 Monday to Friday
[Timer]
OnCalendar=Mon..Fri *-*-* 09:00:00
Persistent=true
[Install]
WantedBy=timers.target
# /etc/systemd/system/job.service
[Service]
Type=oneshot
ExecStart=/usr/local/bin/job.sh
# systemctl daemon-reload && systemctl enable --now job.timer- Confira com
systemd-analyze calendar 'Mon..Fri *-*-* 09:00:00', que mostra a forma normalizada e a próxima execução.AccuracySecpadrão é 1min, então o disparo pode variar até um minuto. Persistent=trueroda a tarefa assim que a máquina liga se o horário passou com ela desligada, algo que o cron não faz.
Spring @Scheduled e Quartz
@Scheduled(cron = "0 0 9 * * 1-5", zone = "UTC")
public void runJob() {
// ...
}
// Quartz CronTrigger:
CronScheduleBuilder.cronSchedule("0 0 9 ? * MON-FRI")- No Spring, o primeiro dos 6 campos são os segundos; o resto segue o cron comum (0 ou 7 = domingo).
- No Quartz, um dos campos de dia precisa ser
?, e os dias da semana vão de 1 = domingo a 7 = sábado; por isso o exemplo usa nomes.
Armadilhas
A Cloudflare lê 1-5 como domingo a quinta
Os Cron Triggers da Cloudflare numeram os dias de 1 = domingo a 7 = sábado. Colar 0 9 * * 1-5 faz rodar de domingo a quinta. Lá, escreva 0 9 * * MON-FRI. O Quartz tem a mesma numeração.
Converter para UTC pode mudar o dia
Em fusos longe de UTC, 09:00 local pode cair no dia UTC anterior ou seguinte. No horário de Brasília não acontece (9h é 12h UTC), mas numa equipe na Ásia ou na Oceania a faixa de dias em UTC precisa ser ajustada.
Feriados e folgas
Um lembrete que dispara no feriado é, na melhor das hipóteses, ruído. Consulte um calendário de feriados na tarefa, ou aceite e deixe as pessoas silenciarem.
Perguntas frequentes
- Qual é a expressão cron para 9h em dias úteis?
- 0 9 * * 1-5 roda às 09:00 de segunda a sexta.
- Como rodar um workflow do GitHub Actions às 9h de Brasília em dias úteis?
- Use cron: '0 9 * * 1-5' com timezone: 'America/Sao_Paulo'. Sem o timezone, o equivalente em UTC é 0 12 * * 1-5.
- Como rodar às 9h de segunda a sexta nos Cloudflare Workers?
- crons = ["0 12 * * MON-FRI"] para 9h de Brasília, já que a Cloudflare roda em UTC. Lá, 1-5 significaria de domingo a quinta.
- Como rodar de hora em hora das 9h às 17h em dias úteis?
- 0 9-17 * * 1-5 roda na hora cheia das 09:00 às 17:00, de segunda a sexta.
Revisado em por Arielton Oberek.