Inputting multiple timezones into lubridate.

I have a vector of dates I am trying to cast into datetime using lubridate. Some of these are in different timezones, so I have another variable of the same length using appropriate timezones.

By default, it seems like lubridate tz does not deal with getting a vector input:

library(lubridate)
test = rep(as.character(Sys.time()), 3)
timezones = c('GMT', 'US/Pacific', 'US/Pacific')
ymd_hms(test, tz = timezones)

This produces the following error:

Error in C_force_tz(time, tz = tzone, roll) : 
  `tz` argument must be a single character string
In addition: Warning message:
In if (tz != "UTC") { :
  the condition has length > 1 and only the first element will be used

I believe there is an lapply solution, and I can conjure up a for loop for this, but I'm convinced there's an elegant way to do this!

Update: I've been working on this, and have a clunky for loop solution, as well as quite a few that surprisingly don't work.
We've established this one:

library(lurbidate)
time = rep(as.character(Sys.time()), 3)
timezones = c('GMT', 'US/Pacific', 'US/Pacific')

# Doesn't work: 
ymd_hms(time, tz = timezones)

This doesn't do the timezone right:

# Doesn't work either: 
b = mapply(ymd_hms, a$time, a$timezones)

Neither does mutate:


a = data.frame(time, timezones, stringsAsFactors = FALSE)

# doesn't work. 

mutate(a, ymd_hms(time, tz = timezones))

This clunky for loop does, though:

a = data.frame(time, timezones, stringsAsFactors = FALSE)
a$time_cast = ymd_hms(a$time)

# This works! 
for (count in 1:nrow(a)){
  tz(a$time_cast[count]) =  a$timezones[count] 
}
a

a$time_cast

For now I'm going to continue my work with this, but appreciate any and all ways to NOT be doing this :slight_smile:

Not sure it is less clunky:

library(lubridate)
#> 
#> Attaching package: 'lubridate'
#> The following object is masked from 'package:base':
#> 
#>     date
test = rep(as.character(Sys.time()), 3)
timezones = c('GMT', 'US/Pacific', 'US/Pacific')

SetTZ <- function(.x, .y) {
  .x <- ymd_hms(.x)
  tz(.x) <- .y
  .x
}
TZ <- purrr::map2(test, timezones, SetTZ)
TZ
#> [[1]]
#> [1] "2019-04-04 12:23:48 GMT"
#> 
#> [[2]]
#> [1] "2019-04-04 12:23:48 PDT"
#> 
#> [[3]]
#> [1] "2019-04-04 12:23:48 PDT"

Created on 2019-04-04 by the reprex package (v0.2.1)

This works, you just need to use rowwise()

library(lubridate)
library(dplyr)

df <- data.frame(stringsAsFactors = FALSE,
                 test = rep(as.character(Sys.time()), 3),
                 timezones = c('GMT', 'US/Pacific', 'US/Pacific'))
df %>%
    rowwise() %>% 
    mutate(date = ymd_hms(test, tz = timezones))
#> Source: local data frame [3 x 3]
#> Groups: <by row>
#> 
#> # A tibble: 3 x 3
#>   test                timezones  date               
#>   <chr>               <chr>      <dttm>             
#> 1 2019-04-04 20:09:14 GMT        2019-04-04 20:09:14
#> 2 2019-04-04 20:09:14 US/Pacific 2019-04-05 03:09:14
#> 3 2019-04-04 20:40:43 US/Pacific 2019-04-05 03:40:43
3 Likes

Thank you - I was missing the "rowwise"!

This topic was automatically closed 7 days after the last reply. New replies are no longer allowed.

If you have a query related to it or one of the replies, start a new topic and refer back with a link.