24

I was trying to round off time to the nearest hour in python in a dataframe.

Suppose if a timestamp is 2017-11-18 0:16 it should come as 2017-11-18 0:00 and 2017-11-18 1:56 should round off as 2017-11-18 2:00

jpp
  • 159,742
  • 34
  • 281
  • 339
user123
  • 467
  • 1
  • 3
  • 10

6 Answers6

42

I experimented a bit with jpp but ended up with a different solution as adding one hour at hour 23 crashed the thing.

from datetime import datetime, timedelta

now = datetime.now()

def hour_rounder(t):
    # Rounds to nearest hour by adding a timedelta hour if minute >= 30
    return (t.replace(second=0, microsecond=0, minute=0, hour=t.hour)
               +timedelta(hours=t.minute//30))

print(now)
print(hour_rounder(now))

Returns:

2018-02-22 23:42:43.352133
2018-02-23 00:00:00
Anton vBR
  • 18,287
  • 5
  • 40
  • 46
18
import pandas as pd

pd.Timestamp.now().round('60min').to_pydatetime()

Returns:

datetime.datetime(2018, 2, 23, 0, 0)
Anton vBR
  • 18,287
  • 5
  • 40
  • 46
user123
  • 467
  • 1
  • 3
  • 10
12

This is one way.

from datetime import datetime

now = datetime.now()

def rounder(t):
    if t.minute >= 30:
        return t.replace(second=0, microsecond=0, minute=0, hour=t.hour+1)
    else:
        return t.replace(second=0, microsecond=0, minute=0)

now           # 2018-02-22 22:03:53.831589
rounder(now)  # 2018-02-22 22:00:00.000000
Anton vBR
  • 18,287
  • 5
  • 40
  • 46
jpp
  • 159,742
  • 34
  • 281
  • 339
  • 5
    Sorry for experimenting with your solution. I rolled it back. Basically I found that it would crash when hour 23 turned hour 24. I could have changed your solution but ended up posting my own. I gave you an upvote though. – Anton vBR Feb 22 '18 at 22:47
5

There is a general function to round a datetime at any time lapse in seconds here

Sample:

print roundTime(datetime.datetime(2012,12,31,23,44,59,1234),roundTo=60*60)
--> 2013-01-01 00:00:00
Le Droid
  • 4,534
  • 3
  • 37
  • 32
0

Here is one way to do it (based on another solution provided here)

def round_to_closest_hour(dttm):
    add_hour = True if dttm.minute >= 30 else False
    dttm = dttm.replace(second=0, microsecond=0, minute=0)
    if add_hour:
        dttm += timedelta(hours=1)
    return dttm

Basically, check if an hour is needed to be added or not (depending on whether it's past 30 minutes mark). Then reset minutes, seconds, microseconds and add an hour if required.

exAres
  • 4,806
  • 16
  • 53
  • 95
0

For those who need to change a whole column:

df = df['Timestamp'].dt.round('60min')

You can also use ceil() and floor() functions to replace round, depending on the rules you want to approximate.

Songhua Hu
  • 191
  • 2
  • 4