I have a datetime.datetime
instance, d
and a datetime.timedelta
instance td
and am attempting to write a function that will break apart the range (d, d+td)
into [(d,x1),(x1,x2),...,(xn,d+td)]
with the xn
variables all being aligned to the hour.
For example, if
d = datetime.datetime(2012, 9, 8, 18, 53, 34)
td = datetime.timedelta(hours=2, minutes=34, seconds=5)
I desire a list of
[(datetime.datetime(..., 18, 53, 34), datetime.datetime(..., 19, 0, 0)),
(datetime.datetime(..., 19, 0, 0), datetime.datetime(..., 20, 0, 0)),
(datetime.datetime(..., 20, 0, 0), datetime.datetime(..., 21, 0, 0)),
(datetime.datetime(..., 21, 0, 0), datetime.datetime(..., 21, 27, 39))]
Can anyone suggest a nice, Pythonic, means of accomplishing this?
Using dateutil, you could generate the list using an rrule:
import dateutil.rrule as rrule
import datetime
def hours_aligned(start, end, inc = True):
if inc: yield start
rule = rrule.rrule(rrule.HOURLY, byminute = 0, bysecond = 0, dtstart=start)
for x in rule.between(start, end, inc = False):
yield x
if inc: yield end
d = datetime.datetime(2012, 9, 8, 18, 53, 34)
td = datetime.timedelta(hours=2, minutes=34, seconds=5)
for x in hours_aligned(d,d+td):
print(x)
yields
2012-09-08 18:53:34
2012-09-08 19:00:00
2012-09-08 20:00:00
2012-09-08 21:00:00
2012-09-08 21:27:39
chunks = []
end = d + td
current = d
# Set next_current to the next hour-aligned datetime
next_current = (d + datetime.timedelta(hours=1)).replace(minute=0, second=0)
# Grab the start block (that ends on an hour alignment)
# and then any full-hour blocks
while next_current < end:
chunks.append( (current, next_current) )
# Advance both current and next_current to the following hour-aligned spots
current = next_current
next_current += datetime.timedelta(hours=1)
# Grab any remainder as the last segment
chunks.append( (current, end) )
The main assumption here is that your initial specified timedelta is not negative. You'll get a single-chunk list [(x,y)]
where y < x
if you do that.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With