Skip to content

Instantly share code, notes, and snippets.

@tkardi
Last active July 30, 2018 11:23
Show Gist options
  • Save tkardi/e4d2aa3e52142f4a389f8431dc54cdae to your computer and use it in GitHub Desktop.
Save tkardi/e4d2aa3e52142f4a389f8431dc54cdae to your computer and use it in GitHub Desktop.
Group a datetime-range over months
from datetime import datetime, timedelta
def group_by_months(since, until):
"""Group a datetime range into month-based ranges with breaks at midnight.
>>> a = datetime(2015,11,5,3,12,5)
>>> b = datetime(2016,3,7,4,32,10)
>>> for i, (since, until) in enumerate(group_by_months(a, b)):
... print i,
... print since.strftime('%Y.%m.%d %H:%M:%S'),
... print until.strftime('%Y.%m.%d %H:%M:%S')
...
0 2015.11.05 03:12:05 2015.11.30 23:59:59
1 2015.12.01 00:00:00 2015.12.31 23:59:59
2 2016.01.01 00:00:00 2016.01.31 23:59:59
3 2016.02.01 00:00:00 2016.02.29 23:59:59
4 2016.03.01 00:00:00 2016.03.07 04:32:10
>>>
Or if there's no time present, only dates
>>> a = datetime(2015,11,5)
>>> b = datetime(2016,3,7)
>>> for i, (since, until) in enumerate(group_by_months(a, b)):
... print i,
... print since.strftime('%Y.%m.%d %H:%M:%S'),
... print until.strftime('%Y.%m.%d %H:%M:%S')
...
0 2015.11.05 00:00:00 2015.11.30 23:59:59
1 2015.12.01 00:00:00 2015.12.31 23:59:59
2 2016.01.01 00:00:00 2016.01.31 23:59:59
3 2016.02.01 00:00:00 2016.02.29 23:59:59
4 2016.03.01 00:00:00 2016.03.07 00:00:00
>>>
"""
_current = since
_month = _current.month
while _current <= until:
if _current == since:
start = since
elif _month != _current.month:
stop = datetime(_current.year, _current.month, _current.day)
yield start, stop - timedelta(seconds=1)
_month = _current.month
start = stop
_current += timedelta(hours=24)
yield start, until
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment