R从标准UTC时区更改为多个本地时区

时间:2018-12-07 19:01:48

标签: r datetime timezone posixct

假设我有一个df,其中包含对调查的一系列回复。每个响应在UTC中都有一个时间戳。我也碰巧对填写调查表的每个人都有当地时区。

例如:

 df <-  data.frame(day = c("2018-12-06 15:40:29", "2018-12-06 15:25:28", 
"2018-12-06 15:25:28", "2018-12-06 14:09:09"), time_zone = c("EST", "PST", "CST", "EST"))

df$day <- as.POSIXct(df$day, tz = "UTC")

对于要进行调查的人,我希望所有这些日期都能反映出当地时间。因此,我尝试了以下方法:

df %>% 
  mutate(time_start = format(day, tz = time_zone))

但是我得到Error in mutate_impl(.data, dots) : Evaluation error: invalid 'tz' value.

我还尝试使用时区为GTM格式的数据框

df<-  data.frame(day = c("2018-12-06 15:40:29", "2018-12-06 15:25:28", 
"2018-12-06 15:25:28", "2018-12-06 14:09:09"), 
time_zone = c("GMT-5", "GMT-6", "GMT-7", "GMT-8"))

是否可以将一系列标准时间更改为本地时间?

1 个答案:

答案 0 :(得分:0)

这里有多个问题

  1. format(以及其他与时间相关的函数)仅对tz采用长度为1的参数;
  2. R识别的
  3. 时区不包括流行的"CST""PST"等。

要解决第一个问题,只需使用Mapmapply

不幸的是,第二个需要更多的研究。像"PST"这样的区域,尽管在美国(如果不是其他国家/地区)至少在美国很受欢迎,但它们不是有效的时区字符串(参考:CCTZ,一个在时区之间进行转换的C ++库,says so)。 "GMT-7"等都没有,尽管prepending with Etc/可以伪造后者,例如:"Etc/GMT-7"。或者,您可以选择"America/New_York""US/Eastern"的替代方案。

df$time_zone <- c("US/Eastern", "US/Pacific", "US/Central", "US/Eastern")
df
#                   day  time_zone
# 1 2018-12-06 15:40:29 US/Eastern
# 2 2018-12-06 15:25:28 US/Pacific
# 3 2018-12-06 15:25:28 US/Central
# 4 2018-12-06 14:09:09 US/Eastern
mapply(format, df$day, tz = "GMT")
# [1] "2018-12-06 15:40:29" "2018-12-06 15:25:28" "2018-12-06 15:25:28"
# [4] "2018-12-06 14:09:09"
mapply(format, df$day, tz = df$time_zone)
# [1] "2018-12-06 10:40:29" "2018-12-06 07:25:28" "2018-12-06 09:25:28"
# [4] "2018-12-06 09:09:09"

R的时区的所有立即可识别格式都可以在594个元素的向量中找到:

str(OlsonNames())
#  chr [1:592] "Africa/Abidjan" "Africa/Accra" "Africa/Addis_Ababa" ...
#  - attr(*, "Version")= chr "2018e"
set.seed(2)
sample(OlsonNames(), size=8)
# [1] "America/El_Salvador"  "Etc/GMT+8"            "Atlantic/Madeira"    
# [4] "America/Creston"      "Pacific/Port_Moresby" "Pacific/Ponape"      
# [7] "America/Atka"         "GB-Eire"             
grep("US/", OlsonNames(), value = TRUE)
#  [1] "US/Alaska"         "US/Aleutian"       "US/Arizona"       
#  [4] "US/Central"        "US/East-Indiana"   "US/Eastern"       
#  [7] "US/Hawaii"         "US/Indiana-Starke" "US/Michigan"      
# [10] "US/Mountain"       "US/Pacific"        "US/Pacific-New"   
# [13] "US/Samoa"         

在此示例中,您将看到可以使用的替代方法之一:"Etc/GMT+8"。请注意,+位于本初子午线的西处,因此

mapply(format, df$day, tz = "US/Eastern")
# [1] "2018-12-06 10:40:29" "2018-12-06 10:25:28" "2018-12-06 10:25:28"
# [4] "2018-12-06 09:09:09"
mapply(format, df$day, tz = "Etc/GMT+5")
# [1] "2018-12-06 10:40:29" "2018-12-06 10:25:28" "2018-12-06 10:25:28"
# [4] "2018-12-06 09:09:09"

随行随行者:使用"US/Eastern"时应适当考虑夏令时;我相信"Etc/GMT+5"不会。