Convert time interval to number in R

Published on

Let’s say you have two time values in R, t1 and t2, and you want to compute the distance between them.

A natural thing to try would be

as.numeric(t1-t2)

This should probably return a number in seconds, but it might be in some other units, so you test just to be safe:

> as.numeric(as.POSIXct("2017-05-17 19:00:10")-as.POSIXct("2017-05-17 19:00:00"))
[1] 10

“Ok,” you think, “seconds it is,” and proceed to use an expression like the above in your code.

You just fell victim to an incredibly nasty “feature” of the R date/time API. The as.numeric and other similar functions actually choose the units based on the length of the interval by default:

> as.numeric(as.POSIXct("2007-05-07 09:00:10")-as.POSIXct("2007-05-07 09:00:00"))
[1] 10
> as.numeric(as.POSIXct("2007-05-07 09:10:00")-as.POSIXct("2007-05-07 09:00:00"))
[1] 10
> as.numeric(as.POSIXct("2007-05-07 19:00:00")-as.POSIXct("2007-05-07 09:00:00"))
[1] 10
> as.numeric(as.POSIXct("2007-05-17 09:00:00")-as.POSIXct("2007-05-07 09:00:00"))
[1] 10

To get a consistent behavior, you need to specify the units, e.g.:

> as.numeric(as.POSIXct("2007-05-17 09:00:00")-as.POSIXct("2007-05-07 09:00:00"), units="secs")
[1] 864000

The acceptable units values are "auto", "secs", "mins", "hours", "days", and "weeks".