Explain Codes LogoExplain Codes Logo

Iterating through a range of dates in Python

python
generator-functions
pandas
dateutil
Nikita BarsukovbyNikita Barsukov·Dec 27, 2024
TLDR

Python's datetime.timedelta lets you iteratively cover dates spanning a range. Here's the quick and dirty for dates from January 1 to 5, 2023:

from datetime import datetime, timedelta start_date, end_date = datetime(2023, 1, 1), datetime(2023, 1, 6) while start_date < end_date: print(start_date.strftime("%Y-%m-%d")) # Output: YYYY-MM-DD start_date += timedelta(days=1) # Next stop, tomorrow!

This while loop steps through each day, starting at start_date and stopping when it reaches end_date.

Using generators for efficient date iteration

To carve up your date range iteration code maintaining cleanliness and efficiency, you can go with a generator function. It's a workhorse for dealing with large number of dates and it's keen on memory:

def daterange(start_date, end_date): for n in range(int((end_date - start_date).days)): yield start_date + timedelta(n) # Usage example: for single_date in daterange(date(2023, 1, 1), date(2023, 1, 6)): print(single_date.strftime("%Y-%m-%d")) # Prints date in YYYY-MM-DD format

Our daterange generator function works as smoothly as Python's built-in range function. It keeps your date traversing code spotless and memory-friendly.

Handling convoluted date scenarios with Pandas and dateutil

Taking a pitstop over rules-based dates like business days or monthly intervals? Pandas and dateutil pack quite a punch:

Using Pandas for time series operations

Pandas lets you juggle with bdate_range for business-days permutation and date_range for more general date sequences:

import pandas as pd # Tomato 🍅, Tomato 🍅. General or business, pick your date range: date_range = pd.date_range(start="2023-01-01", end="2023-01-05") business_days = pd.bdate_range(start="2023-01-01", end="2023-01-05") def print_dates(dates): for date in dates: print(date.strftime("%Y-%m-%d")) # YYYY-MM-DD strikes again! print_dates(date_range) print_dates(business_days)

Excellent for time series, Pandas even gifts you vectorized operations for speedy Gonzales act over dates.

Iterating using dateutil

dateutil library spins up your datetime skills. Want to exclude weekends in the date range iteration? Say no more:

from dateutil.rrule import rrule, DAILY from dateutil.rrule import MO, TU, WE, TH, FR # WeekDays, Assemble! start_date = datetime(2023, 1, 1) end_date = datetime(2023, 1, 31) weekdays = rrule(DAILY, dtstart=start_date, until=end_date, byweekday=(MO, TU, WE, TH, FR)) for dt in weekdays: print(dt.strftime("%Y-%m-%d")) # Your weekdays schedule: YYYY-MM-DD

rrule (recurrence rule) with the byweekday parameter plays the game of weekdays only.

Turbocharging date iteration code

A few nuggets of wisdom to make your date iteration code a mean, clean speed machine:

  1. Keep range logic in a separate generator for clear-cut maintenance.
  2. While courting dateutil or Pandas, match these tools with your project's complexity.
  3. Sidestep modifying mutable objects within loops to ensure code stability and predictability.
  4. Beef up your code to handle inclusive date ranges and negative steps, if needed.