The Python datetime.isocalendar()
method returns a tuple (ISO_year, ISO_week_number, ISO_weekday)
for the given datetime
object. Is there a corresponding inverse function? If not, is there an easy way to compute a date given a year, week number and day of the week?
views:
520answers:
3
+1
A:
EDIT: ignore this, the edge cases are a pain. Go with Ben's solution.
Ok, on closer inspection I noticed that strptime
has %W
and %w
parameters, so the following works:
def fromisocalendar(y,w,d):
return datetime.strptime( "%04dW%02d-%d"%(y,w-1,d), "%YW%W-%w")
A couple of gotchas: The ISO week number starts at 1
, while %W
starts at 0
. The ISO week day starts at 1
(Monday), which is the same as %w
, so Sunday would probably have to be 0
, not 7
...
Tom
2008-11-20 03:56:10
Which version are you using?, I was testing on 2.4.2 and didn't work for me, found http://bugs.python.org/issue1045381 but says it's done on 2.3
Vinko Vrsalovic
2008-11-20 03:58:13
I'm using 2.5.2, %W is working, not sure about %U.
Tom
2008-11-20 04:18:29
This looks like you answered it. Why not accept your answer?
S.Lott
2008-11-20 12:17:57
AFAIK S.O. won't let you accept your own answers...
Tom
2008-11-23 06:28:06
@Tom: S.O. does let you accept your own answers. See this discussion on meta: http://meta.stackoverflow.com/questions/9933/is-there-a-convention-for-accepting-my-own-answer-to-my-own-question
GreenMatt
2010-02-11 07:10:33
@GreenMatt, yeah, that feature's new since I made that comment. And this answer isn't as good as Ben's anyway.
Tom
2010-02-17 09:22:14
@Tom: Oops! Didn't catch that this was from '08.
GreenMatt
2010-02-17 13:54:19
+1
A:
Note that %W is the week # (0-53) which is NOT THE SAME as the ISO week (1-53). There will be edge cases where %W will not work.
I sort of noted that in my answer above, any chance you could expand on what those edge cases would be?
Tom
2008-12-20 21:24:19
+4
A:
I recently had to solve this problem myself, and came up with this solution:
import datetime
def iso_year_start(iso_year):
"The gregorian calendar date of the first day of the given ISO year"
fourth_jan = datetime.date(iso_year, 1, 4)
delta = datetime.timedelta(fourth_jan.isoweekday()-1)
return fourth_jan - delta
def iso_to_gregorian(iso_year, iso_week, iso_day):
"Gregorian calendar date for the given ISO year, week and day"
year_start = iso_year_start(iso_year)
return year_start + datetime.timedelta(iso_day-1, 0, 0, 0, 0, 0, iso_week-1)
A few test cases:
>>> iso = datetime.date(2005, 1, 1).isocalendar()
>>> iso
(2004, 53, 6)
>>> iso_to_gregorian(*iso)
datetime.date(2005, 1, 1)
>>> iso = datetime.date(2010, 1, 4).isocalendar()
>>> iso
(2010, 1, 1)
>>> iso_to_gregorian(*iso)
datetime.date(2010, 1, 4)
>>> iso = datetime.date(2010, 1, 3).isocalendar()
>>> iso
(2009, 53, 7)
>>> iso_to_gregorian(*iso)
datetime.date(2010, 1, 3)
Ben James
2009-11-09 09:57:08
Can you clarify the significance of the 4th of January? Is there a description of the ISO calendar standard somewhere that's appropriate?
Tom
2009-11-10 05:42:30
Tom: from the formal ISO definition of week 1 (the week containing the first Thursday of the year) it follows that 4th January is the latest that week 1 can start.
Ben James
2009-11-10 09:32:51