Expressão cron em português
Traduz a expressão e mostra as próximas execuções. E faz o que nenhum tradutor de cron faz: pergunta qual é o dialeto. O Hangfire usa cinco campos; o Quartz.NET usa seis, com segundos na frente — e copiar de um para o outro agenda na hora errada sem dar erro.
Leitor de expressão
Próximas execuções
Hangfire e Quartz não falam a mesma língua
Cron parece um padrão, e não é. O Hangfire usa cinco campos, começando pelo minuto. O Quartz.NET usa seis ou sete, começando pelos segundos — o que desloca todos os outros uma posição.
// MESMA intenção, expressões DIFERENTES — e é aqui que o incidente nasce.
// Hangfire: 5 campos, sem segundos
// minuto hora dia mês dia-da-semana
RecurringJob.AddOrUpdate("relatorio", () => Gerar(), "0 12 * * *"); // meio-dia
// Quartz.NET: 6 ou 7 campos, com SEGUNDOS na frente
// segundo minuto hora dia mês dia-da-semana [ano]
.WithCronSchedule("0 0 12 * * ?") // meio-dia
// 🔴 O que acontece ao copiar de um para o outro sem ajustar:
// "0 0 12 * *" no Hangfire -> minuto=0 hora=0 dia=12
// MEIA-NOITE DO DIA 12, uma vez por mês
// Ninguém recebe erro. O job só não roda quando se espera.Copiar do Quartz para o Hangfire falha alto, porque cinco campos não comportam seis. O caminho inverso é que é traiçoeiro: a expressão de cinco campos é válida no Hangfire, com outro significado. O job não roda quando se espera, e ninguém recebe erro nenhum. Experimente acima: cole 0 0 12 * * no dialeto do Hangfire e veja o que acontece.
O ponto de interrogação, que só existe no Quartz
// O '?' existe SÓ no Quartz, e só nos campos de dia. Ele significa "não me importo",
// e existe porque no Quartz é PROIBIDO especificar dia-do-mês e dia-da-semana ao
// mesmo tempo — um dos dois tem de ser '?'.
"0 0 12 * * ?" // todo dia ao meio-dia (dia-da-semana = não me importo)
"0 0 12 ? * MON" // toda segunda ao meio-dia (dia-do-mês = não me importo)
"0 0 12 * * *" // ERRO no Quartz: os dois campos preenchidos
// No Hangfire, o '?' não existe — e os dois campos preenchidos são aceitos, com
// semântica de OU: dia 1 OU segunda-feira.O fuso em que o job realmente roda
Esta ferramenta calcula as próximas execuções no fuso do seu navegador. O seu agendador roda no fuso do servidor — e em contêiner isso costuma ser UTC, não Brasília. Um job configurado para "3 da manhã" dispara à meia-noite no horário local.
A recomendação é sempre declarar o fuso explicitamente ao registrar o agendamento, em vez de depender do ambiente. Se o assunto for fuso, vale ver também o conversor de timestamp e fuso, onde está a armadilha do identificador que quebra em contêiner.
Perguntas frequentes
Por que a mesma expressão cron roda em horário diferente no Hangfire e no Quartz?
Porque os dois usam dialetos diferentes, e os campos escorregam uma posição. O Hangfire usa cinco campos, começando pelo minuto; o Quartz.NET usa seis ou sete, começando pelos SEGUNDOS. Copiar uma expressão de cinco campos para o Quartz é erro de sintaxe e pelo menos falha alto — mas o caminho inverso é silencioso: "0 0 12 * *" no Hangfire significa minuto zero, hora zero, dia doze, ou seja meia-noite do dia 12 uma vez por mês, e não meio-dia todos os dias. O agendamento simplesmente não acontece quando se espera, e ninguém recebe erro.
O que significa o ponto de interrogação numa expressão cron?
É uma extensão do Quartz, e não existe no cron tradicional nem no Hangfire. Ele significa "não me importo" e só pode aparecer nos campos de dia-do-mês e dia-da-semana. Existe porque o Quartz PROÍBE especificar os dois ao mesmo tempo: um deles precisa ser o ponto de interrogação. Já no cron tradicional os dois podem ser preenchidos, e a convenção é que o agendamento ocorre quando QUALQUER um dos dois bate — o que surpreende quem espera que os dois precisem coincidir.
O que significa a barra numa expressão cron?
A barra indica um passo. No campo de minutos, */15 quer dizer "de 15 em 15 a partir do zero", ou seja, nos minutos 0, 15, 30 e 45. O detalhe que confunde é que a barra não precisa vir depois do asterisco: 5/10 significa "a partir do minuto 5, de 10 em 10", chegando em 5, 15, 25, 35, 45 e 55. Um valor solto sem barra é só ele mesmo — então 5 é apenas o minuto 5, e não "a cada 5 minutos", que é o erro mais comum de quem está começando.
Em que fuso horário o cron do meu agendador roda?
Depende do agendador e da configuração, e essa é a segunda maior fonte de surpresa depois do dialeto. O Hangfire usa por padrão o fuso do servidor, e aceita um TimeZoneInfo explícito ao registrar o job recorrente. O Quartz.NET permite definir o fuso no próprio agendamento com InTimeZone. Em contêiner, o fuso do servidor costuma ser UTC — então um job configurado para "3 da manhã" roda à meia-noite no horário de Brasília. A recomendação prática é sempre declarar o fuso explicitamente, em vez de depender do ambiente.
Como agendar um job para rodar a cada X minutos?
Use a barra no campo de minutos: */5 para cada cinco minutos, */15 para cada quinze, */30 para cada trinta. Vale notar que o passo se aplica dentro da hora, e reinicia a cada hora — então */7 não significa "a cada sete minutos" de forma contínua: ele dispara nos minutos 0, 7, 14, 21, 28, 35, 42, 49 e 56, e depois pula direto para o minuto 0 da hora seguinte, com um intervalo de apenas quatro minutos na virada. Se o intervalo precisa ser exato, use um agendamento por intervalo em vez de cron.
Outras ferramentas
Todas em ferramentas para desenvolvedor — rodam no navegador, sem cadastro e sem anúncio.
Receba os próximos artigos
Conteúdo técnico de .NET direto no seu e-mail. Sem spam, e você sai quando quiser.