开发者

Generating all dates within a given range in python

I have two string variables which contain dates in 开发者_高级运维yyyy-mm-dd format as follows :

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

I want to write code that generates all dates in the range date1 to date2. How can this be done in Python?


Pandas is great for time series in general, and has direct support both for date ranges and date parsing (it's automagic).

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

It also has lots of options to make life easier. For example if you only wanted weekdays, you would just swap in bdate_range.

See https://pandas.pydata.org/pandas-docs/stable/user_guide/timeseries.html#generating-ranges-of-timestamps


Dates can be compared to each other just like numbers, and you can do date-related math with the datetime.timedelta object. There's no reason to use dateutil here, and there's no reason to hard-code the number of iterations a la 'range(9)'. This really becomes similar to how you'd deal with plain old numbers.

>>> 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
>>> 


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

Since dateutil is not a standard library, you will have to install it as a separate package. See the documentation for further details regarding the format (especially dayfirst and yearfirst switches).


Assuming your dates are already as a datetime.date class you can use .fromordinal and .toordinal to create this 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())]

The result is exclusive end_date. Use end_date.toordinal() + 1 for a range inclusive end_date.


You can easily turn code above into a generator by

from datetime import date


def date_range(x, y, inclusive=False):

    inclusive_nr = 1 if inclusive else 0

    if isinstance(x, date) and isinstance(y, date):

        for i in range(x.toordinal(), y.toordinal() + inclusive_nr):
            yield date.fromordinal(i)

    else:
        raise TypeError("Parameters x and y should be dates.")

Example

>>> from datetime import date
>>> end_date = date(2011, 5, 10)
>>> start_date = date(2011, 5, 3)
>>> [str(d) for d in date_range(start_date, end_date, inclusive=True)]
['2011-05-03', '2011-05-04', '2011-05-05', '2011-05-06', '2011-05-07', '2011-05-08', '2011-05-09', '2011-05-10']


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

for python 3 use range instead of xrange.


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)


I like this one because it is intuitive and it gives an array of date strings.

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)]
)


>>> 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

I'm not too sure whether the parsing of the strings was integral or just the way you started the question. If so, please disregard the answer as oversimplified


import pandas as pd
date1 = '2011-05-03'
date2 = '2011-05-10'
pd.date_range(start = date1,end = date2)
0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