Получить дату от номера недели

Пожалуйста, что не так с моим кодом:

import datetime
d = "2013-W26"
r = datetime.datetime.strptime(d, "%Y-W%W")
print(r)

Дисплей "2013-01-01 00:00:00", спасибо.

8 ответов

Решение

Недельного номера недостаточно, чтобы сгенерировать дату; вам нужен день недели. Добавить по умолчанию:

import datetime
d = "2013-W26"
r = datetime.datetime.strptime(d + '-0', "%Y-W%W-%w")
print(r)

-0 а также -%w pattern говорит парсеру выбрать воскресенье на этой неделе. Это выводит:

2013-07-07 00:00:00

Вы можете выбрать свой собственный день недели, какой бы ни подходил к вашему варианту использования; %W шаблон базы недели с понедельника, так что, возможно, -1 здесь лучше по умолчанию.

Увидеть strftime() а также strptime() раздел поведения в документации, сноска 4:

При использовании с strptime() метод, %U а также %W используются только в расчетах, когда указаны день недели и год.

В Python 3.8 есть удобный datetime.date.fromisocalendar:

>>> from datetime import date
>>> date.fromisocalendar(2020, 1, 1)  # (year, week, day of week)
datetime.date(2019, 12, 30, 0, 0)

В более старых версиях Python (3.7-) для расчета можно использовать информацию из datetime.date.isocalendar чтобы вычислить неделю недель в соответствии с ISO8601:

from datetime import date, timedelta

def monday_of_calenderweek(year, week):
    first = date(year, 1, 1)
    base = 1 if first.isocalendar()[1] == 1 else 8
    return first + timedelta(days=base - first.isocalendar()[2] + 7 * (week - 1))

Оба работают также с datetime.datetime.

Для завершения других ответов - если вы используете номера недель ISO, эта строка подходит (чтобы получить понедельник для данного номера недели ISO):

import datetime
d = '2013-W26'
datetime.datetime.strptime(d + '-1', '%G-W%V-%u')
print(r)

%G, %V, %u являются эквивалентами ISO %Y, %W, %w, так что это выводит:

2013-06-24 00:00:00

Доступен в Python 3.6+; из документов.

import datetime
res = datetime.datetime.strptime("2018 W30 w1", "%Y %W w%w")
print res

Добавление 1 в качестве дня недели даст точное начало текущей недели. Добавление timedelta(days=6) даст вам конец недели.

datetime.datetime(2018, 7, 23)

Если кто-то ищет простую функцию, которая возвращает даты всех рабочих дней (пн-пт) из номера недели, подумайте об этом (на основе принятого ответа )

      import datetime

def weeknum_to_dates(weeknum):
    return [datetime.datetime.strptime("2021-W"+ str(weeknum) + str(x), "%Y-W%W-%w").strftime('%d.%m.%Y') for x in range(-5,0)]

weeknum_to_dates(37)

Выход:

      ['17.09.2021', '16.09.2021', '15.09.2021', '14.09.2021', '13.09.2021']

Если у вас есть годовой номер недели, просто добавьте количество недель к первому дню года.

>>> import datetime
>>> from dateutil.relativedelta import relativedelta

>>> week = 40
>>> year = 2019
>>> date = datetime.date(year,1,1)+relativedelta(weeks=+week)
>>> date
datetime.date(2019, 10, 8)

Другое решение, которое сработало для меня, принимает данные серии, а неstrptimeпринимает только однострочные значения:

      #fw_to_date
import datetime
import pandas as pd

# fw is input in format 'YYYY-WW'
# Add weekday number to string 1 = Monday
fw = fw + '-1'
# dt is output column 
# Use %G-%V-%w if input is in ISO format
dt = pd.to_datetime(fw, format='%Y-%W-%w', errors='coerce')

Вот удобная функция, включающая проблему с нулевой неделей.

Другие вопросы по тегам