1

I'm trying to round a lubridate Period object to the nearest minute.

library(lubridate)
round_date(as.period("2d 20H 22M 9.57S"))

Gives

Error in as.POSIXct.numeric(x) : 'origin' must be supplied

So round_date is converting my period to a POSIXct, but why? Is it possible to round periods in lubridate without converting them to another format? Seems like I'm missing something simple.

Thanks!

blongworth
  • 337
  • 2
  • 10
  • as.period() requires a interval, difftime or numeric object of which the string "2d 20H 22M 9S" is non of the above. How are you generating "2d 20H 22M 9S"? – Morgan Ball Dec 16 '16 at 17:42
  • I was trying for the simplest reproducible example. – blongworth Dec 16 '16 at 20:06
  • `class(as.period("2d 20H 22M 9.57S"))` tells me it's a Period, and it produces the same error as the Period object I'm working with in my code. Did you try my example? – blongworth Dec 16 '16 at 20:08
  • How about: `round_date(Sys.time() - (Sys.time() - 5000))`? That's working directly on a difftime object and gives me the same error. – blongworth Dec 16 '16 at 20:21

3 Answers3

3

Since this issue was opened, it is now possible to round a lubridate Period as shown in this thread. Here is the example in your case :

library("lubridate")  
round(as.period("2d 20H 22M 9.57S"))  
[1] "2d 20H 22M 10S"
Quentin
  • 56
  • 3
2

According to ?round_date, the function expects as first argument a vector of date-time objects. Therefore, it isn't meant to be used on a period object.

An explanation why it isn't possible to round a period object in general can be found in ?as.period: The exact length of each time unit in a period will depend on when it occurs. [...] For example, when a leap second occurs one minute is longer than 60 seconds.

lubridate very carefully distinguishes between Duration, Interval, and Period classes.

Uwe
  • 41,420
  • 11
  • 90
  • 134
  • 1
    Definitely missed this in the docs. I think there's a need to round periods though, even if imperfectly. We should be able to answer the question, "About how long will it take?" programmatically. – blongworth Dec 29 '16 at 15:00
2

I definitely think that the best option is to convert it to numeric, that is to say, in seconds, divide it by 60 to make it minutes, then multiply by 60 to make it seconds, round it up and then period. And then you will get the nearest minute.

seconds_to_period(round(as.numeric(as.period("2d 20H 22M 9.57S"))/60)*60)
[1] "2d 20H 22M 0S"

If you want to approximate the seconds you can do the following

seconds_to_period(round(as.numeric(as.period("2d 20H 22M 9.57S"))))
[1] "2d 20H 22M 10S"
Rafael Díaz
  • 2,134
  • 2
  • 16
  • 32