5

Following this answer I tried to get the date for last Thursday of the current month. But my code doesn't get out of loop.

from datetime import datetime
from dateutil.relativedelta import relativedelta, TH

todayte = datetime.today()
cmon = todayte.month

nthu = todayte
while nthu.month == cmon:
    nthu += relativedelta(weekday=TH(1))
    #print nthu.strftime('%d%b%Y').upper()
Community
  • 1
  • 1
Frash
  • 724
  • 1
  • 10
  • 19

11 Answers11

5

Looking at the documentation of relativedelta

Notice that if the calculated date is already Monday, for example, using (0, 1) or (0, -1) won’t change the day.

If nthu is already Thursday then adding TH(1) or TH(-1) won't have any effect but result in the same date and that's why your loop is running infinitely.

I will assume maximum 5 weeks in a month and do it like following:

todayte = datetime.today()
cmon = todayte.month

for i in range(1, 6):
    t = todayte + relativedelta(weekday=TH(i))
    if t.month != cmon:
        # since t is exceeded we need last one  which we can get by subtracting -2 since it is already a Thursday.
        t = t + relativedelta(weekday=TH(-2))
        break
AKS
  • 18,983
  • 3
  • 43
  • 54
3

Based on Adam Smith's answer on How can I get the 3rd Friday of a month in Python?, you can get the date of the last Thursday of the current month as follows:

import calendar
import datetime

def get_thursday(cal,year,month,thursday_number):
    '''
    For example, get_thursday(cal, 2017,8,0) returns (2017,8,3) 
    because the first thursday of August 2017 is 2017-08-03
    '''
    monthcal = cal.monthdatescalendar(year, month)
    selected_thursday = [day for week in monthcal for day in week if \
                    day.weekday() == calendar.THURSDAY and \
                    day.month == month][thursday_number]
    return selected_thursday

def main():
    '''
    Show the use of get_thursday()
    '''
    cal = calendar.Calendar(firstweekday=calendar.MONDAY)
    today = datetime.datetime.today()
    year = today.year
    month = today.month
    date = get_thursday(cal,year,month,-1) # -1 because we want the last Thursday 
    print('date: {0}'.format(date)) # date: 2017-08-31        

if __name__ == "__main__":
    main()
Franck Dernoncourt
  • 77,520
  • 72
  • 342
  • 501
2

You can do something like this:

import pandas as pd
from dateutil.relativedelta import relativedelta, TH

expiry_type = 0
today = pd.datetime.today()
expiry_dates = []

if expiry_type == 0:
    # Weekly expiry
    for i in range(1,13):
         expiry_dates.append((today + relativedelta(weekday=TH(i))).date())
else:
    # Monthly expiry
    for i in range(1,13):
        x = (today + relativedelta(weekday=TH(i))).date()
        y = (today + relativedelta(weekday=TH(i+1))).date()
        if x.month != y.month :
            if x.day > y.day :
                expiry_dates.append(x)

print(expiry_dates)
codebraker
  • 98
  • 10
1

You should pass 2 to TH instead of 1, as 1 doesn't change anything. Modify your code to:

while (nthu + relativedelta(weekday=TH(2))).month == cmon:
    nthu += relativedelta(weekday=TH(2))

print nthu.strftime('%d-%b-%Y').upper()
# prints 26-MAY-2016

Note that I modified the loop's condition in order to break in the last occurrence of the day on the month, otherwise it'll break in the next month (in this case, June).

Maroun
  • 94,125
  • 30
  • 188
  • 241
  • 1
    This will fail if initial value of `nthu` is `23-MAY-2016`. or any day in the same week of last thursday. – AKS May 02 '16 at 06:32
1
from datetime import datetime , timedelta

todayte = datetime.today()
cmon = todayte.month

nthu = todayte
while todayte.month == cmon:
    todayte += timedelta(days=1)
    if todayte.weekday()==3: #this is Thursday 
        nthu = todayte
print nthu
Ohad the Lad
  • 1,889
  • 1
  • 15
  • 24
1

You can also use calendar package. Access the calendar in the form of monthcalendar. and notice that, the Friday is the last day of a week.

import calendar
import datetime
now = datetime.datetime.now()
last_sunday = max(week[-1] for week in calendar.monthcalendar(now.year,
                                                              now.month))
print('{}-{}-{:2}'.format(now.year, calendar.month_abbr[now.month],
                              last_sunday))
Hooting
  • 1,681
  • 11
  • 20
1

I think this will be fastest perhaps:

end_of_month = datetime.datetime.today() + relativedelta(day=31)
last_thursday = end_of_month + relativedelta(weekday=TH(-1))
DrBug
  • 2,004
  • 2
  • 20
  • 21
1

This code can be used in python 3.x for finding last Thursday of current month.

import datetime
dt = datetime.datetime.today()
def lastThurs(dt):
    currDate, currMth, currYr = dt, dt.month, dt.year
    for i in range(31):
        if currDate.month == currMth and currDate.year == currYr and currDate.weekday() == 3:
            #print('dt:'+ str(currDate))
            lastThuDate = currDate
        currDate += datetime.timedelta(1)

    return lastThuDate
Artemis
  • 2,553
  • 7
  • 21
  • 36
0
import datetime
def get_thursday(_month,_year):
    for _i in range(1,32):
        if _i > 9:
            _dateStr = str(_i)
        else:
            _dateStr = '0' + str(_i)
        _date = str(_year) + '-' + str(_month) + '-' + _dateStr
        try:
            a = datetime.datetime.strptime(_date, "%Y-%m-%d").strftime('%a')
        except:
             continue
        if a == 'Thu':
            _lastThurs = _date
    return _lastThurs

x = get_thursday('05','2017')
print(x)
Kurnal
  • 16
  • When answering an old question, your answer would be much more useful to other StackOverflow users if you included some context to explain how your answer helps, particularly for a question that already has an accepted answer. See: [How do I write a good answer](https://stackoverflow.com/help/how-to-answer). – David Buck Nov 30 '19 at 17:40
0

It is straightforward fast and easy to understand, we take the first of every month and then subtract it by 3 coz 3 is Thursday weekday number and then multiply it by either 4 and check if it is in the same month if it is then that is last Thursday otherwise we multiply it with 3 and we get our last Thursday

import datetime as dt

from datetime import timedelta

#start is the first of every month

start = dt.datetime.fromisoformat('2022-08-01')

if start.month == (start + timedelta((3 - start.weekday()) + 4*7)).month:

  exp = start + timedelta((3 - start.weekday()) + 4*7)

else:

  exp = start + timedelta((3 - start.weekday()) + 3*7)
0

You can use Calendar to achieve your result. I find it simple.

import calendar
import datetime

testdate= datetime.datetime.now()
weekly_thursday=[]
for week in calendar.monthcalendar(testdate.year,testdate.month):
    if week[3] != 0:
        weekly_thursday.append(week[3])
weekly_thursday

The list weekly_thursday will have all the Thursdays from the month.

weekly_thursday[-1] will give you the last Thursday of the month.


testdate : datetime.datetime(2022, 9, 9, 6, 35, 16, 752465)
weekly_thursday : [1, 8, 15, 22, 29]
weekly_thursday [-1]:29