2012-02-08 21 views
8

Dos problemas relacionados: (1) Todos los datos con los que trabajo tienen fechas de días laborables adjuntas. En varios puntos, necesito saber cuál es el próximo día de la semana. He escrito algo así como el código a continuación para tomar esta determinación, pero estoy seguro de que hay una mejor manera. ¿Nadie? (2) Idealmente, necesito saber no solo el próximo día laborable, sino el próximo día hábil en los EE. UU., es decir, el siguiente día laborable que no sea feriado en el mercado estadounidense. Cualquier ayuda en esto también sería genial.Datetime Python - Siguiente día hábil

import datetime as dt 

day = dt.datetime.strptime('2012-02-03','%Y-%m-%d').date() 
print day#day=2012-03-02 (Friday) 

if day.weekday()==4: 
    day = day+dt.timedelta(days=3) 
else: 
    day = day+dt.timedelta(days=1) 

print day#day=2012-02-06 (Monday) 
day = day+dt.timedelta(days=1) 
print day#day=2012-02-07 (Tuesday) 
+2

Podría ayudar: http: // stackoverflow.com/questions/2224742/business-days-in-python –

Respuesta

14

usaría dateutil.rrule:

import datetime 
from dateutil import rrule 


holidays = [ 
    datetime.date(2012, 5, 1,), 
    datetime.date(2012, 6, 1,), 
    # ... 
] 

# Create a rule to recur every weekday starting today 
r = rrule.rrule(rrule.DAILY, 
       byweekday=[rrule.MO, rrule.TU, rrule.WE, rrule.TH, rrule.FR], 
       dtstart=datetime.date.today()) 

# Create a rruleset 
rs = rrule.rruleset() 

# Attach our rrule to it 
rs.rrule(r) 

# Add holidays as exclusion days 
for exdate in holidays: 
    rs.exdate(exdate) 


print rs[0] 
6

esta pregunta es común y hay diferentes niveles de soluciones:

más simple: usar algo como el enfoque de la comprobación de la día de la semana. Una idom común es algo así como

d = datetime.date(2012,2,7) 
next = d + datetime.timedelta(days= 7-d.weekday() if d.weekday()>3 else 1) 

vez que desee días de fiesta, se puede rodar su propia fecha y hora "TradingDateChecker" que tiene que explorar para las vacaciones "predecibles" Like 1 Ene 4 de julio 25 Dic el viernes anterior o Lunes después de esos si caen en un fin de semana, el último lunes de mayo, primer lunes de septiembre, etc.

No me molestaré en publicar ese código aquí porque para las vacaciones comerciales, todavía es insuficiente.

  • Viernes Santo la Bolsa de Nueva York está cerrada y futuros y los mercados de bonos están abiertas
  • Columbus día y día de los veteranos, los bancos están cerrados y la bolsa está abierta.

Los mercados de valores y futuros tienen diferentes días festivos. Si desea vacaciones en NYSE (una solicitud común), consulte a continuación. Realmente no se puede evitar mantener su propio calendario ya que las fechas de cierre generalmente solo se anuncian en un par de años en el futuro.

