问题描述:

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

网友答案:

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'
网友答案:

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)
相关阅读:
Top