pythonpython-3.xpython-2.7

Print all thursdays between date range


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?


Solution

  • 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