Получить номера недели между двумя датами с Python

Я хотел бы найти наиболее питонический способ вывести список номеров недели между двумя датами.

Например:

вход

start = datetime.date(2011, 12, 25) 
end = datetime.date(2012, 1, 21)

выход

find_weeks(start, end)
>> [201152, 201201, 201202, 201203]

Я боролся с использованием библиотеки datetime с небольшим успехом

5 ответов

Решение

Что-то в строках (обновление: удалена менее читаемая опция)

import datetime

def find_weeks(start,end):
    l = []
    for i in range((end-start).days + 1):
        d = (start+datetime.timedelta(days=i)).isocalendar()[:2] # e.g. (2011, 52)
        yearweek = '{}{:02}'.format(*d) # e.g. "201152"
        l.append(yearweek)
    return sorted(set(l))

start = datetime.date(2011, 12, 25) 
end = datetime.date(2012, 1, 21)

print(find_weeks(start,end)[1:]) # [1:] to exclude first week.

Возвращает

['201152', '201201', '201202', '201203']

Чтобы включить первую неделю (201151) просто удалите [1:] после вызова функции

Использование панд

import pandas as pd

dates=pd.date_range(start=start,end=end,freq='W')
date_index=dates.year.astype(str)+dates.weekofyear.astype(str).str.zfill(2)
date_index.tolist()

.isocalendar() Ваш друг здесь - он возвращает кортеж (year, week of year, day of week), Мы используем это для сброса даты начала к началу недели, а затем добавляем каждую неделю до тех пор, пока мы не передадим дату окончания:

import datetime


def find_weeks(start_date, end_date):
    subtract_days = start_date.isocalendar()[2] - 1
    current_date = start_date + datetime.timedelta(days=7-subtract_days)
    weeks_between = []
    while current_date <= end_date:
        weeks_between.append(
            '{}{:02d}'.format(*current_date.isocalendar()[:2])
        )
        current_date += datetime.timedelta(days=7)
    return weeks_between

start = datetime.date(2011, 12, 25)
end = datetime.date(2012, 1, 21)

print(find_weeks(start, end))

Это печатает

['201152', '201201', '201202', '201203']

Я предлагаю вам следующее простое для чтения решение:

import datetime

start = datetime.date(2011, 12, 25) 
end = datetime.date(2012, 1, 21)

def find_weeks(start, end):
    l = []
    while (start.isocalendar()[1] != end.isocalendar()[1]) or (start.year != end.year):
        l.append(start.isocalendar()[1] + 100*start.year)
        start += datetime.timedelta(7)
    l.append(start.isocalendar()[1] + 100*start.year)
    return (l[1:])


print(find_weeks(start, end))

>> [201252, 201201, 201202, 201203]

я предпочитаюarrowстильное решение здесь (может понадобитьсяpip install arrow):

      import arrow

start = arrow.get('2011-12-25')
end = arrow.get('2012-01-21')
weeks = list(arrow.Arrow.span_range('week', start, end))

результат выглядит так:

      >> from pprint import pprint
>> pprint(weeks[1:])
[(<Arrow [2011-12-19T00:00:00+00:00]>,
  <Arrow [2011-12-25T23:59:59.999999+00:00]>),
 (<Arrow [2011-12-26T00:00:00+00:00]>,
  <Arrow [2012-01-01T23:59:59.999999+00:00]>),
 (<Arrow [2012-01-02T00:00:00+00:00]>,
  <Arrow [2012-01-08T23:59:59.999999+00:00]>),
 (<Arrow [2012-01-09T00:00:00+00:00]>,
  <Arrow [2012-01-15T23:59:59.999999+00:00]>),
 (<Arrow [2012-01-16T00:00:00+00:00]>,
  <Arrow [2012-01-22T23:59:59.999999+00:00]>)]

оттуда вы можете изменить вывод, чтобы он соответствовал году и номеру недели.

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