Reputation: 797
Is there a more elegant/pythonic way to do what the title says and this function does?
def split_datetime_range(start, end, split):
"""Splits a range of dates into a list of equal ranges
with remaining time allocated to the last of the series.
This function doesn't overlap dates, so seconds are lost
inbetween each range
Parameters:
start - The start of the range
end - The end of the range
split - How many ranges to produce
Returns:
A list of tuples, each tuple is its own range
"""
total_seconds = int((end - start).total_seconds())
delta = total_seconds / split
starts = [start + timedelta(seconds=delta * i) for i in range(split)]
ends = [s + timedelta(seconds=delta - 1) for s in starts]
ends[len(ends) - 1] = end
return zip(starts, ends)
edit -
one constraint is it has to be in 'seconds' resolution and not 'microseconds' resolution. The idea is to generate a list of date ranges to supply to a web service that accepts dates in iso8601 with seconds resolution
Upvotes: 1
Views: 2792
Reputation: 142146
You mentioned itertools
- so here's something you could play with - untested though:
from datetime import datetime
from itertools import count, islice
def datetime_range(start, end, number):
start_secs = (start - datetime(1970, 1, 1)).total_seconds()
end_secs = (end - datetime(1970, 1, 1)).total_seconds()
dates = [datetime.fromtimestamp(el) for el in islice(count(start_secs, (end_secs - start_secs) / number), number + 1)]
return zip(dates, dates[1:])
print datetime_range(datetime(2012, 1, 1), datetime(2012, 1, 30), 10)
Upvotes: 0
Reputation: 494
I am not sure if this meets your requirements.
>>> from datetime import *
>>> end = datetime.now()
>>> start = end - timedelta(30)
>>> start
datetime.datetime(2013, 6, 17, 18, 35, 17, 353000)
>>> end
datetime.datetime(2013, 7, 17, 18, 35, 17, 353000)
>>> d = (end- start) / 7
>>> d
datetime.timedelta(4, 24685, 714285)
>>> [(i * d + start, (i+1)*d+start) for i in range(7)]
[(datetime.datetime(2013, 6, 17, 18, 35, 17, 353000), datetime.datetime(2013, 6,
22, 1, 26, 43, 67285)), (datetime.datetime(2013, 6, 22, 1, 26, 43, 67285), date
time.datetime(2013, 6, 26, 8, 18, 8, 781570)), (datetime.datetime(2013, 6, 26, 8
, 18, 8, 781570), datetime.datetime(2013, 6, 30, 15, 9, 34, 495855)), (datetime.
datetime(2013, 6, 30, 15, 9, 34, 495855), datetime.datetime(2013, 7, 4, 22, 1, 0
, 210140)), (datetime.datetime(2013, 7, 4, 22, 1, 0, 210140), datetime.datetime(
2013, 7, 9, 4, 52, 25, 924425)), (datetime.datetime(2013, 7, 9, 4, 52, 25, 92442
5), datetime.datetime(2013, 7, 13, 11, 43, 51, 638710)), (datetime.datetime(2013
, 7, 13, 11, 43, 51, 638710), datetime.datetime(2013, 7, 17, 18, 35, 17, 352995)
)]
>>>
If you want the iso format without the milliseconds, given a datetime object 'now':
>>> now
datetime.datetime(2013, 7, 17, 19, 9, 1, 835000)
>>> now.strftime('%Y-%m-%dT%H:%M:%S')
'2013-07-17T19:09:01'
Upvotes: 1