I want to print all Thursdays between these date ranges
from datetime import date, timedelta
sdate = date(2015, 1, 7) # start date
edate = date(2015, 12, 31) # end date
What is the best pythonic way to do that?
Most people are iterating through every day which is a waste. Also might be helpful to delay calculating the thursdays until you actually need them. For this you could use a generator.
def get_days(start, day_index, end=None):
# set the start as the next valid day
start += timedelta(days=(day_index - start.weekday()) % 7)
week = timedelta(days=7)
while end and start < end or not end:
yield start
start += week
This delays getting the next day until you need it, and allows infinite days if you don't specify and end date.
thursday_generator = get_days(date(2015, 1, 7), 3, date(2015, 12, 31))
print(list(thursday_generator))
"""
[datetime.date(2015, 1, 8), datetime.date(2015, 1, 15), datetime.date(2015, 1, 22), ...]
"""
You can easily dump as strings:
print("\n".join(map(str, thursday_generator)))
"""
2015-01-08
2015-01-15
2015-01-22
...
"""
You can also use f-strings for custom string formatting:
print("\n".join(f"{day:%A %x}" for day in thursday_generator))
"""
Thursday 01/08/15
Thursday 01/15/15
Thursday 01/22/15
...
"""
If you don't specify an end date, it goes on forever.
In [28]: thursday_generator = get_days(date(2015, 1, 7), 3)
...: print(len(list(thursday_generator)))
---------------------------------------------------------------------------
OverflowError Traceback (most recent call last)
<ipython-input-28-b161cdcccc75> in <module>
1 thursday_generator = get_days(date(2015, 1, 7), 3)
----> 2 print(len(list(thursday_generator)))
<ipython-input-16-0691db329606> in get_days(start, day_index, end)
5 while end and start < end or not end:
6 yield start
----> 7 start += week
8
OverflowError: date value out of range