'Extract time (HMS) from lubridate date time object?

I have the following datetime:

t <- "2018-05-01 23:02:50 UTC"

I want to split it to time and date.

When I apply date(t) I get the date part. But when I use lubridate's hms, parse_date_time and other functions to do this in "HMS" order I get NA.

I have checked other answers here on SOF but for some reason it gives me NA.

Please advise how to extract it.

I want to understand why:

strftime(t, format="%H:%M:%S") 

will do the job but what I am missing in lubridate::hms or parse_date_time?



Solution 1:[1]

My solution is to install library(anytime):

date <- anytime::anydate(t)
time <- strftime(t, format="%H:%M:%S")

Solution 2:[2]

Is this what you were looking for? It can now be done more simply with hms::as_hms.

> library(lubridate)
> library(hms)
> as_hms(ymd_hms("2018-05-01 23:02:50 UTC"))
23:02:50

> t <- "2018-05-01 23:02:50 UTC"
> as_hms(ymd_hms(t))
23:02:50

Solution 3:[3]

What you are missing in lubridate's hms() is that it expects "a character vector of hour minute second triples" as an argument. There's no provision for handling a string which also contains date info. Hence, the output of Sys.Date() or lubridate::now() doesn't work as input to lubridate::hms().

In case you want a tidyverse solution, here's one:

library(tidyverse)
library(lubridate)

now()
#> [1] "2018-08-13 16:41:31 BST"

get_time <- function(time = now()) {
  time %>%
    str_split(" ") %>%
    map_chr(2) %>%
    hms()
}

get_time()
#> [1] "16H 41M 31S"

get_time("2018-05-01 23:02:50 UTC")
#> [1] "23H 2M 50S"

Created on 2018-08-13 by the reprex package (v0.2.0).

Solution 4:[4]

Something like this?

  library(hms)
    t <- "2018-05-01 23:02:50 UTC"
    unlist(strsplit(t," "))[2]%>%hms::parse_hms()

Solution 5:[5]

Here is a solution without including just another package (hms on top of lubridate):

t <- "2018-05-01 23:02:50 UTC"

sprintf("%02d:%02d:%02d", hour(t), minute(t), second(t))

"23:02:50"

Solution 6:[6]

Posting a solution that I have used to extract either ymd or the hms independently after a lubridate conversion. I noticed OP mentioned wanting to separate both time and date so for future SO users who may find themselves here I included the regex's used for both below. assuming df contains a column called date where time is formated ymd_hms like so "2018-05-01 23:02:50 UTC":

library(stringr)
df <- df %>%
   mutate(
    time = str_extract(date, "[0-9]{2}:[0-9]{2}:[0-9]{2}") #to extract hms time
    day = str_extract(date, "[0-9]{4}-[0-9]{2}-[0-9]{2}") #to extract ymd time
)

Solution 7:[7]

The fucntion in Lubridate package exists, it is called "hour()", here the official guide: https://lubridate.tidyverse.org/reference/hour

t <- "2018-05-01 23:02:50 UTC"

lubridate::hour(t)

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 J_F
Solution 2 Susie Derkins
Solution 3
Solution 4 jyjek
Solution 5 Sinval
Solution 6 milo
Solution 7 Andrea