PYTHON 3.8 date range

Question:

i trying to find all dates bettween two dates for example:
I have two dates 2019-09-21 and 2019-10-09, how can i get all dates between those like that:

2019-09-21
2019-09-22
2019-09-23
2019-09-24
....
....
2019-10-08
2019-10-09
Asked By: robotiaga

||

Answers:

The below code can help you.

from datetime import datetime, timedelta
start_date = datetime.strptime('2019-09-21', '%Y-%m-%d').date()
end_date = datetime.strptime('2019-10-09', '%Y-%m-%d').date()
while start_date <= end_date:
    print(start_date)
    start_date = start_date+timedelta(days=1)

Output

2019-09-21
2019-09-22
2019-09-23
2019-09-24
2019-09-25
2019-09-26
2019-09-27
2019-09-28
2019-09-29
2019-09-30
2019-10-01
2019-10-02
2019-10-03
2019-10-04
2019-10-05
2019-10-06
2019-10-07
2019-10-08
2019-10-09
Answered By: Karmveer Singh

A Pythonic way to do this is to create an iterator, something like:

from datetime import datetime, timedelta

class dater(object):
    def __init__(self, first, lastPlusOne, inclusiveEnd = False):
        # Store important stuff, adjusting end if you want it inclusive.

        self.__oneDay = timedelta(days = 1)
        self.__curr = datetime.strptime(first, "%Y-%m-%d").date()
        self.__term = datetime.strptime(lastPlusOne, "%Y-%m-%d").date()
        if inclusiveEnd:
            self.__term += self.__oneDay

    def __iter__(self):
        return self

    def __next__(self):
        return self.next()

    def next(self):
        # This is the meat. It checks to see if the generator is
        # exhausted and raises the correct exception if so. If not,
        # it saves the current, calculates the next, stores that
        # for the next time, then returns the saved current.

        if self.__curr >= self.__term:
            raise StopIteration()

        (cur, self.__curr) = (self.__curr, self.__curr + self.__oneDay)
        return cur

You can call it with something like (from your example):

for date in dater("2019-09-21", "2019-10-09", inclusiveEnd=True):
    print(date)

to get:

2019-09-21
2019-09-22
2019-09-23
2019-09-24
2019-09-25
: no need to show it all, trust me :-)
2019-10-08
2019-10-09

The advantage of using an iterator is that:

  • the code to use it becomes a very simple for loop, similar to Python’s many other methods; and
  • you can make the __init__ constructor arbitrarily complex (for example, accepting datetime or date variables as well as the current strings).

That last point bears some extra explanation. In the code that sets up the self.__curr (for example), you can use something like this:

if type(first) == type(date(2000, 1, 1)):        # copy a date.
    self.__curr = first
elif type(first) == type(datetime(2000, 1, 1)):  # extract date from datetime.
    self.__curr = first.date()
else:                                            # convert string.
    self.__curr = datetime.strptime(first, "%Y-%m-%d").date()

This will detect the source type and adjust behaviour so that you get a date regardless. If you do the same thing for the final date, you’ll get a truly adaptable iterator that can even start and end with different representations:

for mydate in dater("2000-01-01", datetime.now()):
    process_every_date_from_start_of_2000_to_yesterday(mydate)
Answered By: paxdiablo

I like using the built-in function range to create ranges, but alas, it doesn’t work with dates. Fortunately, Python dates can be converted to/from integers, which range CAN use:

from datetime import date

start_date = date(2019, 9, 21)
end_date = date(2019, 10, 9)

for ordinal in range(start_date.toordinal(), end_date.toordinal() + 1):  # Don't forget the + 1 (like I usually do)!
    print(date.fromordinal(ordinal))

This gives you:

2019-09-21
2019-09-22
2019-09-23
2019-09-24
2019-09-25
2019-09-26
2019-09-27
2019-09-28
2019-09-29
2019-09-30
2019-10-01
2019-10-02
2019-10-03
2019-10-04
2019-10-05
2019-10-06
2019-10-07
2019-10-08
2019-10-09

Happy dating!

Answered By: Bryon
Categories: questions Tags: , , ,
Answers are sorted by their score. The answer accepted by the question owner as the best is marked with
at the top-right corner.