I have the following code below.
I would like to roundup TIME to the nearest 30 minutes in the hour. For example: 12:00PM or 12:30PM and so on.
EASTE
to round forward you can use :
#!/usr/bin/env python3
from datetime import datetime, timedelta
def ceil_dt(dt, delta):
return dt + (datetime.min - dt) % delta
now = datetime.now()
print(now)
print(ceil_dt(now, timedelta(minutes=30)))
To round back to the nearest 30th minute
def rounded_to_the_last_30th_minute_epoch():
now = datetime.now()
rounded = now - (now - datetime.min) % timedelta(minutes=30)
return rounded
>>> from dateutil.rrule import rrule, MINUTELY
>>> import datetime
>>> import bisect
>>> times = list(rrule(MINUTELY,interval=30,dtstart=datetime.date.today(),count=
48))
>>> print times[bisect.bisect(times,datetime.datetime.now())]
2015-09-22 11:00:00
>>>
Note that this solution uses the 3rd party dateutil library that can be installed with pip install dateutil
... Of course, you could solve it without it... but it's easier with it.
you can just take datetime input apart and ajust time
def ajustTime():
from datetime import datetime
mytime= datetime.now().strftime("%Y-%m-%d %H-%M")
m = mytime.split()
hours, mints = m[1].split('-')
if 15 <= int(mints) <= 45:
mints = ':30'
elif int(mints) < 15:
mints = ':00'
elif int(mints) > 45:
mints = ':00'
h = int(hours) + 1
hours = str(h)
print(m[0] + " " + hours + mints)
ajustTime()
output
2015-09-22 15:42:03.587633
2015-09-22 15:30
2015-09-22 15:46:01.956860
2015-09-22 16:00
To round up to the nearest 30 minutes:
#!/usr/bin/env python3
from datetime import datetime, timedelta
def ceil_dt(dt, delta):
return dt + (datetime.min - dt) % delta
now = datetime.now()
print(now)
print(ceil_dt(now, timedelta(minutes=30)))
The formula is suggested by @Mark Dickinson (for a different question).
2015-09-22 19:08:34.839915
2015-09-22 19:30:00
Note: if the input is timezone-aware datetime object such as EASTERN_NOW
in your case then you should call timezone.make_aware(rounded_dt.replace(tzinfo=None))
if you want to preserve the rounded local time and to attach the correct tzinfo, otherwise you may get wrong timezone info if the rounding crosses DST boundaries. Or to avoid failing for ambiguous local time, call .localize()
manually:
localize = getattr(rounded_dt.tzinfo, 'localize', None)
if localize:
rounded_dt = localize(rounded_dt.replace(tzinfo=None),
is_dst=bool(rounded_dt.dst()))
You can divide your minutes by 30, round that and multiply by 30 again to get either 0, 30 or 60 minutes:
date = datetime.datetime(2015, 9, 22, 12, 35)
approx = round(date.minute/30.0) * 30
date = date.replace(minute=0)
date += datetime.timedelta(seconds=approx * 60)
time = date.time()
print(time.strftime('%H:%M'))
# prints '13:30'
I'm using a datetime object because timedelta doesn't work with time objects. In the end you can obtain the time using date.time()
.
To round down:
Or, in words, using the number of whole intervals (x) there are in the current minutes, replace the minutes by that number of intervals (x * interval):
#!/usr/bin/env python3
def floor_dt(dt, interval):
replace = (dt.minute // interval)*interval
return dt.replace(minute = replace, second=0, microsecond=0)
print(datetime.now())
# datetime.datetime(2019, 5, 30, 22, 25, 31, 115901)
print(floor_dt(datetime.now(),30))
# datetime.datetime(2019, 5, 30, 22, 0)
print(datetime.now())
# datetime.datetime(2019, 5, 30, 22, 26, 29, 469555)
print(floor_dt(datetime.now(),10))
# datetime.datetime(2019, 5, 30, 22, 20)