1

I'm trying to get a list with days in a given week. I can get the year and week.

E.g.:

>>> year, week, dow = datetime.today().isocalendar()
>>> week
>>> 39

I'd like to get the 7 days in the week 39. For this year, 2015, I would get

[21, 22, 23, 24, 25, 26, 27]

As shown here

Note

I've found lot's of questions asking for:

This is not a duplicate, I don't need the last 7 days and I already have the current week number.

I need to get the 7 days in a given week, in this case, week 39. Thanks for your time.

Community
  • 1
  • 1
Gocht
  • 9,924
  • 3
  • 42
  • 81

3 Answers3

1

The difficulty with the isocalendar is that it's not really counting day-of-month. Therefore you have to translate back in order to get that. strptime can help:

year, week, dow = datetime.today().isocalendar()
result = [datetime.strptime(str(year) + "-" + str(week-1) + "-" + str(x), "%Y-%W-%w").day for x in range(1,7)]

What we are doing here is constructing a string that striptime can understand, starting with a week back (to account for counting from 0 versus 1) and starting at the start of the week (Monday, which is 1) and constructing a datetime for each day going forward 7 days.

By playing with week between those two statements (adding or removing weeks to get to month breaks) we can see that it works:

>>> year, week, dow = datetime.today().isocalendar()
>>> result = [datetime.strptime(str(year) + "-" + str(week-1) + "-" + str(x), "%Y-%W-%w").day for x in range(1,7)]
>>> result
[21, 22, 23, 24, 25, 26]
>>> year, week, dow = datetime.today().isocalendar()
>>> week = week + 1
>>> result = [datetime.strptime(str(year) + "-" + str(week-1) + "-" + str(x), "%Y-%W-%w").day for x in range(1,7)]
>>> result
[28, 29, 30, 1, 2, 3]

Now, to address the two very real concerns raised in comments we have to modify things a little bit:

year, week, dow = datetime.today().isocalendar()
week_start = datetime.strptime(str(year) + "-" + str(week-2) + "-0", "%Y-%W-%w")
result = [(week_start + timedelta(days=x)).day for x in range(0,7)]

This uses timedelta to increment. To make this work we have to back up across the week divide (hence the -2 instead of -1). Then the for comprehension adds an increasingly large time delta as we iterate through the week:

>>> year, week, dow = datetime.today().isocalendar()
>>> week_start = datetime.strptime(str(year) + "-" + str(week-2) + "-0", "%Y-%W-%w")
>>> result = [(week_start + timedelta(days=x)).day for x in range(0,7)]
>>> result
[20, 21, 22, 23, 24, 25, 26]
>>> year, week, dow = datetime.today().isocalendar()
>>> week = week + 1
>>> week_start = datetime.strptime(str(year) + "-" + str(week-2) + "-0", "%Y-%W-%w")
>>> result = [(week_start + timedelta(days=x)).day for x in range(0,7)]
>>> result
[27, 28, 29, 30, 1, 2, 3]
Nathaniel Ford
  • 20,545
  • 20
  • 91
  • 102
  • It's returning 6 days. I know isocalendar consider monday as 1, but I have been working with weekday from datetime which consider Monday as 0. How can this fit to work with Monday 0 and Sunday 6? – Gocht Sep 21 '15 at 23:34
  • Check the update! See if that addresses your concern. – Nathaniel Ford Sep 21 '15 at 23:47
  • It's pretty close dude, I work with Monday as 0 I will try to get a list wirh dates from Monday to Sunday. I can see you are returning from Sunday to Saturday. In the link I provided [this](http://www.timeanddate.com/calendar/index.html?country=18&year=) week are counted from mon to sun, currently in week 39 as in my answer, is that possible? – Gocht Sep 21 '15 at 23:54
  • I'm sure it's just a matter of adjusting the 'dow' offset. To effectively bridge from where you're using it to the code snippets above, you'd need to provide an example of what your expected inputs and outputs are. – Nathaniel Ford Sep 21 '15 at 23:59
  • Now I will try to adjust it to get not only de date number, but the full date. – Gocht Sep 22 '15 at 00:02
