Получить дату из номера недели ISO в Python

Возможный дубликат:
Как лучше всего найти обратную функцию datetime.isocalendar()?

У меня есть год и номер недели по ISO 8601, и мне нужно перевести его в дату первого дня этой недели (понедельник). Как я могу это сделать?

datetime.strptime() принимает как %W, так и %U директива, но ни один из них не придерживается правил рабочего дня ISO 8601, которые datetime.isocalendar( ) использовать.

Обновление: Python 3.6 поддерживает %G , %V и %u также присутствуют в libc, что позволяет использовать однострочник:

>>> datetime.strptime('2011 22 1', '%G %V %u')
datetime.datetime(2011, 5, 30, 0, 0)

Обновление 2: Python 3.8 добавил метод fromisocalendar(), который стал еще более интуитивным:

>>> datetime.fromisocalendar(2011, 22, 1)
datetime.datetime(2011, 5, 30, 0, 0)

person Erik Cederstrand    schedule 04.05.2011    source источник
comment
Почему не элегантно? Другие варианты, которые вы найдете через Google, еще более уродливы.   -  person Andreas Jung    schedule 04.05.2011
comment
Я нашел связанный вопрос с хорошим ответом: заголовок stackoverflow.com/questions/304256/   -  person Erik Cederstrand    schedule 04.05.2011
comment
Я вижу упоминание о директиве %V в PHP strftime(), а также в libc strptime(), но, по-видимому, Python ее не реализует. Я пошел с решением по ссылке, которую я разместил выше.   -  person Erik Cederstrand    schedule 05.05.2011


Ответы (2)


%W считает, что первый понедельник приходится на неделю 1, но ISO определяет, что неделя 1 содержит 4 января. Итак, результат от

datetime.strptime('2011221', '%Y%W%w')

выключен на один раз, если первый понедельник и 4 января приходятся на разные недели. Последнее имеет место в том случае, если 4 января приходится на пятницу, субботу или воскресенье. Итак, должно работать следующее:

from datetime import datetime, timedelta, date
def tofirstdayinisoweek(year, week):
    ret = datetime.strptime('%04d-%02d-1' % (year, week), '%Y-%W-%w')
    if date(year, 1, 4).isoweekday() > 4:
        ret -= timedelta(days=7)
    return ret
person Uwe Kleine-König    schedule 04.05.2011

С модулем isoweek вы можете сделать это с помощью:

from isoweek import Week
d = Week(2011, 40).monday()
person gisle    schedule 07.10.2011
comment
Это, безусловно, самый практичный способ, особенно если вы много манипулируете ISO-неделями. - person gldnspud; 10.02.2015