Генерация всех дат в заданном диапазоне в Python - PullRequest
20 голосов
/ 03 мая 2011

У меня есть две строковые переменные, которые содержат даты в формате гггг-мм-дд следующим образом:

date1 = '2011-05-03'
date2 = '2011-05-10'

Я хочу написать код, который генерирует все даты в диапазоне от даты1 до даты2. Как это можно сделать в Python?

Ответы [ 8 ]

27 голосов
/ 03 мая 2011

Даты можно сравнивать друг с другом так же, как числа, и вы можете выполнять математику, связанную с датой, с объектом datetime.timedelta.Нет никакой причины использовать dateutil здесь, и нет никакой причины жестко кодировать количество итераций а-ля 'range (9)'.Это действительно становится похоже на то, как вы будете иметь дело с простыми старыми числами.

>>> import datetime
>>> date1 = '2011-05-03'
>>> date2 = '2011-05-10'
>>> start = datetime.datetime.strptime(date1, '%Y-%m-%d')
>>> end = datetime.datetime.strptime(date2, '%Y-%m-%d')
>>> step = datetime.timedelta(days=1)
>>> while start <= end:
...     print start.date()
...     start += step
... 
2011-05-03
2011-05-04
2011-05-05
2011-05-06
2011-05-07
2011-05-08
2011-05-09
2011-05-10
>>> 
24 голосов
/ 27 октября 2014

Pandas отлично подходит для временных рядов в целом и имеет прямую поддержку как для диапазонов дат, так и для анализа дат (это автоматически).

import pandas as pd
date1 = '2011-05-03'
date2 = '2011-05-10'
mydates = pd.date_range(date1, date2).tolist()

У этого также есть много вариантов, чтобы облегчить жизнь. Например, если вы хотите только рабочие дни, вы просто должны поменять местами bdate_range.

См. http://pandas.pydata.org/pandas-docs/stable/timeseries.html#generating-ranges-of-timestamps

17 голосов
/ 03 мая 2011
from dateutil import rrule, parser

date1 = '2011-05-03'
date2 = '2011-05-10'

dates = list(rrule.rrule(rrule.DAILY,
                         dtstart=parser.parse(date1),
                         until=parser.parse(date2)))

print dates

Поскольку dateutil не является стандартной библиотекой, вам придется установить ее как отдельный пакет. См. Документацию для получения дополнительной информации о формате (особенно переключатели dayfirst и yearfirst).

6 голосов
/ 20 марта 2017

Предполагая, что ваши даты уже являются классом datetime.date, вы можете использовать .fromordinal и .toordinal для создания этого oneliner.

from datetime import date

start_date = date(2011, 5, 3)
end_date = date(2011, 5, 10)

[date.fromordinal(i) for i in range(start_date.toordinal(), end_date.toordinal())]

Результат эксклюзивный end_date.Используйте end_date.toordinal() + 1 для диапазона включительно end_date.

3 голосов
/ 22 марта 2016

Мне нравится этот, потому что он интуитивно понятен и дает массив строк даты.

import re
import datetime

def datetime_to_str_date(dt):
    return re.sub(r'\T.+$','', dt.isoformat())

start_date = datetime.datetime.strptime('2016-01-01', '%Y-%m-%d')
end_date = datetime.datetime.today()
num_of_days = (end_date - start_date).days

date_list = map(
        datetime_to_str_date, 
        [start_date + datetime.timedelta(days=x) for x in range(0, num_of_days)]
)
3 голосов
/ 03 мая 2011
import time

def dates_between(start, end):
  start_epoch = int(time.mktime(time.strptime(start, "%Y-%m-%d")))
  end_epoch = int(time.mktime(time.strptime(end, "%Y-%m-%d"))) + 1 #include end
  return range(start_epoch, end_epoch, 86400)
2 голосов
/ 03 мая 2011
import datetime
real_date1 = datetime.date(*[int(x) for x in date1.split('-')])
real_date2 = datetime.date(*[int(x) for x in date2.split('-')])
date_range =  real_date2 - real_date1
dates = list()
for days in xrange(date_range.days):
    dates.append(real_date1 + datetime.timedelta(days))

print dates
1 голос
/ 03 мая 2011
>>> for a in range(9):
...     print(datetime.date(2011, 05, 03) + datetime.timedelta(a))
...
2011-05-03
2011-05-04
2011-05-05
2011-05-06
2011-05-07
2011-05-08
2011-05-09
2011-05-10
2011-05-11

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...