Gocht
Gocht

Reputation: 10256

Days/dates in a given week

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.

Upvotes: 1

Views: 1623

Answers (3)

LetzerWille
LetzerWille

Reputation: 5658

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

Upvotes: 1

Nathaniel Ford
Nathaniel Ford

Reputation: 21220

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]

Upvotes: 1

Prune
Prune

Reputation: 77837

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.

Upvotes: 0

Related Questions