datetime datetime - Giorni lavorativi in Python





from string (8)


Usa i panda!

import pandas as pd
# BDay is business day, not birthday...
from pandas.tseries.offsets import BDay

# pd.datetime is an alias for datetime.datetime
today = pd.datetime.today()
print today - BDay(4)

Da oggi è giovedì, 26 settembre, che ti darà una produzione di:

datetime.datetime(2013, 9, 20, 14, 8, 4, 89761)

Devo sottrarre i giorni lavorativi dalla data corrente.

Al momento ho del codice che deve essere sempre in esecuzione il giorno lavorativo più recente. Quindi potrebbe essere oggi se siamo da lunedì a venerdì, ma se è sabato o domenica, allora devo riportarlo al venerdì prima del fine settimana. Al momento ho un codice piuttosto goffo per fare questo:

 lastBusDay = datetime.datetime.today()
 if datetime.date.weekday(lastBusDay) == 5:      #if it's Saturday
     lastBusDay = lastBusDay - datetime.timedelta(days = 1) #then make it Friday
 elif datetime.date.weekday(lastBusDay) == 6:      #if it's Sunday
     lastBusDay = lastBusDay - datetime.timedelta(days = 2); #then make it Friday

C'è un modo migliore?

Posso dire a timedelta di lavorare nei giorni feriali piuttosto che nei giorni di calendario, ad esempio?




 def getNthBusinessDay(startDate, businessDaysInBetween):
    currentDate = startDate
    daysToAdd = businessDaysInBetween
    while daysToAdd > 0:
        currentDate += relativedelta(days=1)
        day = currentDate.weekday()
        if day < 5:
            daysToAdd -= 1

    return currentDate 



pacchetto di timeboard fa questo.

Supponiamo che il tuo appuntamento sia il 4 settembre 2017. Nonostante sia lunedì, è stata una vacanza negli Stati Uniti (il Labor Day). Quindi, il giorno lavorativo più recente è stato venerdì, 1 settembre.

>>> import timeboard.calendars.US as US
>>> clnd = US.Weekly8x5()
>>> clnd('04 Sep 2017').rollback().to_timestamp().date()
datetime.date(2017, 9, 1)

Nel Regno Unito, il 4 settembre 2017 era la normale giornata lavorativa, quindi la giornata lavorativa più recente era di per sé.

>>> import timeboard.calendars.UK as UK
>>> clnd = UK.Weekly8x5()
>>> clnd('04 Sep 2017').rollback().to_timestamp().date()
datetime.date(2017, 9, 4)

NOTA BENE: Sono l'autore del timeboard.




Forse questo codice potrebbe aiutare:

lastBusDay = datetime.datetime.today()
shift = datetime.timedelta(max(1,(lastBusDay.weekday() + 6) % 7 - 3))
lastBusDay = lastBusDay - shift

L'idea è che il lunedì devi tornare 3 giorni, la domenica 2 e 1 in qualsiasi altro giorno.

L'istruzione (lastBusDay.weekday() + 6) % 7 ripropone il lunedì da 0 a 6.

Davvero non so se questo sarà migliore in termini di prestazioni.




DISCLAMER: Sono l'autore ...

Ho scritto un pacchetto che fa esattamente questo, calcoli di date aziendali. Puoi utilizzare le specifiche della settimana e le festività personalizzate.

Ho avuto questo problema esatto mentre lavoravo con i dati finanziari e non ho trovato nessuna delle soluzioni disponibili particolarmente facile, quindi ne ho scritto uno.

Spero che questo sia utile per le altre persone.

https://pypi.python.org/pypi/business_calendar/




Questo darà un generatore di giorni lavorativi, ovviamente senza vacanze, stop è l'oggetto datetime.datetime. Se hai bisogno di una vacanza basta fare ulteriori argomenti con l'elenco delle vacanze e controllare con 'IFology' ;-)

def workingdays(stop, start=datetime.date.today()):
    while start != stop:
        if start.weekday() < 5:
            yield start
        start += datetime.timedelta(1)

Più tardi puoi contarli come

workdays = workingdays(datetime.datetime(2015, 8, 8))
len(list(workdays))






Puoi farlo :-

[condition] and [expression_1] or [expression_2] ;

Esempio:-

print(number%2 and "odd" or "even")

Questo verrebbe stampato "dispari" se il numero è dispari o "pari" se il numero è pari.

Il risultato: - Se la condizione è vera, exp_1 viene eseguita altrimenti viene eseguita exp_2.

Nota: - 0, Nessuna, False, lista vuota, emptyString viene valutata come False. E qualsiasi dato diverso da 0 viene valutato come True.

Ecco come funziona:

se la condizione [condizione] diventa "Vero", allora espressione_1 sarà valutata ma non espressione_2. Se noi "e" qualcosa con 0 (zero), il risultato sarà sempre fasullo. Quindi nella seguente istruzione,

0 and exp

L'espressione exp non verrà valutata affatto poiché "e" con 0 valuterà sempre a zero e non è necessario valutare l'espressione. Ecco come funziona il compilatore stesso, in tutte le lingue.

Nel

1 or exp

l'espressione exp non verrà valutata affatto poiché "o" con 1 sarà sempre 1. Quindi non si preoccuperà di valutare l'espressione exp poiché il risultato sarà 1 comunque. (metodi di ottimizzazione del compilatore).

Ma in caso di

True and exp1 or exp2

La seconda espressione exp2 non verrà valutata poiché True and exp1 sarebbe True se exp1 non è falso.

Allo stesso modo in

False and exp1 or exp2

L'espressione exp1 non sarà valutata poiché False equivale a scrivere 0 e fare "e" con 0 sarebbe 0 stesso ma dopo exp1 poiché "or" è usato, valuterà l'espressione exp2 dopo "o".

Nota: - Questo tipo di diramazione che utilizza "or" e "and" può essere utilizzato solo quando expression_1 non ha un valore di verità di False (o 0 o None o emptylist [] o emptystring ''.) Poiché if expression_1 diventa False, quindi l'espressione_2 verrà valutata a causa della presenza "o" tra exp_1 e exp_2.

Se vuoi comunque farlo funzionare per tutti i casi indipendentemente dai valori di verità exp_1 e exp_2, fai questo: -

[condition] and ([expression_1] or 1) or [expression_2] ;







python datetime