Iterating through a range of dates in Python
Asked Answered
C

28

551

I have the following code to do this, but how can I do it better? Right now I think it's better than nested loops, but it starts to get Perl-one-linerish when you have a generator in a list comprehension.

day_count = (end_date - start_date).days + 1
for single_date in [d for d in (start_date + timedelta(n) for n in range(day_count)) if d <= end_date]:
    print strftime("%Y-%m-%d", single_date.timetuple())

Notes

  • I'm not actually using this to print. That's just for demo purposes.
  • The start_date and end_date variables are datetime.date objects because I don't need the timestamps. (They're going to be used to generate a report).

Sample Output

For a start date of 2009-05-30 and an end date of 2009-06-09:

2009-05-30
2009-05-31
2009-06-01
2009-06-02
2009-06-03
2009-06-04
2009-06-05
2009-06-06
2009-06-07
2009-06-08
2009-06-09
Carchemish answered 29/6, 2009 at 20:16 Comment(6)
Just to point out: I don't think there's any difference between 'time.strftime("%Y-%m-%d", single_date.timetuple())' and the shorter 'single_date.strftime("%Y-%m-%d")'. Most answers seem to be copying the longer style.Diaghilev
Wow, these answers are much too complicated. Try this: #7274767Sidoon
@GringoSuave: what is complicated about Sean Cavanagh's answer?Nette
@GringoSuave That link is a duplicate to: #1060779Reliance
Does this answer your question? Creating a range of dates in PythonMajorette
@Reliance "That link is a duplicate to:" that's... this question.Margay
T
802

Why are there two nested iterations? For me it produces the same list of data with only one iteration:

for single_date in (start_date + timedelta(n) for n in range(day_count)):
    print ...

And no list gets stored, only one generator is iterated over. Also the "if" in the generator seems to be unnecessary.

After all, a linear sequence should only require one iterator, not two.

Update after discussion with John Machin:

Maybe the most elegant solution is using a generator function to completely hide/abstract the iteration over the range of dates:

from datetime import date, timedelta

def daterange(start_date, end_date):
    for n in range(int((end_date - start_date).days)):
        yield start_date + timedelta(n)

start_date = date(2013, 1, 1)
end_date = date(2015, 6, 2)
for single_date in daterange(start_date, end_date):
    print(single_date.strftime("%Y-%m-%d"))

NB: For consistency with the built-in range() function this iteration stops before reaching the end_date. So for inclusive iteration use the next day, as you would with range().

Taima answered 29/6, 2009 at 20:27 Comment(14)
Thanks, good point. That if statement was left over from a previous version, before I was subtracting start date from end date.Carchemish
Thanks Ber, that's awesome. It works perfectly and looks much better than my old mess.Carchemish
-1 ... having a preliminary calculation of day_count and using range is not awesome when a simple while loop will suffice.Cornet
@John Machin: Okay. I do however prever an iteration over while loops with explicit incrementation of some counter or value. The interation pattern is more pythonic (at least in my personal view) and also more general, as it allows to express an iteration while hiding the details of how that iteration is done.Taima
@John Machin: I have updated my answer to show what I mean. Hope you'll like it.Taima
@Ber: I don't like it at all; it's DOUBLY bad. You ALREADY had an iteration! By wrapping the complained-about constructs in a generator, you have added even more execution overhead plus diverted the user's attention to somewhere else to read your 3-liner's code and/or docs. -2Cornet
@John Machin: I disagree. The point is not about reducing the number of lines to the absolute minimum. After all, we're not talking Perl here. Also, my code does only one iteration (that's how the generator works, but I guess you know that). *** My point is about abstracting concepts for re-use and self explanatory code. I maintain that this is far more worthwhile than have the shortest code possible.Taima
You can make this code slightly shorter if you use the datetime object's strftime method.Mcgrew
If you're going for terseness you can use a generator expression: (start_date + datetime.timedelta(n) for n in range((end_date - start_date).days))Maurreen
@JohnMachin It’s the most pythonic solution, really. Iterating over mutating values is a thing of the past and very implicit. Explicit over implicit, rule 2, remember?Cunaxa
I like this, but I had to refresh my memory on the relevant imports: from datetime import timedelta, date ; start_date = date(2014,1,1) ; day_count = 15 - after that, it executes for me. You might consider putting the complete example for those rusty or new to Python.Fiddling
It is worth noting that this doesn't seamlessly translate to time zone aware datetime objects as the start & end datetimes might be in different daylight savings zones which makes it much more fiddly. As far as I can tell, you have to reconstruct the datetime at each point to allow the time zone and pytz.localize to figure out the daylight savings.Ona
just a little improviment: for n in range(int(start_date.day), int ((end_date - start_date).days), step): this way now is possible pass steps (in case want jump steps in interation)Pigmy
for n in range(int ((end_date - start_date).days+1)): For the end_date to be includedProductive
O
367