# For a longer list of NYSE closed dates see: http://www.chronos-st.org/NYSE_Observed_Holidays-1885-Present.html 
holidays = [datetime.date(2000, 1, 17), 
datetime.date(2000, 2, 21), 
datetime.date(2000, 4, 21), 
datetime.date(2000, 5, 29), 
datetime.date(2000, 7, 4), 
datetime.date(2000, 9, 4), 
datetime.date(2000, 11, 23), 
datetime.date(2000, 12, 25), 
datetime.date(2001, 1, 1), 
datetime.date(2001, 1, 15), 
datetime.date(2001, 2, 19), 
datetime.date(2001, 5, 28), 
datetime.date(2001, 7, 4), 
datetime.date(2001, 9, 3), 
datetime.date(2001, 9, 11), 
datetime.date(2001, 9, 12), 
datetime.date(2001, 9, 13), 
datetime.date(2001, 9, 14), 
datetime.date(2001, 11, 22), 
datetime.date(2001, 12, 25), 
datetime.date(2002, 1, 1), 
datetime.date(2002, 1, 21), 
datetime.date(2002, 2, 18), 
datetime.date(2002, 3, 29), 
datetime.date(2002, 5, 27), 
datetime.date(2002, 7, 4), 
datetime.date(2002, 9, 2), 
datetime.date(2002, 11, 28), 
datetime.date(2002, 12, 25), 
datetime.date(2003, 1, 1), 
datetime.date(2003, 1, 20), 
datetime.date(2003, 2, 17), 
datetime.date(2003, 4, 18), 
datetime.date(2003, 5, 26), 
datetime.date(2003, 7, 4), 
datetime.date(2003, 9, 1), 
datetime.date(2003, 11, 27), 
datetime.date(2003, 12, 25), 
datetime.date(2004, 1, 1), 
datetime.date(2004, 1, 19), 
datetime.date(2004, 2, 16), 
datetime.date(2004, 4, 9), 
datetime.date(2004, 5, 31), 
datetime.date(2004, 6, 11), 
datetime.date(2004, 7, 5), 
datetime.date(2004, 9, 6), 
datetime.date(2004, 11, 25), 
datetime.date(2004, 12, 24), 
datetime.date(2005, 1, 17), 
datetime.date(2005, 2, 21), 
datetime.date(2005, 3, 25), 
datetime.date(2005, 5, 30), 
datetime.date(2005, 7, 4), 
datetime.date(2005, 9, 5), 
datetime.date(2005, 11, 24), 
datetime.date(2005, 12, 26), 
datetime.date(2006, 1, 2), 
datetime.date(2006, 1, 16), 
datetime.date(2006, 2, 20), 
datetime.date(2006, 4, 14), 
datetime.date(2006, 5, 29), 
datetime.date(2006, 7, 4), 
datetime.date(2006, 9, 4), 
datetime.date(2006, 11, 23), 
datetime.date(2006, 12, 25), 
datetime.date(2007, 1, 1), 
datetime.date(2007, 1, 2), 
datetime.date(2007, 1, 15), 
datetime.date(2007, 2, 19), 
datetime.date(2007, 4, 6), 
datetime.date(2007, 5, 28), 
datetime.date(2007, 7, 4), 
datetime.date(2007, 9, 3), 
datetime.date(2007, 11, 22), 
datetime.date(2007, 12, 25), 
datetime.date(2008, 1, 1), 
datetime.date(2008, 1, 21), 
datetime.date(2008, 2, 18), 
datetime.date(2008, 3, 21), 
datetime.date(2008, 5, 26), 
datetime.date(2008, 7, 4), 
datetime.date(2008, 9, 1), 
datetime.date(2008, 11, 27), 
datetime.date(2008, 12, 25), 
datetime.date(2009, 1, 1), 
datetime.date(2009, 1, 19), 
datetime.date(2009, 2, 16), 
datetime.date(2009, 4, 10), 
datetime.date(2009, 5, 25), 
datetime.date(2009, 7, 3), 
datetime.date(2009, 9, 7), 
datetime.date(2009, 11, 26), 
datetime.date(2009, 12, 25), 
datetime.date(2010, 1, 1), 
datetime.date(2010, 1, 18), 
datetime.date(2010, 2, 15), 
datetime.date(2010, 4, 2), 
datetime.date(2010, 5, 31), 
datetime.date(2010, 7, 5), 
datetime.date(2010, 9, 6), 
datetime.date(2010, 11, 25), 
datetime.date(2010, 12, 24), 
datetime.date(2011, 1, 17), 
datetime.date(2011, 2, 21), 
datetime.date(2011, 4, 22), 
datetime.date(2011, 5, 30), 
datetime.date(2011, 7, 4), 
datetime.date(2011, 9, 5), 
datetime.date(2011, 11, 24), 
datetime.date(2011, 12, 26), 
datetime.date(2012, 1, 2), 
datetime.date(2012, 1, 16), 
datetime.date(2012, 2, 20), 
datetime.date(2012, 4, 6), 
datetime.date(2012, 5, 28), 
datetime.date(2012, 7, 4), 
datetime.date(2012, 9, 3), 
datetime.date(2012, 11, 22), 
datetime.date(2012, 12, 25), 
datetime.date(2013, 1, 1), 
datetime.date(2013, 1, 21), 
datetime.date(2013, 2, 18), 
datetime.date(2013, 3, 29), 
datetime.date(2013, 5, 27), 
datetime.date(2013, 7, 4), 
datetime.date(2013, 9, 2), 
datetime.date(2013, 11, 28), 
datetime.date(2013, 12, 25)] 
1

otra manera sin IFS sería:

def next_wk_day(): 
    date_today = datetime.datetime.today() 
    shift = 1 + ((date_today.weekday()//4)*(6-date_today.weekday())) 
    return(date_today+shift) 

que también funcionaría en caso de que lo están haciendo en sábado o el domingo.

+4

o más simple: 'return date_today + [1, 1, 1, 1, 3, 2, 1] [date_today.weekday()]' Aunque estas fórmulas ignoran las vacaciones. – jfs

1

Utilicé el paquete holidays.

$ pip install holidays 

Aquí está la función que hice para determinar el siguiente día hábil después de hoy.

import datetime 
import holidays 

ONE_DAY = datetime.timedelta(days=1) 
HOLIDAYS_US = holidays.US() 

def next_business_day(): 
    next_day = datetime.date.today() + ONE_DAY 
    while next_day.weekday() in holidays.WEEKEND or next_day in HOLIDAYS_US: 
     next_day += ONE_DAY 
    return next_day 

Volverá la fecha de mañana, si mañana no es un fin de semana y no es un día festivo. De lo contrario, encontrará el próximo día * que no sea cualquiera de esas cosas. Ejemplo ejecuta el miércoles 15 de marzo de 2017

>>> next_business_day() 
datetime.date(2017, 3, 16) 

* Atención, en caso President Camacho declara cada día un día de fiesta, esto podría bucle infinito.

Cuestiones relacionadas