My requirement is to loop through calendar dates in python in 2-day increments capturing every date across multiple months or years without repeating any dates.
I’m sure that sounds confusing so I’ve posted some reference visuals to demonstrate.
I have written Python code that successfully achieves my desired result (also attached), but it is clunky and gross code. I’m wondering if someone has a more elegant solution?
The reason I need this loop is to "span" the main function and capture either 1 whole month, multiple whole months, or even multiple years with multiple whole months (which I set by changing the years and months variables at the top of the code). These variable give me control over what years and months I want to span with the main function.
Example:
First Loop Iteration: start_date = 1/1/2021 end_date = 1/2/2021
Second Loop Iteration: start_date = 1/3/2021 end_date = 1/4/2021
….
Fifteenth Loop Iteration: start_date = 1/29/2021 end_date = 1/30/2021
Sixteenth Loop Iteration: start_date = 1/31/2021 end_date = 1/31/2021
Seventeenth Loop Iteration: start_date = 2/1/2021 end_date = 2/2/2021
Eighteenth Loop Iteration: start_date = 2/3/2021 end_date = 2/4/2021
Visualization of Example of Desired Loop
Here is the code that works to accomplish this task:
# Set date range to loop through
years = [2021, 2022]
months = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12]
days_in_month = {1: 31, 2: 28, 3: 31, 4: 30, 5: 31,
6: 30, 7: 31, 8: 31, 9: 30, 10: 31, 11: 30, 12: 31}
clients = ["client1", "client2"]
# Loop through clients list and date range
combined_records = []
for client in clients:
for target_year in years:
for target_month in months:
start_day = 1
end_day = 2
# Even number days in a month
if days_in_month[target_month] % 2 == 0:
while end_day <= days_in_month[target_month]:
# Arguments for main function: main(client, start_date, end_date)
list_of_records = main(client, date(target_year, target_month, start_day),
date(target_year, target_month, end_day))
for record in list_of_records:
combined_records.append(record)
# Increment date range
start_day += 2
end_day += 2
# Odd number days in a month
else:
while end_day <= 32:
if end_day < 32:
# Arguments for main function: main(client, start_date, end_date)
list_of_records = main(client, date(target_year, target_month, start_day),
date(target_year, target_month, end_day))
for record in list_of_records:
combined_records.append(record)
# Increment date range
start_day += 2
end_day += 2
else:
end_day = 31
# Arguments for main function: main(client, start_date, end_date)
list_of_records = main(client, date(target_year, target_month, start_day),
date(target_year, target_month, end_day))
for record in list_of_records:
combined_records.append(record)
# Increment date range
start_day += 2
end_day += 2
print(f"CLIENT COMPLETE: {client}")
>Solution :
You can use numpy’s datetime64 to create an array of evenly spaced dates and then just iterate through that single array.
dates = np.arange(np.datetime64('2021-01-01'), np.datetime64('2022-12-31'), np.timedelta64(2, 'D'))
for date in dates:
# code here