This might be more clear:

from datetime import date, timedelta

start_date = date(2019, 1, 1)
end_date = date(2020, 1, 1)
delta = timedelta(days=1)
while start_date <= end_date:
    print(start_date.strftime("%Y-%m-%d"))
    start_date += delta
Orthogonal answered 29/6, 2009 at 20:31 Comment(1)
Very clear and short, but doesn't work well if you want to use continueKiushu
C
206

Use the dateutil library:

from datetime import date
from dateutil.rrule import rrule, DAILY

a = date(2009, 5, 30)
b = date(2009, 6, 9)

for dt in rrule(DAILY, dtstart=a, until=b):
    print dt.strftime("%Y-%m-%d")

This python library has many more advanced features, some very useful, like relative deltas—and is implemented as a single file (module) that's easily included into a project.

Cachou answered 30/6, 2009 at 4:49 Comment(2)
Note that the final date in the for loop here is inclusive of until whereas the final date of the daterange method in Ber's answer is exclusive of end_date.Arnst
more modern docs dateutil.readthedocs.io/en/stable/rrule.htmlMekong
K
128

Pandas is great for time series in general, and has direct support for date ranges.

import pandas as pd
daterange = pd.date_range(start_date, end_date)

You can then loop over the daterange to print the date:

for single_date in daterange:
    print (single_date.strftime("%Y-%m-%d"))

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 http://pandas.pydata.org/pandas-docs/stable/timeseries.html#generating-ranges-of-timestamps

The power of Pandas is really its dataframes, which support vectorized operations (much like numpy) that make operations across large quantities of data very fast and easy.

EDIT: You could also completely skip the for loop and just print it directly, which is easier and more efficient:

print(daterange)
Karolinekaroly answered 25/5, 2014 at 8:44 Comment(2)
"much like numpy" - Pandas is built on numpy :PCrozier
You can also use floor, round,ceil to start on exact dates: pd.date_range(start=start_date.floor('d'),end=end_date.floor('d'), freq = 'd')Mccutchen
T
20

This is the most human-readable solution I can think of.

import datetime

def daterange(start, end, step=datetime.timedelta(1)):
    curr = start
    while curr < end:
        yield curr
        curr += step
Tobietobin answered 13/10, 2016 at 14:28 Comment(0)
K
19
import datetime

def daterange(start, stop, step=datetime.timedelta(days=1), inclusive=False):
  # inclusive=False to behave like range by default
  if step.days > 0:
    while start < stop:
      yield start
      start = start + step
      # not +=! don't modify object passed in if it's mutable
      # since this function is not restricted to
      # only types from datetime module
  elif step.days < 0:
    while start > stop:
      yield start
      start = start + step
  if inclusive and start == stop:
    yield start

# ...

for date in daterange(start_date, end_date, inclusive=True):
  print strftime("%Y-%m-%d", date.timetuple())

This function does more than you strictly require, by supporting negative step, etc. As long as you factor out your range logic, then you don't need the separate day_count and most importantly the code becomes easier to read as you call the function from multiple places.

Kelp answered 29/6, 2009 at 20:35 Comment(4)
Thanks, renamed to more closely match range's parameters, forgot to change in the body.Kelp
+1 ... but as you are allowing the step to be a timedelta, you should either (a) call it dateTIMErange() and make steps of e.g. timedelta(hours=12) and timedelta(hours=36) work properly or (b) trap steps that aren't an integral number of days or (c) save the caller the hassle and express the step as a number of days instead of a timedelta.Cornet
Any timedelta should work already, but I did add datetime_range and date_range to my personal scrap collection after writing this, because of (a). Not sure another function is worthwhile for (c), the most common case of days=1 is already taken care of, and having to pass an explicit timedelta avoids confusion. Maybe uploading it somewhere is best: bitbucket.org/kniht/scraps/src/tip/python/gen_range.pyKelp
to make this work on increments other than days you should check against step.total_seconds(), and not step.daysJoacimah
T
15

