Estoy tratando de agregar n (enteros) días hábiles a una fecha determinada, la fecha adicional para evitar las vacaciones y los fines de semana (no está incluido en días laborables)Agregar n días hábiles a una fecha dada ignorando días festivos y fines de semana en python
Respuesta
fines de semana Saltarse serían bastante fácil hacer algo como esto:
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)
El problema con las vacaciones es que varían mucho por país o incluso por región, religión, etc. Sería n Haga una lista/conjunto de días festivos para su caso de uso y omítalos de manera similar. Un punto de partida puede ser el calendario que Apple publica para iCal (en el formato ics), el de Estados Unidos sería http://files.apple.com/calendars/US32Holidays.ics
Puede usar el módulo icalendar para analizar esto.
Esto requerirá cierto trabajo ya que no hay ningún constructo definido para las vacaciones en ninguna biblioteca (por lo que sé, al menos). Tendrá que crear su propia enumeración de esos.
La comprobación de los días de fin de semana se realiza fácilmente llamando al .weekday() < 6
en su objeto datetime.
No hay un atajo real para hacer esto. Pruebe este enfoque:
- crear una clase que tiene un método que devuelve
skip(self, d)
True
para las fechas que deben ser omitidos. - Cree un diccionario en la clase que contiene todas las vacaciones como date objects. No use
datetime
o similar porque las fracciones de un día lo matarán. - Volver
True
para cualquier fecha que está en el diccionario od.weekday() >= 5
Para añadir N días, utilice este método:
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
Tu respuesta fue útil pero no puedo marcarla :(¡No tengo suficientes puntos de reputación! ¡Gracias! – cyberbrain
Gracias a base de código omz he hecho algunos pequeños cambios ... que tal vez útil para otros usuarios:
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)
Si no les importa usar una biblioteca tercera parte dateutil entonces es práctico
from dateutil.rrule import *
print "In 4 business days, it's", rrule(DAILY, byweekday=(MO,TU,WE,TH,FR))[4]
también puede mirar en rruleset
y el uso de .exdate()
para proporcionar las vacaciones para saltar los del cálculo, y opcionalmente hay una opción cache
para evitar la re-cálculo que podría ser digno de mirar en a.
Parece que podría haber una extensión de 'dateutil' que proporciona este soporte: https://pypi.python.org/pypi/bdateutil/0.1 – Blairg23
o pandas: https://stackoverflow.com/a/19036752/2097 – BlackShift
Quería una solución que no fuera O (N) y parecía un poco divertido de código de golf. Esto es lo que saqué en caso de que alguien esté interesado. Funciona para números positivos y negativos. Avísame si me perdí algo.
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í, necesitamos algo que no sea O (N), pero ¿es eso realmente posible? ¿Cómo evitar las vacaciones en el medio? – Ethan
Solución impresionante, aunque no maneja las vacaciones como el OP quería. Además, debe usar 'math.floor (business_days_to_add/5)' en la segunda línea, también funciona en Python3. – lufte
Espero que esto ayude. No es O(N)
sino O(holidays)
. Además, las vacaciones solo funcionan cuando el desplazamiento es 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. Días hábiles en Python
- 2. r - búsqueda de diferencia entre días hábiles
- 3. Generador de rango de fechas de Python durante días hábiles
- 4. Agregar días a una fecha pero sin incluir fines de semana
- 5. ¿Cómo agregar el número de días a una fecha, considere solo los días hábiles (es decir, ignore los fines de semana)?
- 6. Calcular el número de días hábiles entre dos días
- 7. joda time - agregar días de la semana a la fecha
- 8. Agregar días a una fecha en Java
- 9. MySQL agregar días a una fecha
- 10. R Agregar los días a una fecha
- 11. ¿Cómo calcular 8 días hábiles a partir de la fecha de hoy?
- 12. ¿Cómo convertir una cantidad dada de días a años, meses y días en MySQL?
- 13. C#: Agregando días hábiles a partir de una fecha de recepción
- 14. ¿Cómo agregaría solo días hábiles a un NSDate?
- 15. añadiendo días a una fecha
- 16. Buscar número de días de la semana/fines de semana en un rango de fechas dado
- 17. Agregar días hasta la fecha en ActionScript
- 18. Cómo restar/agregar días de/a una fecha?
- 19. .NET Fecha de comparación: contar la cantidad de días hábiles desde una fecha?
- 20. ¿Encontrar diferencia de días entre dos fechas (excluyendo días de fin de semana) en Python?
- 21. ¿Cómo obtengo días festivos de la API de Bloomberg?
- 22. ¿Cómo agregar días a la fecha actual en javascript?
- 23. Búsqueda de directorios anteriores a N días en HDFS
- 24. Adición días a $ Fecha en PHP
- 25. Subconjunto R X días de la semana
- 26. ¿Cómo saltear fechas vacías (fines de semana) en un gráfico financiero de Matplotlib Python?
- 27. Días naturales/relativos en Python
- 28. Programador de tareas 6 días a la semana
- 29. ¿Eliminar registros con una fecha anterior a 3 días, para un trabajo de 3 días rodando?
- 30. ¿Agregar n horas a una fecha en Java?
¿Puede mostrarnos lo que ha intentado hasta ahora y también cómo desea que funcione el código? ¿Una función?o simplemente cómo hacerlo? –
tendrías que codificar las fechas de las vacaciones en (creo que de todos modos) –