Python: for a string called the name of the day of the week, how to define the day of the week as decimal (and the next date).

Given the string (reqDayOf) called the name of the day of the week, how do you define the day of the week as decimal (and then return the next instance from it based on the datetime object)?

Getting the datetime year and iso Week of Year objects, and then using strptime with the year + week of the year + workday name works, but feels like a hack.

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 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'
+5
source share
2 answers

The day of the week (as an integer) is returned by the 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)

Or using 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

dateutil, , ,

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

@unutbu anwser, -. datetime.data toordinal() , , , , , fromordinal(),

DAYNUMS reqDayOf 1 7, isoweekday() dateTimeObj, . DAYNUMS , reqDayOf, 'lundi' .

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')
+2

All Articles