Why not try:

import datetime as dt

start_date = dt.datetime(2012, 12,1)
end_date = dt.datetime(2012, 12,5)

total_days = (end_date - start_date).days + 1 #inclusive 5 days

for day_number in range(total_days):
    current_date = (start_date + dt.timedelta(days = day_number)).date()
    print current_date
Trichotomy answered 12/4, 2013 at 10:47 Comment(0)
H
15

Numpy's arange function can be applied to dates:

import numpy as np
from datetime import datetime, timedelta
d0 = datetime(2009, 1,1)
d1 = datetime(2010, 1,1)
dt = timedelta(days = 1)
dates = np.arange(d0, d1, dt).astype(datetime)

The use of astype is to convert from numpy.datetime64 to an array of datetime.datetime objects.

Hjerpe answered 29/5, 2016 at 10:41 Comment(2)
Super lean construction ! The last line works for me with dates = np.arange(d0, d1, dt).astype(datetime.datetime)Harmonic
+1 for posting a generic one-liner solution which allows any timedelta, instead of a fixed rounded step such as hourly/minutely/… .Maintain
M
10

For completeness, Pandas also has a period_range function for timestamps that are out of bounds:

import pandas as pd

pd.period_range(start='1/1/1626', end='1/08/1627', freq='D')
Mosra answered 17/9, 2019 at 11:30 Comment(0)
T
9

Show the last n days from today:

import datetime
for i in range(0, 100):
    print((datetime.date.today() + datetime.timedelta(i)).isoformat())

Output:

2016-06-29
2016-06-30
2016-07-01
2016-07-02
2016-07-03
2016-07-04
Theft answered 25/4, 2016 at 3:34 Comment(5)
Please add round brackets, like print((datetime.date.today() + datetime.timedelta(i)).isoformat())Spindle
@Spindle please feel free to do edits, I'll accept them.Theft
I tried. Editing requires minimum 6 chars, but in this case it is necessary to add just 2 chars, "(" and ")"Spindle
print((datetime.date.today() + datetime.timedelta(i))) without the .isoformat() gives exactly the same output. I need my script to print YYMMDD. Anyone know how to do that?Smackdab
Just do this in the for loop instead of the print statement d = datetime.date.today() + datetime.timedelta(i); d.strftime("%Y%m%d")Theft
C
7
import datetime

def daterange(start, stop, step_days=1):
    current = start
    step = datetime.timedelta(step_days)
    if step_days > 0:
        while current < stop:
            yield current
            current += step
    elif step_days < 0:
        while current > stop:
            yield current
            current += step
    else:
        raise ValueError("daterange() step_days argument must not be zero")

if __name__ == "__main__":
    from pprint import pprint as pp
    lo = datetime.date(2008, 12, 27)
    hi = datetime.date(2009, 1, 5)
    pp(list(daterange(lo, hi)))
    pp(list(daterange(hi, lo, -1)))
    pp(list(daterange(lo, hi, 7)))
    pp(list(daterange(hi, lo, -7))) 
    assert not list(daterange(lo, hi, -1))
    assert not list(daterange(hi, lo))
    assert not list(daterange(lo, hi, -7))
    assert not list(daterange(hi, lo, 7)) 
Cornet answered 30/6, 2009 at 11:49 Comment(0)
W
6

You can generate a series of date between two dates using the pandas library simply and trustfully

import pandas as pd

print pd.date_range(start='1/1/2010', end='1/08/2018', freq='M')

You can change the frequency of generating dates by setting freq as D, M, Q, Y (daily, monthly, quarterly, yearly )

Watercress answered 9/8, 2018 at 5:41 Comment(0)
B
5
for i in range(16):
    print datetime.date.today() + datetime.timedelta(days=i)
Benitabenites answered 17/6, 2010 at 6:26 Comment(0)
T
4

I have a similar problem, but I need to iterate monthly instead of daily.

This is my solution

import calendar
from datetime import datetime, timedelta

def days_in_month(dt):
    return calendar.monthrange(dt.year, dt.month)[1]

def monthly_range(dt_start, dt_end):
    forward = dt_end >= dt_start
    finish = False
    dt = dt_start

    while not finish:
        yield dt.date()
        if forward:
            days = days_in_month(dt)
            dt = dt + timedelta(days=days)            
            finish = dt > dt_end
        else:
            _tmp_dt = dt.replace(day=1) - timedelta(days=1)
            dt = (_tmp_dt.replace(day=dt.day))
            finish = dt < dt_end

