Python
date range
datetime module
programming
code tutorial

Creating a range of dates in Python

Interview Questions practice on Codemia

Over 8,000 real interview questions from top companies, searchable by company and role.

Browse interview questions

Introduction

Python does not have a built-in daterange() function like range() for integers. To generate a sequence of dates, use datetime.timedelta in a loop, a generator function, or pandas.date_range() for data analysis workflows. Each approach lets you iterate over consecutive days, weeks, months, or custom intervals.

Method 1: timedelta Loop

python
1from datetime import date, timedelta
2
3start = date(2025, 1, 1)
4end = date(2025, 1, 10)
5
6current = start
7while current <= end:
8    print(current)
9    current += timedelta(days=1)
10
11# 2025-01-01
12# 2025-01-02
13# ...
14# 2025-01-10
python
1from datetime import date, timedelta
2
3def daterange(start, end, step=1):
4    """Yield dates from start to end (exclusive), stepping by `step` days."""
5    current = start
6    while current < end:
7        yield current
8        current += timedelta(days=step)
9
10# Daily dates
11for d in daterange(date(2025, 1, 1), date(2025, 1, 6)):
12    print(d)
13# 2025-01-01 through 2025-01-05
14
15# Every 3 days
16for d in daterange(date(2025, 1, 1), date(2025, 1, 15), step=3):
17    print(d)
18# 2025-01-01, 2025-01-04, 2025-01-07, 2025-01-10, 2025-01-13

The generator yields one date at a time without building the full list in memory.

Method 3: List Comprehension

python
1from datetime import date, timedelta
2
3start = date(2025, 1, 1)
4days = 10
5
6dates = [start + timedelta(days=i) for i in range(days)]
7print(dates)
8# [date(2025, 1, 1), date(2025, 1, 2), ..., date(2025, 1, 10)]
9
10# Between two dates
11start = date(2025, 3, 1)
12end = date(2025, 3, 8)
13dates = [start + timedelta(days=i) for i in range((end - start).days + 1)]
14# Includes both start and end dates

Method 4: pandas.date_range()

python
1import pandas as pd
2
3# Daily range
4dates = pd.date_range(start="2025-01-01", end="2025-01-10", freq="D")
5print(dates)
6# DatetimeIndex(['2025-01-01', '2025-01-02', ..., '2025-01-10'], freq='D')
7
8# By number of periods
9dates = pd.date_range(start="2025-01-01", periods=5, freq="D")
10# 5 consecutive days starting from Jan 1
11
12# Weekly
13dates = pd.date_range(start="2025-01-01", end="2025-03-01", freq="W-MON")
14# Every Monday
15
16# Monthly (end of month)
17dates = pd.date_range(start="2025-01-01", end="2025-12-31", freq="ME")
18
19# Convert to Python date objects
20date_list = dates.date.tolist()

Common Frequency Codes

CodeMeaning
DCalendar day
BBusiness day (Mon-Fri)
WWeekly (default Sunday)
W-MONWeekly on Monday
MSMonth start
MEMonth end
QSQuarter start
YSYear start
hHourly

Method 5: dateutil.rrule

python
1from datetime import date
2from dateutil.rrule import rrule, DAILY, WEEKLY, MONTHLY
3
4# Daily
5dates = list(rrule(DAILY, dtstart=date(2025, 1, 1), until=date(2025, 1, 5)))
6# [datetime(2025, 1, 1), ..., datetime(2025, 1, 5)]
7
8# Weekly
9dates = list(rrule(WEEKLY, dtstart=date(2025, 1, 1), count=4))
10# 4 weeks starting from Jan 1
11
12# Monthly (handles varying month lengths correctly)
13dates = list(rrule(MONTHLY, dtstart=date(2025, 1, 31), count=4))
14# Jan 31, Feb 28, Mar 31, Apr 30 — smart month-end handling
15
16# Every 2 weeks
17dates = list(rrule(DAILY, interval=14, dtstart=date(2025, 1, 1), count=6))

