2013-04-05 12 views
5

Biorąc pod uwagę ciąg znaków (reqDayOf), który jest nazwą dnia tygodnia, jak określić dzień tygodnia jako dziesiętny (a następnie zwrócić następną instancję na podstawie obiektu datetime)?Python: Biorąc pod uwagę ciąg znaków, który jest nazwą dnia tygodnia, jak określić dzień tygodnia jako dziesiętny (i datę następną).

Uzyskiwanie roku obiektu datetime i programu iso Tydzień roku, a następnie używanie strptime z rokiem + tydzień w roku + nazwa dnia tygodnia działa, ale działa jak włamanie.

import datetime 

def getDateFromDayOf(dateTimeObj,reqDayOf): 
    #reqDayOf is one of ['monday','tuesday','wednesday','thursday','friday','saturday','sunday'] 
    #return the next instance of reqDayOf 
    #after dateTimeObj 
    #as a datetime object 
    #Get the WeekOfYear from dateTimeObj and then 
    #get the date based on Year + WeekOfYear + reqDayOf 
    (dtoYear,dtoIsoWeek,x)=dateTimeObj.isocalendar() 
    checkDate= '{}-{}-{}'.format(dtoYear,dtoIsoWeek,reqDayOf) 
    dateOfDay=datetime.datetime.strptime(checkDate,"%Y-%U-%A") 
    #return dateOfDay if it's greater than the original date 
    if dateOfDay > dateTimeObj: 
    return dateOfDay 
    else: 
    #this is needed on Sundays 
    #add a week 
    return dateOfDay + datetime.timedelta(days=7) 


>>> datetime.datetime.now().strftime('%a %Y %b %d') 
'Fri 2013 Apr 05' 
>>> getDateFromDayOf(datetime.datetime.now(),'Monday').strftime('%a %Y %b %d') 
'Mon 2013 Apr 08' 

Odpowiedz

5

dzień tygodnia (jako liczba całkowita), jest zwracany przez weekday method:

import datetime as DT 
dow = dict(zip('monday tuesday wednesday thursday friday saturday sunday'.split(), 
      range(7))) 

def getDateFromDayOf(dateTimeObj, reqDayOf): 
    weekday = dateTimeObj.weekday()   
    return dateTimeObj + DT.timedelta(days=(dow[reqDayOf.lower()]-weekday-1)%7+1) 

In [90]: getDateFromDayOf(DT.datetime.now(), 'Monday').date() 
Out[90]: datetime.date(2013, 4, 8) 

In [91]: getDateFromDayOf(DT.datetime.now(), 'Tuesday').date() 
Out[91]: datetime.date(2013, 4, 9) 

In [92]: getDateFromDayOf(DT.datetime.now(), 'Friday').date() 
Out[92]: datetime.date(2013, 4, 12) 

Lub przy dateutil,

import datetime as DT 
import dateutil 
import dateutil.relativedelta as rdelta 
import dateutil.rrule as rrule 

dow = dict(zip('monday tuesday wednesday thursday friday saturday sunday'.split(), 
       (getattr(rdelta, d) for d in 'MO TU WE TH FR SA SU'.split()))) 
def getDateFromDayOf(dateTimeObj, reqDayOf): 
    rr = rrule.rrule(
     rrule.DAILY,      # step by days 
     byweekday = dow[reqDayOf.lower()], # return only this day of the week 
     dtstart = dateTimeObj)    # start on this day 
    res = rr.after(dateTimeObj, inc=False) # inc=False means don't include the dtstart day 
    return res 

Korzystanie dateutil można wyrazić ideę w sposób na wysokim poziomie, bez konieczności martwienia się o off-by-one błędy w brudnych szczegóły, takie jak

DT.timedelta(days=(dow[reqDayOf.lower()]-weekday-1)%7+1) 
+0

Nauczyłem się kilku rzeczy tutaj. dzięki! – Alex

2

ten jest podobny do sposobu w dni powszednie w @unutbu's anwser, ale realizowane różnie. Używa ona metody datetime.data do konwertowania daty na jedną liczbę, a następnie oblicza, ile dni ma zostać dodanych do żądanego dnia tygodnia, a następnie przekształciła ponownie nową liczbę w datę przy użyciu metody fromordinal().

Słownik nazwie DAYNUMS służy do konwersji nazwy reqDayOf dni powszednie w liczbie od 1 do 7, a isoweekday() służy do uczynienia tego samego dla dateTimeObj argument, który został przekazany w. Słownik DAYNUMS jest tworzony bez użycia nazw jawnie wpisanej dziennie oraz w taki sposób, aby działał w językach nieangielskich i językach, podając odpowiedni argument reqDayOf, np. 'lundi' w języku francuskim.

import datetime 

# April 1, 2013 was a Monday 
DAYNUMS = {datetime.date(2013, 4, i).strftime('%A').lower(): i 
       for i in range(1,8)} 

def getDateFromDayOf(dateTimeObj, reqDayOf): 
    daysDiff = (DAYNUMS[reqDayOf.lower()] - dateTimeObj.isoweekday() - 1) % 7 + 1 
    return datetime.date.fromordinal(dateTimeObj.toordinal() + daysDiff) 

now = datetime.datetime.now() 
print now.strftime('%a %Y %b %d') 
print getDateFromDayOf(now, 'Monday').strftime('%a %Y %b %d') 
Powiązane problemy