Reputation: 10256
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
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
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
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