2011-01-06 1 views
11

Qual è un modo efficace per calcolare il tempo di esecuzione successivo di un evento, data l'ora corrente e una specifica cron?Calcola il prossimo orario pianificato in base alla specifica cron

Sto cercando qualcosa di diverso da "scorrere ogni minuto controllando se corrisponde alle specifiche".

Esempi di specifiche potrebbero essere:

  • Ogni mese, il 1 ° e il 15 a 15:01
  • A 10.20.30.40.50 minuti dopo l'ora ogni ora

Il codice Python sarebbe bello ma sarebbe apprezzato anche il codice psuedo o la descrizione di alto livello.

[Aggiorna] Si supponga che la specifica sia già stata analizzata e sia in un formato ragionevole.

+0

Ho fatto qualcosa del genere, e ho trovato difficile da ottenere (e le mie possibili "specifiche" sono un tuo sottoinsieme). L'ho fatto solo con calcoli datetime e funzioni per ogni tipo di specifica. Sono interessato se qualcuno ha una risposta migliore (probabilmente la soluzione sarà usare la libreria: x) – Gerrat

+0

Puoi dare un esempio del formato della specifica? – aaronasterling

risposta

10

Basta guardarla, penso che è necessario:

  • analizzare il Chron spec a cinque array contenenti valori accettabili per ogni campo;
  • analizza 'ora' a un valore per ogni campo;
  • in ordine di minuto, ora, {giorno del mese O giorno della settimana}, mese dell'anno: trovare il valore dell'array più basso che corrisponde o supera il valore corrente, correggendo per carry.

Non so come gestire il giorno della settimana e il giorno del mese contemporaneamente; Sono sicuro che c'è un modo, ma d'altra parte non penso di aver mai visto una specifica che in realtà ha specificato entrambi. Penso che sarebbe sufficiente scrivere un gestore per entrambi e lanciare un errore se si ricevono entrambi.

Edit: a quanto pare, se il giorno della settimana e giorno-di-mese sono entrambi specificati, si suppone di sparare sui sia - vale a dire se la regola è '15, Mercoledì' che verrà fuoco su ogni 15 e ogni mercoledì.

Il pacchetto croniter fa ciò che si vuole:

import croniter 
import datetime 

now = datetime.datetime.now() 
sched = '1 15 1,15 * *' # at 3:01pm on the 1st and 15th of every month 
cron = croniter.croniter(sched, now) 

for i in range(4): 
    nextdate = cron.get_next(datetime.datetime) 
    print nextdate 

stampe

2011-01-15 15:01:00 
2011-02-01 15:01:00 
2011-02-15 15:01:00 
2011-03-01 15:01:00 

anche se sarebbe bello se fosse stato scritto come un iteratore vero e proprio. Forse ho il mio prossimo progetto ;-)

+0

Bella scoperta con croniter, molte grazie. Lascerò la domanda aperta ancora per un po 'per vedere se qualcuno lascia cadere un algoritmo fantastico su di noi. – Parand

+0

Grazie per la risposta.Ho usato il tuo codice per farlo funzionare, ma ho avuto bisogno di eseguirlo come un file EXE, quindi l'ho compilato in uno usando py2exe. Per chiunque voglia utilizzarlo, è possibile scaricarlo da qui: http://www.toughtomato.com/cron2NextDate/. Esempio di utilizzo: cron2NextDate.exe "0 15 1 * *" – Martin

+0

Sfortunatamente 'croniter' non funziona sulle modifiche all'ora legale. – mike

2

Later.js è una libreria javascript che fa proprio questo. È in grado di analizzare un'espressione Cron e quindi calcolare le occorrenze future del programma. L'algoritmo non è molto elaborato, ma fa il lavoro. Potrebbe meritare un'occhiata.