Как перебирать время в течение нескольких дней, часов, недель и месяцев на Python?
Как я могу перебирать промежуток времени по дням, часам, неделям или месяцам?
Что-то вроде:
for date in foo(from_date, to_date, delta=HOURS):
print date
Где foo - это функция, возвращающая итератор. Я смотрел на модуль календаря, но это работает только в течение одного года или месяца, а не между датами.
Ответы
Ответ 1
Используйте dateutil и его реализацию rrule, например:
from dateutil import rrule
from datetime import datetime, timedelta
now = datetime.now()
hundredDaysLater = now + timedelta(days=100)
for dt in rrule.rrule(rrule.MONTHLY, dtstart=now, until=hundredDaysLater):
print dt
Выход
2008-09-30 23:29:54
2008-10-30 23:29:54
2008-11-30 23:29:54
2008-12-30 23:29:54
Замените ЕЖЕМЕСЯЧНО любой из ГОДОВ, ЕЖЕМЕСЯЧНО, ЕЖЕНЕДЕЛЬНО, ЕЖЕДНЕВНО, ЧАСОВ, МИНУТЫ ИЛИ ВТОРОЕ. Замените dtstart и до тех пор, пока вы не захотите использовать любой объект datetime.
Этот рецепт имеет преимущество для работы во всех случаях, включая ЕЖЕМЕСЯЧНО. Только оговорка, которую я могу найти, состоит в том, что если вы пропустите номер дня, который не существует на протяжении всех месяцев, он пропускает эти месяцы.
Ответ 2
Я не думаю, что есть метод в библиотеке Python, но вы можете легко создать его самостоятельно, используя datetime module:
from datetime import date, datetime, timedelta
def datespan(startDate, endDate, delta=timedelta(days=1)):
currentDate = startDate
while currentDate < endDate:
yield currentDate
currentDate += delta
Затем вы можете использовать его следующим образом:
>>> for day in datespan(date(2007, 3, 30), date(2007, 4, 3),
>>> delta=timedelta(days=1)):
>>> print day
2007-03-30
2007-03-31
2007-04-01
2007-04-02
Или, если вы хотите уменьшить свою дельту:
>>> for timestamp in datespan(datetime(2007, 3, 30, 15, 30),
>>> datetime(2007, 3, 30, 18, 35),
>>> delta=timedelta(hours=1)):
>>> print timestamp
2007-03-30 15:30:00
2007-03-30 16:30:00
2007-03-30 17:30:00
2007-03-30 18:30:00
Ответ 3
Для повторения нескольких месяцев вам нужен другой рецепт, поскольку timedeltas не может выразить "один месяц".
from datetime import date
def jump_by_month(start_date, end_date, month_step=1):
current_date = start_date
while current_date < end_date:
yield current_date
carry, new_month = divmod(current_date.month - 1 + month_step, 12)
new_month += 1
current_date = current_date.replace(year=current_date.year + carry,
month=new_month)
(NB: вы должны вычесть 1 из месяца для операции модуля, а затем добавить его обратно к new_month
, так как месяцы в datetime.date
начинаются с 1.)
Ответ 4
Месячный итерационный подход:
def months_between(date_start, date_end):
months = []
# Make sure start_date is smaller than end_date
if date_start > date_end:
tmp = date_start
date_start = date_end
date_end = tmp
tmp_date = date_start
while tmp_date.month <= date_end.month or tmp_date.year < date_end.year:
months.append(tmp_date) # Here you could do for example: months.append(datetime.datetime.strftime(tmp_date, "%b '%y"))
if tmp_date.month == 12: # New year
tmp_date = datetime.date(tmp_date.year + 1, 1, 1)
else:
tmp_date = datetime.date(tmp_date.year, tmp_date.month + 1, 1)
return months
Больше кода, но он отлично справится с длительными периодами времени, проверяя, что данные даты в порядке...
Ответ 5
Я достиг этого, используя библиотеки pandas и datetime следующим образом. Это было гораздо удобнее для меня.
import pandas as pd
from datetime import datetime
DATE_TIME_FORMAT = '%Y-%m-%d %H:%M:%S'
start_datetime = datetime.strptime('2018-05-18 00:00:00', DATE_TIME_FORMAT)
end_datetime = datetime.strptime('2018-05-23 13:00:00', DATE_TIME_FORMAT)
timedelta_index = pd.date_range(start=start_datetime, end=end_datetime, freq='H').to_series()
for index, value in timedelta_index.iteritems():
dt = index.to_pydatetime()
print(dt)
Ответ 6
Эта библиотека предоставляет удобный инструмент календаря: mxDateTime, этого должно быть достаточно:)
Ответ 7
Вы должны изменить эту строку, чтобы сделать эту работу правильно:
current_date = current_date.replace(year = current_date.year + carry, month = new_month, day = 1)
;)