16

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?

7 Answers 7

19

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
1
  • If you want to represent hour, minutes and seconds without a date, the hms package is a good answer. Using only lubridate, you can extract the hours, minutes and seconds from any date as a Period object using lubridate::hms(format(validation$time, "%H:%M:%S")). Period objects can then be added to a date object using the + operator. Commented Apr 21 at 19:33
8

My solution is to install library(anytime):

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

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

2

Something like this?

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

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

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

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)
1
  • hour() returns only the hour of the date-time object. hour("2024-03-04 14:21:25") returns just 14, not 14:21:25. Commented Apr 21 at 19:23

Not the answer you're looking for? Browse other questions tagged or ask your own question.