Sto tentando di aggiungere n (numero intero) giorni lavorativi a una determinata data, l'aggiunta data deve evitare le festività e i fine settimana (non è inclusa nel giorni lavorativi)Aggiungere n giorni lavorativi a una determinata data ignorando le festività ei fine settimana in python
risposta
Saltare i fine settimana sarebbe abbastanza facile fare qualcosa di simile:
import datetime
def date_by_adding_business_days(from_date, add_days):
business_days_to_add = add_days
current_date = from_date
while business_days_to_add > 0:
current_date += datetime.timedelta(days=1)
weekday = current_date.weekday()
if weekday >= 5: # sunday = 6
continue
business_days_to_add -= 1
return current_date
#demo:
print '10 business days from today:'
print date_by_adding_business_days(datetime.date.today(), 10)
Il problema delle vacanze è che variano molto per nazione o anche per regione, religione, ecc. visualizzare una lista/una serie di festività per il proprio caso d'uso e poi saltarle in un modo simile. Un punto di partenza potrebbe essere il feed di calendario che Apple pubblica per iCal (nel formato ics), quello per gli Stati Uniti sarebbe http://files.apple.com/calendars/US32Holidays.ics
È possibile utilizzare il modulo icalendar per analizzarlo.
Questo richiederà un po 'di lavoro dal momento che non esiste alcun costrutto definito per le vacanze in nessuna libreria (almeno a mia conoscenza). Dovrai creare la tua enumerazione di quelli.
Il controllo dei giorni del fine settimana viene effettuato facilmente chiamando .weekday() < 6
sull'oggetto datetime.
Non esiste una vera scorciatoia per farlo. Prova questo approccio:
- creare una classe che ha un metodo che restituisce
skip(self, d)
True
per le date che dovrebbero essere ignorati. - Creare un dizionario nella classe che contiene tutte le festività come date objects. Non usare
datetime
o simili perché le frazioni di un giorno ti uccideranno. - ritorno
True
per qualsiasi data che è nel dizionario od.weekday() >= 5
Per aggiungere N giorni, utilizzare questo metodo:
def advance(d, days):
delta = datetime.timedelta(1)
for x in range(days):
d = d + delta
while holidayHelper.skip(d):
d = d + delta
return d
La tua risposta è stata utile ma non posso contrassegnarla :(non ho abbastanza punti reputazione !! grazie! – cyberbrain
Grazie basati sul codice OMZ ho fatto alcuni piccoli cambiamenti ... è forse utile per gli altri utenti:
import datetime
def date_by_adding_business_days(from_date, add_days,holidays):
business_days_to_add = add_days
current_date = from_date
while business_days_to_add > 0:
current_date += datetime.timedelta(days=1)
weekday = current_date.weekday()
if weekday >= 5: # sunday = 6
continue
if current_date in holidays:
continue
business_days_to_add -= 1
return current_date
#demo:
Holidays =[datetime.datetime(2012,10,3),datetime.datetime(2012,10,4)]
print date_by_adding_business_days(datetime.datetime(2012,10,2), 10,Holidays)
Se non ti dispiace utilizzando una libreria 3rd party allora dateutil è a portata di mano
from dateutil.rrule import *
print "In 4 business days, it's", rrule(DAILY, byweekday=(MO,TU,WE,TH,FR))[4]
potete anche guardare rruleset
e utilizzando .exdate()
offrire le vacanze di saltare quelli nel calcolo e, facoltativamente, c'è un'opzione cache
per evitare di ri-calcolo che potrebbe essere la pena di guardare a.
Sembra che ci possa essere un'estensione di 'dateutil' che fornisce questo supporto: https://pypi.python.org/pypi/bdateutil/0.1 – Blairg23
o panda: https://stackoverflow.com/a/19036752/2097 – BlackShift
Volevo una soluzione che non fosse O (N) e sembrava un po 'divertente del codice golf. Ecco cosa ho sbattuto fuori nel caso qualcuno fosse interessato. Funziona con numeri positivi e negativi. Fammi sapere se mi sono perso qualcosa.
def add_business_days(d, business_days_to_add):
num_whole_weeks = business_days_to_add/5
extra_days = num_whole_weeks * 2
first_weekday = d.weekday()
remainder_days = business_days_to_add % 5
natural_day = first_weekday + remainder_days
if natural_day > 4:
if first_weekday == 5:
extra_days += 1
elif first_weekday != 6:
extra_days += 2
return d + timedelta(business_days_to_add + extra_days)
Sì, abbiamo bisogno di qualcosa non O (N), ma è davvero possibile? Come evitare le festività intermedie? – Ethan
Soluzione impressionante, sebbene non gestisca le vacanze come l'OP voleva. Inoltre, dovresti usare 'math.floor (business_days_to_add/5)' nella seconda riga quindi funziona anche in Python3. – lufte
Spero che questo aiuti. Non è O(N)
ma O(holidays)
. Inoltre, le festività funzionano solo quando l'offset è positivo.
def add_working_days(start, working_days, holidays=()):
"""
Add working_days to start start date , skipping weekends and holidays.
:param start: the date to start from
:type start: datetime.datetime|datetime.date
:param working_days: offset in working days you want to add (can be negative)
:type working_days: int
:param holidays: iterator of datetime.datetime of datetime.date instances
:type holidays: iter(datetime.date|datetime.datetime)
:return: the new date wroking_days date from now
:rtype: datetime.datetime
:raise:
ValueError if working_days < 0 and holidays
"""
assert isinstance(start, (datetime.date, datetime.datetime)), 'start should be a datetime instance'
assert isinstance(working_days, int)
if working_days < 0 and holidays:
raise ValueError('Holidays and a negative offset is not implemented. ')
if working_days == 0:
return start
# first just add the days
new_date = start + datetime.timedelta(working_days)
# now compensate for the weekends.
# the days is 2 times plus the amount of weeks are included in the offset added to the day of the week
# from the start. This compensates for adding 1 to a friday because 4+1 // 5 = 1
new_date += datetime.timedelta(2 * ((working_days + start.weekday()) // 5))
# now compensate for the holidays
# process only the relevant dates so order the list and abort the handling when the holiday is no longer
# relevant. Check each holiday not being in a weekend, otherwise we don't mind because we skip them anyway
# next, if a holiday is found, just add 1 to the date, using the add_working_days function to compensate for
# weekends. Don't pass the holiday to avoid recursion more then 1 call deep.
for hday in sorted(holidays):
if hday < start:
# ignore holidays before start, we don't care
continue
if hday.weekday() > 4:
# skip holidays in weekends
continue
if hday <= new_date:
# only work with holidays up to and including the current new_date.
# increment using recursion to compensate for weekends
new_date = add_working_days(new_date, 1)
else:
break
return new_date
- 1. Trova tre giorni lavorativi precedenti da una determinata data
- 2. Giorni lavorativi in Python
- 3. C# DateTime per aggiungere/Sottrarre giorni lavorativi
- 4. Ottenere inizio e fine giorni per una determinata settimana in PHP
- 5. Aggiunta di giorni a una determinata data in jQuery
- 6. Calcolare il numero di giorni lavorativi tra due giorni
- 7. Come calcolare 8 giorni lavorativi dalla data odierna?
- 8. r - trovare la differenza tra giorni lavorativi
- 9. Ottenere giorni lavorativi tra la data di inizio e di fine utilizzando i panda
- 10. Trova differenza di giorno tra due giorni (esclusi i giorni del fine settimana) in Python?
- 11. Generatore di intervalli di date in Python durante i giorni lavorativi
- 12. Jfreechart: come escludere i giorni del fine settimana dal grafico?
- 13. Aggiunta giorni lavorativi alla colonna datetime
- 14. Data confronto data: conta la quantità di giorni lavorativi da una data?
- 15. Come eseguire le operazioni del calendario in GWT Java? Come aggiungere giorni a una data?
- 16. data Mongoose campo - di default impostato a date.now + N giorni
- 17. Iterate in giorni, a partire da x data fino a una data di fine
- 18. Gestione affari/festività data
- 19. Come sottrarre/aggiungere giorni da/a una data?
- 20. Aggiungere giorni a una data senza modificare l'ora GMT
- 21. data get Android prima di 7 giorni (una settimana)
- 22. Ottenere giorni lavorativi usando Javascript
- 23. Come aggiungerei solo giorni lavorativi a un NSDate?
- 24. R aggiunta giorni a una data
- 25. Rimuovi righe di giorni non lavorativi da dataframe panda
- 26. Nascondi fine settimana sul toolkit WPF
- 27. escluda i fine settimana dal conteggio data/ora di tempo
- 28. come determinare se la data è fine settimana in javascript
- 29. Come calcolare il conteggio dei giorni lavorativi tra due date?
- 30. Android fornisce un'API per determinare i giorni del fine settimana che è sensibile alle impostazioni internazionali?
puoi mostrarci cosa hai provato fino ad ora - e anche, come vuoi che il codice funzioni? una funzione?o semplicemente come farlo? –
dovresti inserire il codice di sicurezza delle date delle vacanze (penso comunque) –