Example #1

date_start = datetime(2016, 6, 1)
date_end = datetime(2017, 1, 1)

for p in monthly_range(date_start, date_end):
    print(p)

Output

2016-06-01
2016-07-01
2016-08-01
2016-09-01
2016-10-01
2016-11-01
2016-12-01
2017-01-01

Example #2

date_start = datetime(2017, 1, 1)
date_end = datetime(2016, 6, 1)

for p in monthly_range(date_start, date_end):
    print(p)

Output

2017-01-01
2016-12-01
2016-11-01
2016-10-01
2016-09-01
2016-08-01
2016-07-01
2016-06-01
Tbar answered 24/1, 2017 at 7:34 Comment(0)
J
4
import datetime
from dateutil.rrule import DAILY,rrule

date=datetime.datetime(2019,1,10)

date1=datetime.datetime(2019,2,2)

for i in rrule(DAILY , dtstart=date,until=date1):
     print(i.strftime('%Y%b%d'),sep='\n')

OUTPUT:

2019Jan10
2019Jan11
2019Jan12
2019Jan13
2019Jan14
2019Jan15
2019Jan16
2019Jan17
2019Jan18
2019Jan19
2019Jan20
2019Jan21
2019Jan22
2019Jan23
2019Jan24
2019Jan25
2019Jan26
2019Jan27
2019Jan28
2019Jan29
2019Jan30
2019Jan31
2019Feb01
2019Feb02
Jam answered 2/6, 2020 at 16:8 Comment(1)
Welcome to Stack Overflow! While this code may solve the question, including an explanation of how and why this solves the problem, especially on questions with too many good answers, would really help to improve the quality of your post, and probably result in more upvotes. Remember that you are answering the question for readers in the future, not just the person asking now. Please edit your answer to add explanations and give an indication of what limitations and assumptions apply. From ReviewCespitose
S
4

Using pendulum.period:

import pendulum

start = pendulum.from_format('2020-05-01', 'YYYY-MM-DD', formatter='alternative')
end = pendulum.from_format('2020-05-02', 'YYYY-MM-DD', formatter='alternative')

period = pendulum.period(start, end)

for dt in period:
    print(dt.to_date_string())
Sporozoite answered 19/11, 2020 at 14:15 Comment(0)
B
4

For those who are interested in Pythonic functional way:

from datetime import date, timedelta
from itertools import count, takewhile

for d in takewhile(lambda x: x<=date(2009,6,9), map(lambda x:date(2009,5,30)+timedelta(days=x), count())):
    print(d)
Brazilein answered 23/12, 2020 at 23:15 Comment(0)
D
3
> pip install DateTimeRange

from datetimerange import DateTimeRange

def dateRange(start, end, step):
        rangeList = []
        time_range = DateTimeRange(start, end)
        for value in time_range.range(datetime.timedelta(days=step)):
            rangeList.append(value.strftime('%m/%d/%Y'))
        return rangeList

    dateRange("2018-09-07", "2018-12-25", 7)  

    Out[92]: 
    ['09/07/2018',
     '09/14/2018',
     '09/21/2018',
     '09/28/2018',
     '10/05/2018',
     '10/12/2018',
     '10/19/2018',
     '10/26/2018',
     '11/02/2018',
     '11/09/2018',
     '11/16/2018',
     '11/23/2018',
     '11/30/2018',
     '12/07/2018',
     '12/14/2018',
     '12/21/2018']
Deliquesce answered 11/9, 2018 at 16:4 Comment(0)
H
3

You can use Arrow:

This is example from the docs, iterating over hours:

from arrow import Arrow

>>> start = datetime(2013, 5, 5, 12, 30)
>>> end = datetime(2013, 5, 5, 17, 15)
>>> for r in Arrow.range('hour', start, end):
...     print repr(r)
...
<Arrow [2013-05-05T12:30:00+00:00]>
<Arrow [2013-05-05T13:30:00+00:00]>
<Arrow [2013-05-05T14:30:00+00:00]>
<Arrow [2013-05-05T15:30:00+00:00]>
<Arrow [2013-05-05T16:30:00+00:00]>

To iterate over days, you can use like this:

