Convert multiple timezones in a variable using 'lubridate'

47 Views Asked by At

Data

I have a vector of times, each in different timezones e.g

x = c("2024-01-05 11:12:13 UTC", "2024-01-10 12:13:14 CET", "2024-01-15 07:08:09 EST")

Question

How can I get info about the timezone for each element and use it to convert these data into one "universal" timezone, e.g. "UTC"? Solutions using {base} or {lubridate} are preferred.

Attempt

dtf <- 
  tibble(
    x <- c("2024-01-05 11:12:13 UTC", "2024-01-10 12:13:14 CET", "2024-01-15 07:08:09 EST")
    y <- str_extract(x, "[^ ]+$")
  )
dtf %>% 
  map(
   y, ~ as_datetime(x, tz = y)
  )

which gives NULL values.

2

There are 2 best solutions below

0
VinceGreg On

Interesting. I don't know a lot about lubridate::as_date(), I prefere lubridate::ymd_hms(). In lubridate::ymd_hms() (or parse_date_time()) , the tz argument as to be of length one. You were in the right path with with map.

I did my example with with_tz(tzone="EST") to demonstrate an alternative to UTC representation.

library(tidyverse)
dtf <- 
  tibble(
    x <- c("2024-01-05 11:12:13 UTC", "2024-01-10 12:13:14 CET", "2024-01-15 07:08:09 EST")
    y <- str_extract(x, "[^ ]+$")
  )

map2(dtf$x, dtf$y, \(x,y) ymd_hms(x, tz= y) %>%
       with_tz(tzone="EST")) %>% 
  list_c()
0
Friede On

This, hopefully, serves as an R base approach getting you started.

x = c("2024-01-05 11:12:13 UTC", "2024-01-10 12:13:14 CET", "2024-01-15 07:08:09 EST")
Y = data.frame(t(list2DF(strsplit(x,"\\s+(?=[A-Z])", perl = TRUE)))) |> 
  setNames(c("tmp", "tzone")) #cosmetics
z = unname(Map(as.POSIXct, Y$tmp, Y$tzone)) # unname is cosmetics 

gives

> z 
[[1]]
[1] "2024-01-05 11:12:13 UTC"

[[2]]
[1] "2024-01-10 12:13:14 CET"

[[3]]
[1] "2024-01-15 07:08:09 EST"

> lapply(z, class)
[[1]]
[1] "POSIXct" "POSIXt" 

[[2]]
[1] "POSIXct" "POSIXt" 

[[3]]
[1] "POSIXct" "POSIXt" 

> lapply(z, attr, "tzone")
[[1]]
[1] "UTC"

[[2]]
[1] "CET"

[[3]]
[1] "EST"

(Couldn't think of something more concise than data.frame(t(list2DF(..))) yet.) Now you can accomplish your desired timezone conversion I suspect.