13

simple question in lubridate--I want to convert an hms object into its appropriate number of seconds since the start of the day.

For instance

library(lubridate)
hms("12:34:45")

then I want to know exactly how long 12 hours, 34 minutes, and 45 seconds is, in seconds

something obvious like

seconds(hms("12:34:45"))

just returns

45s

which is not what I want. How do I convert these hms values into seconds? I'd like to use lubridate

tomw
  • 3,114
  • 4
  • 29
  • 51

2 Answers2

37
R>lubridate::period_to_seconds(hms("01:00:00")) 

gives expected 3600 seconds as numeric counting from 00:00:00 or in the case above:

R>period_to_seconds(hms("12:34:45")) 
Steven Varga
  • 672
  • 1
  • 7
  • 10
12

It doesn't matter which package you use -- it will have convert a date / datetime object into a POSIXct representation of seconds since the epoch. So you may as well do it in base R -- so here deploy ISOdatetime() with an arbitrary day, using today:

R> difftime(ISOdatetime(2012,7,2,12,34,45), ISOdatetime(2012,7,2,0,0,0))
Time difference of 12.5792 hours

So we want seconds:

R> difftime(ISOdatetime(2012,7,2,12,34,45), ISOdatetime(2012,7,2,0,0,0), 
+          unit="secs")
Time difference of 45285 secs

And we can cast to numbers:

R> as.numeric(difftime(ISOdatetime(2012,7,2,12,34,45), +
                       ISOdatetime(2012,7,2,0,0,0), unit="secs"))
[1] 45285

Edit: And getting back to lubridate, this is arguably a bug:

> hms("12:34:45") - hms("00:00:00")
[1] 12 hours, 34 minutes and 45 seconds
R> as.numeric(hms("12:34:45") - hms("00:00:00"))
[1] 45
R>
Dirk Eddelbuettel
  • 360,940
  • 56
  • 644
  • 725
  • Yeah, this will be more accurate than just `as.duration` which (I think) simply converts each piece to the "default" number of seconds. In lubridate you'd have to convert it to an interval first, which is basically what you're doing here, I guess. – joran Jul 02 '12 at 17:47
  • lubridate does not invent new time types either so your suggested as.duration() may well work, or maybe a difference to hms("00:00:00"), or ... – Dirk Eddelbuettel Jul 02 '12 at 17:52
  • 1
    Late to the party but thought I'd throw in: `out <- as.POSIXct("12:34:45", format="%H:%M:%S",tz="UTC"); difftime(out,trunc(out,"day"),units="secs")` – thelatemail Aug 07 '15 at 04:26
  • `as.numeric(as.POSIXct(paste("1970-01-01", "12:34:45")))` – user3226167 Feb 17 '16 at 11:29