Как перебирать промежуток времени после дней, часов, недель и месяцев в Python?


Как я могу перебирать промежуток времени после дней, часов, недель или месяцев?

что-то типа:

for date in foo(from_date, to_date, delta=HOURS):
    print date

где foo-функция, возвращающая итератор. Я смотрел на модуль календаря, но это работает только в течение одного конкретного года или месяца, а не между датами.

7   51   2008-09-30 19:35:22

7 ответов:

использовать 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, который вы хотите.

этот рецепт имеет преимущество для работы во всех случаях, в том числе ежемесячно. Единственное предостережение, которое я мог бы найти, это то, что если вы передаете номер дня, который не существует для всех месяцев, он пропускает этот месяц.

Я не думаю, что есть метод в библиотеке Python, но вы можете легко создать его самостоятельно с помощью datetime модуль:

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

для повторения в течение нескольких месяцев вам нужен другой рецепт, так как 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.dates начало в 1.)

месяц итерационный подход:

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

больше кода, но он будет отлично справляться с длительными периодами времени, проверяя, что данные даты в порядке...

Я достиг этого, используя панды и библиотеки 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)

эта библиотека предоставляет удобный инструмент календарь: mxDateTime, этого должно быть достаточно :)

вы должны изменить эту строку, чтобы сделать эту работу правильно:

current_date используется = current_date используется.заменить(год=current_date используется.год + перенос, месяц=new_month, день=1)

;)