cron
não sabe quando um trabalho será acionado. Tudo o que faz é a cada minuto, passar por cima de todas as entradas crontab
e disparar aquelas que correspondem a "$(date '+%M %H %d %m %w')"
.
O que você pode fazer é gerar todos esses timestamps para cada minuto a partir de agora até 49 horas a partir de agora (contabilizar a alteração do horário de verão), fazer a correspondência manualmente (a parte complicada) e reportar o primeiro correspondente.
Ou você pode usar o cronificador python
module:
python -c '
from croniter import croniter
from datetime import datetime
iter = croniter("3 9 * * *", datetime.now())
print iter.get_next(datetime)'
Para o atraso:
$ faketime 13:52:00 python -c '
from croniter import croniter
from datetime import datetime
d = datetime.now()
iter = croniter("30 9 * * *", d)
print iter.get_next(datetime) - d'
19:37:59.413956
Cuidado com os possíveis bugs relacionados às alterações do horário de verão:
$ faketime '2015-03-28 01:01:00' python -c '
from croniter import croniter
from datetime import datetime
iter = croniter("1 1 * * *", datetime.now())
print iter.get_next(datetime)'
2015-03-29 02:01:00
$ FAKETIME_FMT=%s faketime -f 1445734799 date
Sun 25 Oct 01:59:59 BST 2015
$ FAKETIME_FMT=%s faketime -f 1445734799 python -c '
from croniter import croniter
from datetime import datetime
iter = croniter("1 1 * * *", datetime.now())
print iter.get_next(datetime)'
2015-10-25 01:01:00
$ FAKETIME_FMT=%s faketime -f 1445734799 python -c '
from croniter import croniter
from datetime import datetime
d = datetime.now()
iter = croniter("1 1 * * *", d)
print iter.get_next(datetime) - d'
-1 day, 23:01:01
O cron
cuida disso evitando executar o trabalho duas vezes se o tempo foi para trás ou executar tarefas ignoradas após o turno se o tempo tiver passado.