Let's imagine this datetime
>>> import datetime
>>> dt = datetime.datetime(2012, 10, 25, 17, 32, 16)
I'd like to ceil it to the next quarter of hour, in order to get
datetime.datetime(2012, 10, 25, 17, 45)
I imagine something like
>>> quarter = datetime.timedelta(minutes=15)
>>> import math
>>> ceiled_dt = math.ceil(dt / quarter) * quarter
But of course, this does not work
This one takes microseconds into account!
import math
def ceil_dt(dt):
# how many secs have passed this hour
nsecs = dt.minute*60 + dt.second + dt.microsecond*1e-6
# number of seconds to next quarter hour mark
# Non-analytic (brute force is fun) way:
# delta = next(x for x in xrange(0,3601,900) if x>=nsecs) - nsecs
# analytic way:
delta = math.ceil(nsecs / 900) * 900 - nsecs
#time + number of seconds to quarter hour mark.
return dt + datetime.timedelta(seconds=delta)
t1 = datetime.datetime(2017, 3, 6, 7, 0)
assert ceil_dt(t1) == t1
t2 = datetime.datetime(2017, 3, 6, 7, 1)
assert ceil_dt(t2) == datetime.datetime(2017, 3, 6, 7, 15)
t3 = datetime.datetime(2017, 3, 6, 7, 15)
assert ceil_dt(t3) == t3
t4 = datetime.datetime(2017, 3, 6, 7, 16)
assert ceil_dt(t4) == datetime.datetime(2017, 3, 6, 7, 30)
t5 = datetime.datetime(2017, 3, 6, 7, 30)
assert ceil_dt(t5) == t5
t6 = datetime.datetime(2017, 3, 6, 7, 31)
assert ceil_dt(t6) == datetime.datetime(2017, 3, 6, 7, 45)
t7 = datetime.datetime(2017, 3, 6, 7, 45)
assert ceil_dt(t7) == t7
t8 = datetime.datetime(2017, 3, 6, 7, 46)
assert ceil_dt(t8) == datetime.datetime(2017, 3, 6, 8, 0)
Explanation of delta
:
nsecs / 900
is the number of quarter hour chunks that have transpired. Taking the ceil
of this rounds up the number of quarter hour chunks.