29

If I have a certain week number (eg 51) and a given year (eg 2008), how do I find the date of the first Monday of that same week?

Many thanks

Rui Vieira
  • 5,253
  • 5
  • 42
  • 55

6 Answers6

35
>>> import time
>>> time.asctime(time.strptime('2008 50 1', '%Y %W %w'))
'Mon Dec 15 00:00:00 2008'

Assuming the first day of your week is Monday, use %U instead of %W if the first day of your week is Sunday. See the documentation for strptime for details.

Update: Fixed week number. The %W directive is 0-based so week 51 would be entered as 50, not 51.

Robert Gamble
  • 106,424
  • 25
  • 145
  • 137
  • 8
    Note that this function does not work correctly with isocalendar(). For instance, the first week of 2013 starts on 31 December (which is correct), but 2012-1 starts at 26 December (which should be 2 January). This is caused by the fact that %W uses its own implementation of week numbers, and isocalendar() uses the ISO standard. Use Vaidas' method below for a more accurate method. – ralphje Jan 02 '13 at 14:22
33

PEZ's and Gerald Kaszuba's solutions work under assumption that January 1st will always be in the first week of a given year. This assumption is not correct for ISO calendar, see Python's docs for reference. For example, in ISO calendar, week 1 of 2010 actually starts on Jan 4, and Jan 1 of 2010 is in week 53 of 2009. An ISO calendar-compatible solution:

from datetime import date, timedelta

def week_start_date(year, week):
    d = date(year, 1, 1)    
    delta_days = d.isoweekday() - 1
    delta_weeks = week
    if year == d.isocalendar()[0]:
        delta_weeks -= 1
    delta = timedelta(days=-delta_days, weeks=delta_weeks)
    return d + delta
Vaidas K.
  • 433
  • 5
  • 7
  • According to [this list](http://www.epochconverter.com/date-and-time/weeknumbers-by-year.php), Sep 3 (the day your comment was posted) was on the 36th week of 2013 in ISO calendar. `week_start_date(2013,36)` returns 2013-09-02. – Vaidas K. Sep 13 '13 at 10:44
  • `time.strftime('%W')` that day gave me `35`. Today it gives me `36`. Is that not right? – 2rs2ts Sep 13 '13 at 14:35
  • 3
    As noted in ralphje's comment on the accepted answer, %W uses its own implementation of week numbers, not the ISO standard. Note also that %W is 0-based. – Vaidas K. Oct 21 '13 at 14:40
17
from datetime import date, timedelta

def first_monday(year, week):
    d = date(year, 1, 4)  # The Jan 4th must be in week 1  according to ISO
    return d + timedelta(weeks=(week-1), days=-d.weekday())
minkwe
  • 501
  • 5
  • 6
  • 1
    works well, if you need it to determine the beginning of a current week - use datetime.datetime.now().isocalendar()[1] to determine current week of the year – robertzp May 19 '14 at 04:26
8

This seems to work, assuming week one can have a Monday falling on a day in the last year.

from datetime import date, timedelta

def get_first_dow(year, week):
    d = date(year, 1, 1)
    d = d - timedelta(d.weekday())
    dlt = timedelta(days = (week - 1) * 7)
    return d + dlt
gak
  • 32,061
  • 28
  • 119
  • 154
4

I have slightly modified the script of Vaidas K. in a way that it will return the beginning of the week and the end day of the week.

from datetime import datetime, date, timedelta

def weekbegend(year, week):
    """
    Calcul du premier et du dernier jour de la semaine ISO
    """
    d = date(year, 1, 1)    
    delta_days = d.isoweekday() - 1
    delta_weeks = week
    if year == d.isocalendar()[0]:
        delta_weeks -= 1
    # delta for the beginning of the week
    delta = timedelta(days=-delta_days, weeks=delta_weeks)
    weekbeg = d + delta
    # delta2 for the end of the week
    delta2 = timedelta(days=6-delta_days, weeks=delta_weeks)
    weekend = d + delta2
    return weekbeg, weekend

Soyou can use it that way.

weekbeg, weekend = weekbegend(2009, 1)
begweek = weekbeg.strftime("%A %d %B %Y")
endweek = weekend.strftime("%A %d %B %Y")
karlcow
  • 6,977
  • 4
  • 38
  • 72
0

Use the string formatting found in the time module. Detailed explanation of the formats used

>>> import time
>>> time.strptime("51 08 1","%U %y %w")
(2008, 12, 22, 0, 0, 0, 0, 357, -1)

The date returned is off by one week according to the calendar on my computer, maybe that is because weeks are indexed from 0?

Algorias
  • 3,043
  • 5
  • 22
  • 16