21

I have a vector of hours. For example:

vec.hours <- c("15:52:00", "15:56:00", "12:10:00", "15:12:00",  "11:49:00" ,"13:35:00", "14:53:00")

I would like to round the hours to get the new hours that will be the nearest whole 5 minutes, like this.

round.hours <- c("15:50:00", "16:00:00", "12:10:00", "15:10:00",  "11:50:00" ,"13:35:00", "14:55:00" )

I tried this

hour <- strptime(vec.hours , "%H:%M:%S")
round.hour <- round(hour , "mins")

But it isn't working.

After for each round.hours I want to do +/- one hour, for example like this:

hour.rd <- strptime(round.hours[1] , "%H:%M:%S")
hourM <- hour.rd - 3600
hourP <- hour.rd + 3600
l.tm <- timeSequence(from = hourM, to = hourP,format = "%H-%S-%M",by="5 min",FinCenter = "Europe/Zurich")

so, for 15:50:00 I have a vector of times from 14:50 until 16:50.

I dont know how to get round.hour from vec.hours.

Many thanks

Tali
  • 711
  • 3
  • 8
  • 15

4 Answers4

21

The Lubridate package has the very friendly round_date function.

round_date(hour,unit="5 minutes")

[1] "2017-08-28 15:50:00 UTC" "2017-08-28 15:55:00 UTC"
[3] "2017-08-28 12:10:00 UTC" "2017-08-28 15:10:00 UTC"
[5] "2017-08-28 11:50:00 UTC" "2017-08-28 13:35:00 UTC"
[7] "2017-08-28 14:55:00 UTC"
Glorfindel
  • 21,988
  • 13
  • 81
  • 109
groceryheist
  • 1,538
  • 17
  • 24
10

I would put the hours into datetime objects, convert these to POSIXlt, which allows you to access the minutes as integers, round using integer division, then extract the hours again.

timestamps <- as.POSIXlt(as.POSIXct('1900-1-1', tz='UTC') + as.difftime(vec.hours))
timestamps$min <- (timestamps$min + 5/2) %/% 5 * 5
format(timestamps, format='%H:%M:%S')
# [1] "15:50:00" "15:55:00" "12:10:00" "15:10:00" "11:50:00" "13:35:00" "14:55:00"
Matthew Plourde
  • 43,932
  • 7
  • 96
  • 113
2

From xts package you can use align.time

# align to next whole 5 min interval
align.time(hour, 5*60)
[1] "2013-06-14 15:55:00 CEST" "2013-06-14 16:00:00 CEST" "2013-06-14 12:15:00 CEST" "2013-06-14 15:15:00 CEST"
[5] "2013-06-14 11:50:00 CEST" "2013-06-14 13:40:00 CEST" "2013-06-14 14:55:00 CEST"

This will Change timestamps to the start of the next period, slightly different of the OP, which is to start to the nearest period.

agstudy
  • 119,832
  • 17
  • 199
  • 261
1

An alternative, based on the answers here - round after dividing by 300 (5 minutes * 60 seconds), then multiply the result by 300:

format(as.POSIXlt(as.POSIXct('2000-1-1', "UTC") + 
                    round(as.numeric(hours)/300)*300), 
       format = "%H:%M:%S")

#[1] "15:50:00" "15:55:00" "12:10:00" "15:10:00" "11:50:00" "13:35:00" "14:55:00"
Community
  • 1
  • 1
alexwhan
  • 15,636
  • 5
  • 52
  • 66