122
day = "13/Oct/2013"
print("Parsing :",day)
day, mon, yr= day.split("/")
sday = yr+" "+day+" "+mon
myday = time.strptime(sday, '%Y %d %b')
Sstart = yr+" "+time.strftime("%U",myday )+" 0"
Send = yr+" "+time.strftime("%U",myday )+" 6"
startweek = time.strptime(Sstart, '%Y %U %w')
endweek = time.strptime(Send, '%Y %U %w')
print("Start of week:",time.strftime("%a, %d %b %Y",startweek))
print("End of week:",time.strftime("%a, %d %b %Y",endweek))
print("Data entered:",time.strftime("%a, %d %b %Y",myday))

out:
Parsing : 13/Oct/2013
Start of week: Sun, 13 Oct 2013
End of week: Sat, 19 Oct 2013
Sun, 13 Oct 2013

Learned python in the past 2 days and was wondering if there is a cleaner way to do this.This method works...it just looks ugly and It seems silly to have to create a new time variable for each date, and that there should be a way to offset the given date to the start and end of the week through a simple call but i have been unable to find anything on the internet or documentation that looks like it would work.

shadowtdt09
  • 1,279
  • 2
  • 8
  • 6
  • 1
    This isn't a programming critique, but I've never seen anyone write a date like "13/Oct/2013". Are you sure that's how you want to parse the input? – Brionius Oct 07 '13 at 02:46
  • @Brionius I don't know where OP is from, but here in my country this format is quite common (and maybe even the most common). – Hyperboreus Oct 07 '13 at 03:00
  • 5
    Huh - how interesting. I've never seen non-numerical segments in a slash-based date notation. – Brionius Oct 07 '13 at 03:02

5 Answers5

254

Use the datetime module.

This will yield start and end of week (from Monday to Sunday):

from datetime import datetime, timedelta

day = '12/Oct/2013'
dt = datetime.strptime(day, '%d/%b/%Y')
start = dt - timedelta(days=dt.weekday())
end = start + timedelta(days=6)
print(start)
print(end)

EDIT:

print(start.strftime('%d/%b/%Y'))
print(end.strftime('%d/%b/%Y'))
orokusaki
  • 55,146
  • 59
  • 179
  • 257
Hyperboreus
  • 31,997
  • 9
  • 47
  • 87
  • 2
    is start and end a datetime object, or is it a string. I need the output be formatted like my question originally stated and i tried using ,datetime.strftime("%a, %d %b %Y",end), however it said end was a sting not a datetime object. – shadowtdt09 Oct 07 '13 at 03:21
  • 1
    Thanks for the help, one last question, is there any way to change the start of the week to sunday instead of monday? – shadowtdt09 Oct 07 '13 at 03:29
  • 25
    Just move the weekday one day around. Something like this `start = dt - timedelta(days = (dt.weekday() + 1) % 7)` should work. – Hyperboreus Oct 07 '13 at 03:31
  • how can addition and subtraction work if there is time component as well in day? Something like `day = '12/10/2013 13:43:43'` ? – Vineet Menon May 08 '14 at 07:24
  • AttributeError: module 'datetime' has no attribute 'strptime' – Saravanan Nandhan Mar 02 '18 at 12:41
  • @VineetMenon just replace the time part, so for example, `start = dt - timedelta(days=dt.weekday()).replace(hour=0, minute=0, second=0, microsecond=0)` to get 00:00 for monday. – gdvalderrama May 23 '18 at 15:20
  • 1
    @SaravananNandhan make sure you're importing datetime from datetime, not just datetime. So `from datetime import datetime` and NOT `import datetime` – gdvalderrama May 23 '18 at 15:21
52

Slight variation if you want to keep the standard time formatting and refer to the current day:

from datetime import date, timedelta

today = date.today()
start = today - timedelta(days=today.weekday())
end = start + timedelta(days=6)
print("Today: " + str(today))
print("Start: " + str(start))
print("End: " + str(end))
johnson
  • 3,729
  • 3
  • 31
  • 32
palamunder
  • 2,555
  • 1
  • 19
  • 20
  • Is there a way to like strafe through weeks? Like a delta value in the equation, as to ++the delta, you go back by one week each time. – ScipioAfricanus Mar 18 '22 at 22:41
  • 1
    Sure, just add 7 days to go forward `next_monday = start + timedelta(days=7)` or n*7 days for more weeks. Same to go back `last_monday = start - timedelta(days=7)` – palamunder Mar 21 '22 at 18:41
33

Use the pendulum module:

today = pendulum.now()
start = today.start_of('week')
end = today.end_of('week')
funnydman
  • 9,083
  • 4
  • 40
  • 55
ogeretal
  • 509
  • 4
  • 12
  • this is exactly what i needed – Raveen Beemsingh Sep 03 '19 at 05:17
  • 1
    ...that's exactly what you need as long as your week starts and ends on Sunday evening. Pendulum apparently has no way of setting the end of the week to be Saturday at 23:59:59. – Aaron C. de Bruyn Nov 26 '19 at 03:35
  • 12
    I found out about pendulum today. According to its [docs](https://pendulum.eustace.io/docs/#modifiers), true #ISO8601 week starts on Monday and ends on Sunday. It would have been a shame if this can't be changed. After some searching, I found [this](https://github.com/sdispater/pendulum/issues/78#issuecomment-565538992). So if you add `pendulum.week_starts_at(pendulum.SUNDAY)` and `pendulum.week_ends_at(pendulum.SATURDAY)`, you should be able to get the right dates using the `start_of()` and `end_of()` methods. I'm not sure if this is the way to go but it seems to be working in my tests. – Karthic Raghupathi May 07 '20 at 22:41
11

you can also use Arrow:

import arrow
now = arrow.now()
start_of_week = now.floor('week')
end_of_week = now.ceil('week')
Marcin
  • 179
  • 2
  • 14
Alon Gouldman
  • 3,025
  • 26
  • 29
1
pip install pendulum

import pendulum
 
today = pendulum.now()
 
start = today.start_of('week')
print(start.to_datetime_string())
 
end = today.end_of('week')
print(end.to_datetime_string())

found from here

Suraj Rao
  • 29,388
  • 11
  • 94
  • 103
  • [A code-only answer is not high quality](https://meta.stackoverflow.com/questions/392712/explaining-entirely-code-based-answers). While this code may be useful, you can improve it by saying why it works, how it works, when it should be used, and what its limitations are. Please [edit] your answer to include explanation and link to relevant documentation. – Muhammad Mohsin Khan Mar 12 '22 at 13:14