>>> start = Arrow(2013, 5, 5)
>>> end = Arrow(2013, 5, 5)
>>> for r in Arrow.range('day', start, end):
...     print repr(r)

(Didn't check if you can pass datetime.date objects, but anyways Arrow objects are easier in general)

Hanson answered 11/1, 2021 at 5:49 Comment(0)
S
3

If you are going to use dynamic timedelta then you can use:

1. With while loop

def datetime_range(start: datetime, end: datetime, delta: timedelta) -> Generator[datetime, None, None]:
    while start <= end:
        yield start
        start += delta

2. With for loop

from datetime import datetime, timedelta
from typing import Generator


def datetime_range(start: datetime, end: datetime, delta: timedelta) -> Generator[datetime, None, None]:
    delta_units = int((end - start) / delta)

    for _ in range(delta_units + 1):
        yield start
        start += delta

3. If you are using async/await

async def datetime_range(start: datetime, end: datetime, delta: timedelta) -> AsyncGenerator[datetime, None]:
    delta_units = int((end - start) / delta)

    for _ in range(delta_units + 1):
        yield start
        start += delta

4. List comprehension

def datetime_range(start: datetime, end: datetime, delta: timedelta) -> List[datetime]:
    delta_units = int((end - start) / delta)
    return [start + (delta * index) for index in range(delta_units + 1)]

Then 1 and 2 solutions simply can be used like this

start = datetime(2020, 10, 10, 10, 00)
end = datetime(2022, 10, 10, 18, 00)
delta = timedelta(minutes=30)

result = [time_part for time_part in datetime_range(start, end, delta)]
# or 
for time_part in datetime_range(start, end, delta):
    print(time_part)

3-third solution can be used like this in async context. Because it retruns an async generator object, which can be used only in async context

start = datetime(2020, 10, 10, 10, 00)
end = datetime(2022, 10, 10, 18, 00)
delta = timedelta(minutes=30)

result = [time_part async for time_part in datetime_range(start, end, delta)]

async for time_part in datetime_range(start, end, delta):
    print(time_part)

The benefit of the solutions about is that all of them are using dynamic timedelta. This can be very usefull in cases when you do not know which time delta you will have.

Sp answered 11/8, 2022 at 9:34 Comment(0)
C
2

What about the following for doing a range incremented by days:

for d in map( lambda x: startDate+datetime.timedelta(days=x), xrange( (stopDate-startDate).days ) ):
  # Do stuff here
  • startDate and stopDate are datetime.date objects

For a generic version:

for d in map( lambda x: startTime+x*stepTime, xrange( (stopTime-startTime).total_seconds() / stepTime.total_seconds() ) ):
  # Do stuff here
  • startTime and stopTime are datetime.date or datetime.datetime object (both should be the same type)
  • stepTime is a timedelta object

Note that .total_seconds() is only supported after python 2.7 If you are stuck with an earlier version you can write your own function:

def total_seconds( td ):
  return float(td.microseconds + (td.seconds + td.days * 24 * 3600) * 10**6) / 10**6
Calgary answered 13/7, 2011 at 2:35 Comment(0)
S
2

This function has some extra features:

  • can pass a string matching the DATE_FORMAT for start or end and it is converted to a date object
  • can pass a date object for start or end
  • error checking in case the end is older than the start

    import datetime
    from datetime import timedelta
    
    
    DATE_FORMAT = '%Y/%m/%d'
    
    def daterange(start, end):
          def convert(date):
                try:
                      date = datetime.datetime.strptime(date, DATE_FORMAT)
                      return date.date()
                except TypeError:
                      return date
    
          def get_date(n):
                return datetime.datetime.strftime(convert(start) + timedelta(days=n), DATE_FORMAT)
    
          days = (convert(end) - convert(start)).days
          if days <= 0:
                raise ValueError('The start date must be before the end date.')
          for n in range(0, days):
                yield get_date(n)
    
    
    start = '2014/12/1'
    end = '2014/12/31'
    print list(daterange(start, end))
    
    start_ = datetime.date.today()
    end = '2015/12/1'
    print list(daterange(start, end))
    
Succulent answered 27/7, 2014 at 3:55 Comment(0)
K
2

Here's code for a general date range function, similar to Ber's answer, but more flexible:

def count_timedelta(delta, step, seconds_in_interval):
    """Helper function for iterate.  Finds the number of intervals in the timedelta."""
    return int(delta.total_seconds() / (seconds_in_interval * step))


def range_dt(start, end, step=1, interval='day'):
    """Iterate over datetimes or dates, similar to builtin range."""
    intervals = functools.partial(count_timedelta, (end - start), step)

    if interval == 'week':
        for i in range(intervals(3600 * 24 * 7)):
            yield start + datetime.timedelta(weeks=i) * step

    elif interval == 'day':
        for i in range(intervals(3600 * 24)):
            yield start + datetime.timedelta(days=i) * step

    elif interval == 'hour':
        for i in range(intervals(3600)):
            yield start + datetime.timedelta(hours=i) * step

    elif interval == 'minute':
        for i in range(intervals(60)):
            yield start + datetime.timedelta(minutes=i) * step

    elif interval == 'second':
        for i in range(intervals(1)):
            yield start + datetime.timedelta(seconds=i) * step

    elif interval == 'millisecond':
        for i in range(intervals(1 / 1000)):
            yield start + datetime.timedelta(milliseconds=i) * step

    elif interval == 'microsecond':
        for i in range(intervals(1e-6)):
            yield start + datetime.timedelta(microseconds=i) * step

    else:
        raise AttributeError("Interval must be 'week', 'day', 'hour' 'second', \
            'microsecond' or 'millisecond'.")
Kutchins answered 15/7, 2016 at 17:59 Comment(0)
C
2
from datetime import date,timedelta
delta = timedelta(days=1)
start = date(2020,1,1)
end=date(2020,9,1)
loop_date = start
while loop_date<=end:
    print(loop_date)
    loop_date+=delta
Cruel answered 14/9, 2020 at 9:15 Comment(0)
K
1

in polars it can be done as well, if eager is set to True

start = datetime.date(year=2009, month=5, day=30)
end = datetime.date(year=2009, month=6, day=9)
dates = pl.date_range(start, end, eager=True)

for date in dates:
    print(date)
Kamat answered 6/11, 2023 at 8:38 Comment(0)
N
1

Here is an alternative solution based on leftjoin solution.

For pendulum below 3.0.0

def test_iteration():
    start = pendulum.from_format('2018-01', 'YYYY-MM')
    end = pendulum.from_format('2020-01', 'YYYY-MM')

    interval = pendulum.period(start, end)

    for dt in interval.range('months'):
        print(dt.format('YYYY-MM'))

And for pendulum 3.0.0 and above (they have renamed period to interval) https://github.com/sdispater/pendulum/pull/676

def test_iteration():
    start = pendulum.from_format('2018-01', 'YYYY-MM')
    end = pendulum.from_format('2020-01', 'YYYY-MM')

    interval = pendulum.interval(start, end)

    for dt in interval.range('months'):
        print(dt.format('YYYY-MM'))

You can change de range values from the list on the documentation here : https://pendulum.eustace.io/docs/#range

Supported units for range() are: years, months, weeks, days, hours, minutes, seconds and microseconds
Nickolas answered 31/12, 2023 at 16:40 Comment(0)
T
0

Slightly different approach to reversible steps by storing range args in a tuple.

def date_range(start, stop, step=1, inclusive=False):
    day_count = (stop - start).days
    if inclusive:
        day_count += 1

    if step > 0:
        range_args = (0, day_count, step)
    elif step < 0:
        range_args = (day_count - 1, -1, step)
    else:
        raise ValueError("date_range(): step arg must be non-zero")

    for i in range(*range_args):
        yield start + timedelta(days=i)
Tasse answered 26/9, 2018 at 3:59 Comment(0)
W
0

Answer for Python API Call Loop

using datetime and timedelta from the datetime module

from datetime import datetime, timedelta

import requests


headers = {"accept": "application/json", "x-api-key": "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"}

delta = timedelta(days=30)
start = datetime(year=2022, month=1, day=1)
num_ranges = 10

for _ in range(num_ranges):
    start_str = start.strftime("%Y-%m-%d")
    end = start + delta
    end_str = end.strftime("%Y-%m-%d")
    url = f"https://apiendpoint.com/v2/dapps/xxxx/history/uaw?dateFrom={start_str}&dateTo={end_str}"
    response = requests.request("GET", url, headers=headers)
    # TODO: append response json to result
    start = end
Weekly answered 22/3, 2024 at 16:10 Comment(0)

© 2022 - 2025 — McMap. All rights reserved.