1

of course can be improved, but works it seems....

def days_of_the_current_numbered_week():

    import datetime
    import  calendar

     # dictionary of days of the week
    days = {   0 :  "Sunday",
            1 : "Monday",
            2 : "Tuesday",
            3 : "Wednesday",
            4 : "Thursday",
            5 : "Friday",
            6 : "Saturday",
            7 : "Sunday" }


    allYearDates = []
    w_days_numbers = []

    # today
    now = datetime.datetime.now()

    # get current values for year, mon, day
    year = int(now.year)
    mon = int(now.month)
    day = int(now.day)

    # get this week number
    # thisWeekN = datetime.date(year, mon, day).isocalendar()[1]

    thisWeekN = datetime.datetime.utcnow().isocalendar()[1]

    # get Calendar obect
    c = calendar.Calendar()

    # get all the days for this year in a list
    for i in range(1, 13):
        for d in c.itermonthdays2(year, i):
            allYearDates.append(d)
    # in the first seven days could be 0's as days, to continue week #'s
    # these tuples need to be removed to produce accurate mapping between
    # weeks and 7 days chunks
    first_seven = allYearDates[:7]
    no_zeros =  [ d for d in first_seven if  d[0] != 0]

    allYearDates = no_zeros + allYearDates[8:]
    # divid all days of year list into one week chuncks
    lt7 = listChunks(allYearDates,7)

    # get days for this week number
    thisWeekDays = lt7[thisWeekN]

    # remove right part of the days tuple
    sevenDaysL = [x for x,y in  thisWeekDays]

    # get week day numbers  1-7 for this week
    for d in sevenDaysL:
        w_days_numbers.append(datetime.date(year, mon, d).isocalendar()[2])

    # zip week day numbers with the dates
    zl = zip(sevenDaysL, w_days_numbers)

    # month number prefix
    if thisWeekN == 1:
        prefix = 'st'
    elif thisWeekN == 2:
        prefix = 'nd'
    elif thisWeekN == 3:
        prefix = 'rd'
    else:
        prefix= "th"

    # print heading
    print("\n 7 days of this {}{} week: of the year {}"
          .format(thisWeekN,prefix, year))
    print("-------------------------------------------")

    # print results
    for el in  list(zl):
        if el[0] == day:
            print("* {} *  {}".format(el[0],days[el[1]]))
        else:
            print("  {}    {}".format(el[0],days[el[1]]))

    mytime= datetime.datetime.now().strftime("%Y-%m-%d %H-%M")
    print("================")
    print(mytime)

days_of_the_current_numbered_week()

OUTPUT

7 days of this 39th week: of the year 2015

17 Thursday

18 Friday

19 Saturday

20 Sunday

21 Monday

22 Tuesday

23 Wednesday

LetzerWille
  • 5,355
  • 4
  • 23
  • 26
0

First, find the day of the week on which the year begins. This is easy to find on the internet. This gives you the offset of week 1 in the year.

Notice that the week will let you compute the day of the year, in the range 1-365. Week 01 starts on day 1; week 02 starts on day 8, etc.

start_day = 1 + (week-1) * 7 - offset

First, find the day of the week on which the year begins. This is easy to find on the internet. This gives you the offset of week 1 in the year.

now that you have the start day, you can easily find the day of the month. It's a little tedious to subtract the days in each month until you get into range of the given month, but it's straightforward.

Does this get you going? I've done this in English description, since you haven't given us any code to debug.

Prune
  • 76,765
  • 14
  • 60
  • 81
  • Sometimes 1st Jan is not in the first week as you can see [here](http://www.epochconverter.com/date-and-time/weeknumbers-by-year.php?year=2010) – Gocht Sep 21 '15 at 23:03
  • Right -- hence computing the offset. – Prune Sep 21 '15 at 23:12