Simon Kemper
Simon Kemper

Reputation: 645

How to divide python datetime-span into equally spaced time-intervals?

I am having two dates, just like:

date_a = datetime.datetime(2016, 8, 9, 8, 24, 30, 993352)
date_b = datetime.datetime(2016, 8, 9, 7, 24, 30, 993352)

What I want is getting a list of timestamps with a five minute interval that lies between those two dates. With the above two dates the result would be:

five_min_timestamps = [
    datetime.datetime(2016, 8, 9, 7, 25, 0, 0)
    datetime.datetime(2016, 8, 9, 7, 30, 0, 0)
    datetime.datetime(2016, 8, 9, 7, 35, 0, 0)
    datetime.datetime(2016, 8, 9, 7, 45, 0, 0)
    datetime.datetime(2016, 8, 9, 7, 55, 0, 0)
    datetime.datetime(2016, 8, 9, 8, 00, 0, 0)
    datetime.datetime(2016, 8, 9, 8, 05, 0, 0)
    datetime.datetime(2016, 8, 9, 8, 10, 0, 0)
    datetime.datetime(2016, 8, 9, 8, 15, 0, 0)
    datetime.datetime(2016, 8, 9, 8, 20, 0, 0)
]

I am still trying to figure out how to implement a function (very pythonic) that puts out timestamps just like in the description above.

Requirement is that the range between those two dates (date_a and date_b) will be greater or less than in that example. So getting an interval between a whole day or even a week should be covered by that function.

Upvotes: 3

Views: 5018

Answers (3)

Raskayu
Raskayu

Reputation: 743

Defining a function that returns a list of intervals between low time a and top time b.

def print_time(a, b, inter):
   tmp = a + datetime.timedelta(0,interval) # sum an interval of inter secs
   list = []
   while tmp < b: 
       list.add(tmp)
       tmp = tmp + datetime.timedelta(0,interval) # sum the interval again
   return list

The result list will have datetimes separated by inter seconds.

Yield version suggested by Toby Speight:

def print_time(a, b, inter):
   tmp = a + datetime.timedelta(0,interval) # sum an interval of inter secs
   while tmp < b: 
       yield tmp
       tmp = tmp + datetime.timedelta(0,interval) # sum the interval again

Upvotes: 0

alecxe
alecxe

Reputation: 473863

You can also look into using rrule module from dateutil:

The rrule module offers a small, complete, and very fast, implementation of the recurrence rules documented in the iCalendar RFC, including support for caching of results.

Sample:

>>> import datetime
>>>
>>> date_a = datetime.datetime(2016, 8, 9, 8, 24, 30, 993352)
>>> date_b = datetime.datetime(2016, 8, 9, 7, 24, 30, 993352)
>>>
>>> from dateutil import rrule
>>>
>>> list(rrule.rrule(rrule.MINUTELY, interval=5, dtstart=date_b + datetime.timedelta(minutes=1), until=date_a))
[
    datetime.datetime(2016, 8, 9, 7, 25, 30), 
    datetime.datetime(2016, 8, 9, 7, 30, 30), 
    datetime.datetime(2016, 8, 9, 7, 35, 30), 
    datetime.datetime(2016, 8, 9, 7, 40, 30), 
    datetime.datetime(2016, 8, 9, 7, 45, 30), 
    datetime.datetime(2016, 8, 9, 7, 50, 30), 
    datetime.datetime(2016, 8, 9, 7, 55, 30), 
    datetime.datetime(2016, 8, 9, 8, 0, 30), 
    datetime.datetime(2016, 8, 9, 8, 5, 30), 
    datetime.datetime(2016, 8, 9, 8, 10, 30), 
    datetime.datetime(2016, 8, 9, 8, 15, 30), 
    datetime.datetime(2016, 8, 9, 8, 20, 30)
]

There is also the often-overlooked Delorean library which can make "a few stops".

Upvotes: 4

Igor Chubin
Igor Chubin

Reputation: 64563

Not extremely pythonic, but clean and concise:

from datetime import timedelta

delta = timedelta(minutes=5)
five_min_timestamps = []
date_x = date_a
while date_x < date_b:
  date_x += timedelta(minutes=5)
  five_min_timestamps.append(date_x) 

Another option is to use list comprehension:

 intervals = divmod((date_b - date_a).total_seconds(), 300)
 five_min_timestamps = [date_a + i * datetime.timedelta(minutes=5) for i in range(intervals)]

The intervals variable shows you, how many intervals in this timespan do you need (difference between the dates divided through 300).

Or with one statement:

five_min_timestamps = [
    date_a + i * datetime.timedelta(minutes=5)
    for i in range(
        divmod((date_b - date_a).total_seconds(), 300))]

Upvotes: 4

Related Questions