In R, use lubridate to convert hms objects into seconds - r

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

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"))

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>

Related

In R convert a list of numbers that represent time in hours to a POSIXct or Date variable format

I have a list of times that are an output of a model, these are in a decimal number format and represent the time from the start of the model running in hours, but they have not been given any units in the output, they are just numbers.
What I would like to do is convert these numbers into a date stamp format, using the numbers as hours the model has run. Specifically as either a POSIXct or Date variable so I can start use the Bupar library.
So for example I would like to convert 1.75, into 1 hour 45 minutes and 25.5 into a time that would equal 1 day 1 hour and 30 mins.
Thanks for any help
One possible way:
We could use seconds_to_period() function from lubridate after multiplying by 3600 to get seconds:
library(lubridate)
x <- 1.75
seconds_to_period(x*3600)
#[1] "1H 45M 0S"

lubridate - get hours and minutes from decimal hours

I have decimal hours in format 245.85 equalling to 245:51:00 in [hh]:mm:ss format.
I want to transform the decimal hours to hh:mm format, but how do I do it?
the original calculation that renders 245.85 is:
library(lubridate)
time_length(hm("7 27")*33,unit = "hours")
what I want is 245:51 or 245:51:00
If I use as.period I get days too - like in:
as.period(dhours(time_length(hm("7 27")*33,"hours")))
[1] "10d 5H 51M 0S"
and for background - my aim is to multiply hours and minutes (e.g. 7:27) by an arbitrary integer (e.g. 33) and get result back in hh:mm format - avoiding days (as in as.period example above). Say if a piece of work takes 7 hours and 27 minutes and we give me 33 pieces of such work to do per year, it should take me about this many work hours (and minutes) to do.
If it's really only the H:M:S format that gives you trouble, try
library(hms)
hms(hours=245.85)
which yields 245:51:00

Convert a decimal number to HH:MM:SS in R

I have a series of decimal numbers (marathon race split times): 64.90, etc., and I want to convert it into HH:MM:SS format using R so that I can us the result to do time math. The answer I am looking for is: 1:04:54.
chron doesn't seem to be doing what I'm expecting it to do.
chron::times(64.90)
Time in days:
[1] 64.9
First time on this site, so be kind. Thanks.
chron times are measured in days and since you apparently have minutes divide the input by the number of minutes in a day:
library(chron)
times(64.90 / (24 * 60))
## [1] 01:04:54
You could try lubridate::seconds_to_period
library(lubridate)
seconds_to_period(64.90)
[1] "1M 4.90000000000001S"
library(hms)
as.hms(64.90*60)
output
01:04:54

How to convert times over 24:00:00 in R

In R I have this data.frame
24:43:30 23:16:02 14:05:44 11:44:30 ...
Note that some of the times are over 24:00:00 ! In fact all my times are within 02:00:00 to 25:59:59.
I want to subtract all entries in my dataset data with 2 hours. This way I get a regular data-set. How can I do this?
I tried this
strptime(data, format="%H:%M:%S") - 2*60*60
and this work for all entries below 23:59:59. For all entries above I simply get NA since the strptime command produce NA to all entries above 23:59:59.
Using lubridate package can make the job easier!
> library(lubridate)
> t <- '24:43:30'
> hms(t) - hms('2:0:0')
[1] "22H 43M 30S"
Update:
Converting the date back to text!
> substr(strptime(hms(t) - hms('2:0:0'),format='%HH %MM %SS'),12,20)
[1] "22:43:30"
Adding #RHertel's update:
format(strptime(hms(t) - hms('2:0:0'),format='%HH %MM %SS'),format='%H:%M:%S')
Better way of formating the lubridate object:
s <- hms('02:23:58) - hms('2:0:0')
paste(hour(s),minute(s),second(s),sep=":")
"0:23:58"
Although the answer by #amrrs solves the main problem, the formatting could remain an issue because hms() does not provide a uniform output. This is best shown with an example:
library(lubridate)
hms("01:23:45")
#[1] "1H 23M 45S"
hms("00:23:45")
#[1] "23M 45S"
hms("00:00:45")
#[1] "45S"
Depending on the time passed to hms() the output may or may not contain an entry for the hours and for the minutes. Moreover leading zeros are omitted in single-digit values of hours, minutes and seconds. This can result pretty much in a formatting nightmare if one tries to put that data into a common form.
To resolve this difficulty one could first convert the time into a duration with lubridate's as.duration() function. Then, the duration in seconds can be transformed into a POSIXct object from which the hours, minutes, and seconds can be extracted easily with format():
times <- c("24:43:30", "23:16:02", "14:05:44", "11:44:30", "02:00:12")
shifted_times <- hms(times) - hms("02:00:00")
format(.POSIXct(as.duration(shifted_times),tz="GMT"), "%H:%M:%S")
#[1] "22:43:30" "21:16:02" "12:05:44" "09:44:30" "00:00:12"
The last entry "02:00:12" would have caused difficulties if shifted_times had been passed to strptime().

Convert time from numeric to time format in R

I read data from an xls file. Apparently, the time is not in the right format. It is as follows (for example)
0.3840277777777778
0.3847222222222222
0.3854166666666667
Indeed, they should be
09:12
09:13
09:13
I don't know how to convert it to the right format. I searched several threads and all of them are about converting the date (with/without time) to the right format.
Can somebody give me any clues?
You can use as.POSIXct after having multiplied your number by the number of seconds in a day (60 * 60 * 24)
nTime <- c(0.3840277777777778, 0.3847222222222222, 0.3854166666666667)
format(as.POSIXct((nTime) * 86400, origin = "1970-01-01", tz = "UTC"), "%H:%M")
## [1] "09:13" "09:14" "09:15"
Another option is times from chron
library(chron)
times(nTime)
#[1] 09:13:00 09:14:00 09:15:00
To strip off the seconds,
substr(times(nTime),1,5)
#[1] "09:13" "09:14" "09:15"
data
nTime <- c(0.3840277777777778, 0.3847222222222222, 0.3854166666666667)
For people who want the opposite way: given the 09:13:00, get 0.3840278
as.numeric(chron::times("09:13:00"))
Essentially, the idea is that one whole day is 1,so noon (12pm) is 0.5.

Resources