TAGS :Viewed: 13 - Published at: a few seconds ago

[ Apply a character variable of time zones to individual date time values parsed in lubridate ]

I would like to use lubridate to parse character strings into datetimes in different time zones.

I have a data frame with character variables for local date times and Olson time zone. Is it possible to have lubridate take the time zone character string from the data frame for each row of data while parsing? Alternatively, forcing the time zone after parsing would meet my needs as well.

# Example data
df <- data.frame(fly = factor(c("AKL-SFO", "SFO-JFK")), 
                 dpt = c("2013-05-20 19:40:00", "2013-05-20 16:00:00"), 
                 dtz = c("Pacific/Auckland", "America/Los_Angeles"), 
                 stringsAsFactors = FALSE)

# Load required package
require(lubridate)

# try to set tz during parsing
df$dtdep <- ymd_hms(df$dpt) # parses to default UTC
df$dtdep2 <- ymd_hms(df$dpt, tz = "dtz") # parses to GMT and errors x4
# Warning messages:
# 1: In as.POSIXct.POSIXlt(lt) : unknown timezone 'dtz'
# 2: In as.POSIXlt.POSIXct(ct) : unknown timezone 'dtz'
# 3: In as.POSIXct.POSIXlt(t) : unknown timezone 'dtz'
# 4: In as.POSIXlt.POSIXct(ct) : unknown timezone 'dtz'
df$dtdep2 # returns[1] "2013-05-20 19:40:00 GMT" "2013-05-20 16:00:00 GMT"
# Warning message: In as.POSIXlt.POSIXct(x, tz) : unknown timezone 'dtz'

df$dtdep3 <- ymd_hms(df$dpt, tz = paste(df$dtz)) 
# Warning messages:
# 1: In if (tz != "UTC") { :
#   the condition has length > 1 and only the first element will be used
# 2: In if (!is.na(new.tz)) attr(date, "tzone") <- new.tz :
#   the condition has length > 1 and only the first element will be used
# Error in as.POSIXlt.POSIXct(x, tz) : invalid 'tz' value
df$dtdep3 # Error in as.POSIXlt.POSIXct(x, tz) : invalid 'tz' value

I followed a similar path trying to change the tz with force_tz() after parsing all data into UTC datetimes.

# try to change tz after parsing with force_tz()
df$ftz <- force_tz(df[1, "dtdep" ], tz = "Pacific/Auckland") # turns all into NZST of first row
df$ftz1 <- force_tz(df$dtdep, tz = "dtz") # gives same 4 errors as above and returns GMT 
df$ftz1 # Warning message: In as.POSIXlt.POSIXct(x, tz) : unknown timezone 'dtz'
df$ftz2 <- force_tz(df$dtdep, tz = df$dtz) # turns all into NZST.
# Warning message: In if (!is.na(new.tz)) attr(date, "tzone") <- new.tz :   the condition has length > 1 and only the first element will be used
# df$ftz3 <- force_tz(df$dtdep, tz = paste(df$dtz)) is the same as ftz2.

Maybe using plyr or a for loop would allow me to parse into different time zones? I am new to R and after much trial and error with both plyr and for loops I couldn't get it to work. Any help is gratefully appreciated.

I am using R v3.0.2 w RStudio v0.97.551 on Windows 7 pro (64 bit) and lubridate v1.3.3.

Answer 1


Could try:

library(lubridate)
## list seems better at preserving POSIXct class
trial <- list()
for (i in 1:nrow(df))
  trial[[i]] <- ymd_hms(df$dpt[i], tz = df$dtz[i], locale = "en_US")