dateutil.rrule is especially useful for month and year intervals where month lengths vary.

Working with datetime (Including Time)

python
1from datetime import datetime, timedelta
2
3start = datetime(2025, 1, 1, 9, 0)  # 9:00 AM
4
5# Every hour for 8 hours
6times = [start + timedelta(hours=i) for i in range(8)]
7for t in times:
8    print(t.strftime("%Y-%m-%d %H:%M"))
9
10# 2025-01-01 09:00
11# 2025-01-01 10:00
12# ...
13# 2025-01-01 16:00
14
15# Every 30 minutes
16times = [start + timedelta(minutes=30*i) for i in range(16)]

Business Days Only

python
1import pandas as pd
2from datetime import date
3
4# pandas business day range
5bdays = pd.bdate_range(start="2025-01-01", end="2025-01-15")
6print(bdays)
7# Excludes weekends
8
9# Custom business days (exclude holidays too)
10from pandas.tseries.holiday import USFederalHolidayCalendar
11bday = pd.offsets.CustomBusinessDay(calendar=USFederalHolidayCalendar())
12dates = pd.date_range(start="2025-01-01", end="2025-01-31", freq=bday)

Formatting Date Ranges

python
1from datetime import date, timedelta
2
3start = date(2025, 1, 1)
4dates = [start + timedelta(days=i) for i in range(5)]
5
6# As strings
7formatted = [d.strftime("%Y-%m-%d") for d in dates]
8# ['2025-01-01', '2025-01-02', ..., '2025-01-05']
9
10# As ISO format
11iso = [d.isoformat() for d in dates]
12
13# As custom format
14labels = [d.strftime("%B %d, %Y") for d in dates]
15# ['January 01, 2025', 'January 02, 2025', ...]

Reverse Range (Descending)

python
1from datetime import date, timedelta
2
3start = date(2025, 1, 10)
4end = date(2025, 1, 1)
5
6# Countdown
7current = start
8while current >= end:
9    print(current)
10    current -= timedelta(days=1)
11
12# Or with list comprehension
13dates = [start - timedelta(days=i) for i in range(10)]
14# [date(2025, 1, 10), date(2025, 1, 9), ..., date(2025, 1, 1)]

Common Pitfalls

  • Off-by-one on end date: range(10) excludes 10. Be explicit about whether your date range includes the end date. Use <= for inclusive, < for exclusive.
  • Month arithmetic with timedelta: timedelta(days=30) does not equal "one month" — months have 28-31 days. Use dateutil.relativedelta(months=1) for month-accurate arithmetic.
  • Timezone-naive date ranges: date objects have no timezone. If you need timezone-aware ranges, use datetime with zoneinfo.ZoneInfo and check DST transitions.
  • Memory with large ranges: [start + timedelta(days=i) for i in range(365*100)] creates a list of 36,500 dates in memory. Use a generator for large ranges.
  • pandas freq string changes: In pandas 2.x, some frequency strings changed (e.g., M became ME for month-end, Y became YE for year-end). Check your pandas version.

Summary

  • Use a generator with timedelta(days=1) for simple day-by-day iteration
  • Use list comprehension [start + timedelta(days=i) for i in range(n)] for small ranges
  • Use pandas.date_range() for data analysis with flexible frequency codes
  • Use dateutil.rrule for month/year intervals that respect varying month lengths
  • Use pd.bdate_range() for business-day-only ranges
  • Always be explicit about inclusive vs exclusive end dates

Related reading
Free course
Beginner
7 lessons
2 hours
Tackling System Design Interview Problems

A short course that equips you with the skills to approach system design interviews methodically.

Start the free course
Track what you have practised

A free account saves your progress, solutions and study plan across every problem on Codemia.

Interview Questions practice on Codemia

Over 8,000 real interview questions from top companies, searchable by company and role.

Browse interview questions

All Rights Reserved.