[Tutor] datetime: inverse of datetime.date.isocalendar()

Peter Otten __peter__ at web.de
Fri Jul 12 21:36:59 CEST 2013


elmar werling wrote:

> how to convert the tuble (iso_year, iso_week, iso_day) to a date object?
> 
> I have tried the following scipt, but the results are buggy
> 
> 
> import datetime
> 
> date_i = datetime.date(2013, 07, 12)
> date_iso = date_i.isocalendar()
> 
> year = str(date_iso[0])[2:]
> week = str(date_iso[1])
> day = str(date_iso[2])
> 
> date_string = year + week + day
> date_ii = datetime.datetime.strptime(date_string,'%y%W%w').date()
> 
> print date_i, date_iso, date_string, date_ii

Here's what I came up with:

import datetime

def ywd_to_date(year, week, weekday):
    """Convert (year, week, isoweekday) tuple to a datetime.date().

    >>> datetime.date(2013, 7, 12).isocalendar()
    (2013, 28, 5)
    >>> ywd_to_date(2013, 28, 5)
    datetime.date(2013, 7, 12)
    """
    first = datetime.date(year, 1, 1)
    first_year, _first_week, first_weekday = first.isocalendar()

    if first_year == year:
        week -= 1

    return first + datetime.timedelta(days=week*7+weekday-first_weekday)

if __name__ == "__main__":
    # perform an exhaustive adhoc test

    def iterdays(start=datetime.date(datetime.MINYEAR, 1, 1)):
        """Generate dates till the end of time aka MAXYEAR."""
        d = start
        one_day = datetime.timedelta(days=1)
        try:
            while True:
                yield d
                d += one_day
        except OverflowError:
            pass

    for d in iterdays():
        # does it round-trip?
        c = ywd_to_date(*d.isocalendar())
        assert d == c, d

I don't really understand what I'm doing here, but the test code makes me 
confident that it's correct ;)



More information about the Tutor mailing list