How to change format from seconds to hh:mm:ss? - r

I need to transform a seconds to hh:mm:ss format in R.
I use the difftime() function to have the difference between two dates and I specify units="mins".
But for the final result, I want it as hh:mm:ss and not only by specifying hour, or minutes, o seconds.

Try using lubridate.
library(lubridate)
seconds_to_period(86400)
#[1] "1d 0H 0M 0S"
seconds_to_period(48000)
#[1] "13H 20M 0S"
Then format the date:
td <- seconds_to_period(86400)
sprintf('%02d %02d:%02d:%02d', day(td), td#hour, minute(td), second(td))
#[1] "01 00:00:00"

Try using hms package:
library(hms)
hms::as_hms(99)
#[1] 00:01:39

Related

Converting Lubridate Period Class Time to Time Stamp Format in R

My code reads in a .txt file that holds a series of time stamps in one column. I needed to account for daylight savings for the column, so I used the lubridate package to subtract an hour from these time stamps. I'm struggling with converting the period class from lubridate back into a time format of %I:%M%:S %p.
Here is my code.
# Changing from 24 Hr to 12 Hr Format #
raw_data_sample$Time <- format(strptime(raw_data_sample$Time, format='%H:%M:%S'), '%I:%M:%S %p')
# Subtracting an Hour for Daylight Savings
raw_data_sample$Time <- hms(raw_data_sample$Time)
raw_data_sample$Time <- raw_data_sample$Time - hours(1)
Here is my current output.
c("1H 41M 54S", "1H 42M 4S", "1H 42M 14S", "1H 42M 31S", "1H 42M 41S", "1H 43M 1S")
I'm hoping to get an output like
1:41:54 PM, 1:42:40 PM
Any advice? Thank you!
You can use parse_date_time function to convert your period object to POSIXct then use format to get in your suitable format.
library(lubridate)
raw_data_sample$Time1 <- format(parse_date_time(raw_data_sample$Time, 'HMS'), '%I:%M:%S %p')
For example,
x <- period(c("1H 41M 54S", "1H 42M 4S", "1H 42M 14S", "1H 42M 31S", "1H 42M 41S", "1H 43M 1S"))
format(parse_date_time(x, 'HMS'), '%I:%M:%S %p')
#[1] "01:41:54 AM" "01:42:04 AM" "01:42:14 AM" "01:42:31 AM" "01:42:41 AM" "01:43:01 AM"
If we need to subtract an hour, do this on the original datetime object, and then do the formatting
library(lubridate)
# // convert to Datetime class
raw_data_sample$Time <- as.POSIXct(raw_data_sample$Time, format = "%H:%M:%S")
# // subtract 1 hour from the Datetime and use format to change the format
format(raw_data_sample$Time %m-% hours(1), "%I:%M:%S %p")

Convert and round column of string times in h:m format to time

I have a column of "times" in string format in hour and minute (no seconds)
time ...
<char>
18:40
12:20
23:59
2:15
...
Is there a way to convert these into times and then round them down such that my data will look like this
time ...
<time>
18:00
12:00
23:00
2:00
...
POSIXct class needs both date and time, so if date is not provided it by default takes today's date. You can then use floor_date to round it down at the nearest hour.
library(lubridate)
floor_date(as.POSIXct(df$time, 'UTC', format = '%H:%M'), 'hour')
#[1] "2020-07-06 18:00:00 UTC" "2020-07-06 12:00:00 UTC" "2020-07-06 23:00:00 UTC"
#[4] "2020-07-06 02:00:00 UTC"
You can then use format to keep part that you are interested in.
format(floor_date(as.POSIXct(df$time, 'UTC', format = '%H:%M'), 'hour'), '%H:%M')
#[1] "18:00" "12:00" "23:00" "02:00"
A solution without date-time manipulation using regex :
sub(':.*', ':00', df$time)
#[1] "18:00" "12:00" "23:00" "2:00"
However, note that manipulating date and times using regex is probably not the best option.
data
df <- structure(list(time = c("18:40", "12:20", "23:59", "2:15")),
class = "data.frame", row.names = c(NA, -4L))
Maybe Period class in lubridate is what you need:
library(lubridate)
Parse periods with hour and minute
hm(df$time)
# [1] "18H 40M 0S" "12H 20M 0S" "23H 59M 0S" "2H 15M 0S"
Extract hours component
hour(hm(df$time))
# [1] 18 12 23 2
Create a new period object
hours(hour(hm(df$time)))
# [1] "18H 0M 0S" "12H 0M 0S" "23H 0M 0S" "2H 0M 0S"

How to convert charater to HH:MM:SS, even if we have more than 24h?

I have a datatable in R with some values of time in hours, minutes and seconds. This values are recognized as character and I want to convert them to time.
I've tried with the following functions, but I obtain the same results.
as.ITime(eventlog.dt$Duration)
as.difftime(eventlog.dt$Duration, units = "hours")
as.POSIXct(eventlog.dt$Duration, format = "%T")
If my data is this(character format):
12:45:12 72:56:12 05:13:36 162:14:12
I obtain:
12:45:12 NA 05:13:36 NA
I want to obtain this(time format):
12:45:12 72:56:12 05:13:36 162:14:12
The required format can only be a character class. If we need a time class, it needs to be converted properly
library(lubridate)
seconds_to_period(period_to_seconds(hms(v1)))
#[1] "12H 45M 12S" "3d 0H 56M 12S" "5H 13M 36S" "6d 18H 14M 12S"
If this needs to be converted to hours alone, convert to seconds and then divide by 3600
round(period_to_seconds(hms(v1))/3600)
data
v1 <- c("12:45:12", "72:56:12", "05:13:36", "162:14:12")

Parsing 12-hour times using lubridate

I'm trying to get my head around parsing 12-hour times using lubridate. If I run
library(lubridate)
times <- c("1:30 AM", "6:29 AM", "6:59 AM", "9:54 AM", "2:45 PM")
hm(times)
I get
[1] "1H 30M 0S" "6H 29M 0S" "6H 59M 0S" "9H 54M 0S" "2H 45M 0S"
Note that the AM/PM designation is not used. However, if if the time strings also includes a date then the parsing works
ymd_hm(paste("01-01-01", times))
[1] "2001-01-01 01:30:00 UTC" "2001-01-01 06:29:00 UTC"
[3] "2001-01-01 06:59:00 UTC" "2001-01-01 09:54:00 UTC"
[5] "2001-01-01 14:45:00 UTC"
It seems to me that the time parsing functions: hm, hms, ... doesn't recognize the AM/PM, but the date functions do. Is it possible to allow for 12-hour parsing without going through the dates?
[I know I can do this by parsing the strings but I was wondering it it was possible within lubidate]
The two objects belong to different classes each one designed for a specific purpose.
With the first function you create a period class object. This kind of class if designed to represent times, like time of a race, or "how many hours Bolt runs 100 meters?" 0 hours 0 minutes 9 seconds 58 and so on.
See:
a <- hm(times)
class(a)
[1] "Period"
attr(,"package")
[1] "lubridate"
The second object with the function ymd_hm creates an object of class:
b <- ymd_hm(paste("01-01-01", times))
class(b)
[1] "POSIXct" "POSIXt"
This class of object is designed to represent "time", in the sense of Gregorian calendar (or maybe other kind of calendars). It does parse also AM/PM that are vital to differentiate hours of the day in a 12 hours clock.

How to separate ":" in a time data

I have a time column in a database, where hours and minutes are separated by a ":". I would like to remove the ":" so that time field becomes numeric as I will use numeric time for some calculation.
Input:
X
00:00
01:15
02:30
Output:
X
0000
0115
0230
I am new to R. My apologies if this is a silly question. Greatly appreciate any help. Thank you.
> x <- c("00:00", "01:15", "02:30")
> gsub(":", "", x)
[1] "0000" "0115" "0230"
If you really want numbers you can coerce to numeric or integer
> as.numeric(gsub(":", "", x))
[1] 0 115 230
GSee's answer does what you ask. However, if you're doing arithmetic with units of time, you might think about some easier ways.
library(lubridate)
X <- hm(c("00:00", "01:15", "02:30")) # Converts to lubridate time objects
X + minutes(1)
# [1] "1M 0S" "1H 16M 0S" "2H 31M 0S"
X + weeks(2)
# [1] "14d 0H 0M 0S" "14d 1H 15M 0S" "14d 2H 30M 0S"
It might be more sensible to use the R facilities for time parsing to convert first to date-time. At the moment you will have no way to capture the non-decimal character of your "time" values. 300-259 should be 1 , not 41. This set of commands illustrates some of R's date-time and Date functions:
> X <- c('00:00', '01:15', '02:30')
> as.POSIXct(X, format="%H:%M")
[1] "2013-08-05 00:00:00 PDT" "2013-08-05 01:15:00 PDT" "2013-08-05 02:30:00 PDT"
This will give the results in differences in seconds from midnight today:
> as.numeric(as.POSIXct(X, format="%H:%M") - as.POSIXct("2013-08-05 00:00:00 PDT"))
[1] 0 4500 9000
Now try to use todays's date, but then notice that there is an offset of 7 hours because as.POSIXct will assume this is GMT.UCT time:
> as.numeric(as.POSIXct(X, format="%H:%M") - as.POSIXct(Sys.Date()))
[1] 7.00 8.25 9.50
> as.numeric(as.POSIXct(X, format="%H:%M") - (as.POSIXct(Sys.Date())+7*3600))
[1] 0 4500 9000
So finish off the process by shifting 7 hours (=7*3600 seconds) and then converting to minutes:
> as.numeric(as.POSIXct(X, format="%H:%M") - (as.POSIXct(Sys.Date())+7*3600))/60
[1] 0 75 150

Resources