lubridate icon indicating copy to clipboard operation
lubridate copied to clipboard

Periods are not automatically normalised

Open mem48 opened this issue 5 years ago • 6 comments

When adding periods, values don't increment across seconds minutes hours etc. For example, adding 45 + 16 minutes returns 61 minutes, not 1 hour 1 minute

library(lubridate)
p1 <- as.period(hms("23:45:00"))
p2 <- as.period(hms("00:16:00"))
p3 <- seconds(60*16)
p1 + p3
#"23H 45M 960S"
p1 + p2
#"23H 61M 0S"

mem48 avatar Mar 14 '19 16:03 mem48

Is there any update on this issue? If the above is the expected output, then ok, but I think most users will find this result surprising. As pointed out by a twitter user, it's possible to force the incrementing by adding

as.period(p1 + p2, unit = 'hours')

Thanks!

alastairrushworth avatar Oct 26 '19 17:10 alastairrushworth

It's not clear to me that this is a bug.

hadley avatar Oct 26 '19 17:10 hadley

Hi @hadley. I don't think it's a bug either, but I think most users might expect the larger units to increment as you add a sufficiently large number of smaller units. The above example might seem innocuous, but if you perform the addition many times (similar to my use case):

p1 <- as.period(hms("23:45:00"))
p2 <- as.period(hms("00:16:10"))

p1 + 1000 *  p2
[1] "23H 16045M 10000S"

It seems a bit wild to me to still be reporting 23H in there. Though, maybe there is already another way to do this in lubridate that doesn't involve periods.

Thanks!

(Thanks for the great pkg btw, not sure where I'd be without lubridate)

alastairrushworth avatar Oct 26 '19 17:10 alastairrushworth

As @alastairrushworth said, I would expect the hour to increment so that the times where in a human readable format. I can't think of a use case where "23H 45M 960S" is a preferable result to "24H 1M".

mem48 avatar Oct 26 '19 22:10 mem48

I think it would be reasonable to have a function that automatically created a human readable format, but I don't think it should be a done by default as it would be a big change from the existing behaviour (e.g. lubridate::period(hour = 30, minutes = 120))

hadley avatar Oct 27 '19 17:10 hadley

@hadley that would be very helpful. In the meantime the as.period(unit = "hours") will have to do.

mem48 avatar Oct 28 '19 08:10 mem48