【问题标题】:Trying to reverse-convert a vector of time zones试图反向转换时区向量
【发布时间】:2020-05-17 22:33:31
【问题描述】:

我有这个时间戳数据库 (AlertTime),并且我知道这些时间戳在哪个时区 (TimeZone)。我知道如何将这些日期设置为 POSIXCT 或者它们是否都是 UTC,但我很难将它们识别为本地时间戳,因为大多数函数不接受 tz 的向量。

我确实需要格式正确的本地时间戳 (AlertTimeLocal) 和等效的 UTC (AlertTimeUTC)。

AlertTime               TimeZone                AlertTimeLocal (desired)  AlertTimeUTC (desired)
11 May 2020, 06:22 PM   America/Denver          2020-05-11 18:22:00 MDT   2020-05-12 00:22:00 MDT
11 MAY 2020, 04:11 AM   America/Los_Angeles     2020-05-11 04:11:00 PDT   2020-05-11 11:11:00 UTC
10 MAY 2020, 03:38 PM   America/Chicago         2020-05-10 15:38:00 CDT   2020-05-10 20:38:00 CDT

我正在使用此代码,但它似乎不再执行任何操作:

FreshAir$AlertTimeLocal <- mapply(function(x,y) {format(x, tz=y, usetz=TRUE)}, FreshAir$AlertTime, FreshAir$TimeZone)

将所有 RAW 时间戳设置为 UTC,然后将它们转换为另一个方向的等效时区,是否会有一个 hacky 解决方案?

【问题讨论】:

  • 你可以试试force_tzs(dmy_hm(FreshAir$AlertTime), tzones = FreshAir$TimeZone)
  • 你在数据中的列名和code列名不匹配
  • 如果您错过了我的答案编辑,请注意您不能(很容易)在单个列中拥有不同的本地时区。
  • (1) 在我的回答中作为评论可能更合适。 (2) 我在回答中指出,一个向量中不能有不同的区域。您的回答 描述 所需的时间,但它们不是 OP 要求的:AlertTimeLocal 的时区是 UTC,而不是 OP 要求的 MDT、PDT 和 CDT。诚然,接受答案的 OP 已经结束了,但所要求的事情不会发生(很容易)。要了解我的意思,请尝试mutate(AlertTimeLocal = format(AlertTimeLocal, format = "%Y-%m-%d %H:%M:%S %Z"))

标签: r posixct


【解决方案1】:

我们可以从lubridate使用force_tzs

library(lubridate)
library(dplyr)
df1 %>%
    mutate(AlertTimeLocal = dmy_hm(AlertTime), 
           AlertTimeUTC = force_tzs(AlertTimeLocal, tzones = TimeZone))
# AlertTime            TimeZone      AlertTimeLocal        AlertTimeUTC
#1 11 May 2020, 06:22 PM      America/Denver 2020-05-11 18:22:00 2020-05-12 00:22:00
#2 11 MAY 2020, 04:11 AM America/Los_Angeles 2020-05-11 04:11:00 2020-05-11 11:11:00
#3 10 MAY 2020, 03:38 PM     America/Chicago 2020-05-10 15:38:00 2020-05-10 20:38:00

更新

如果我们需要存储为单独的时区,我们可以使用list

library(purrr)
df2 <- df1 %>%
         mutate(AlertTime2 = dmy_hm(AlertTime), 
         AlertTimeUTC = force_tzs(AlertTime2, tzones = TimeZone), 
         AlertTimeLocal = map2(AlertTime2, TimeZone, ~ force_tz(.x, tzone = .y))) 


df2$AlertTimeLocal
#[[1]]
#[1] "2020-05-11 18:22:00 MDT"

#[[2]]
#[1] "2020-05-11 04:11:00 PDT"

#[[3]]
#[1] "2020-05-10 15:38:00 CDT"

数据

df1 <- structure(list(AlertTime = c("11 May 2020, 06:22 PM",
       "11 MAY 2020, 04:11 AM", 
"10 MAY 2020, 03:38 PM"), TimeZone = c("America/Denver", 
"America/Los_Angeles", 
"America/Chicago")), class = "data.frame", row.names = c(NA, 
-3L))

【讨论】:

  • 谢谢,尽管您的没有 mutate 的版本似乎可以正常工作。还有FreshAir$AlertTime_UTC &lt;- force_tzs(dmy_hm(FreshAir$AlertTime), tzones = FreshAir$TimeZone) #Determine time in UTC FreshAir$AlertTime_Local &lt;- force_tzs(dmy_hm(FreshAir$AlertTime), tzones = "UTC") #Determine (formatted) time back in Local
  • @Adam 是的,它应该可以工作。我使用了mutate,因为以防万一,扩展链会更容易。想要。
【解决方案2】:

我认为一个整洁的解决方案可能看起来更干净,但如果你想要一个基本的 R 解决方案,这里有一个使用 @akrun 的 df1 的替代方案:

df1$AlertTimeLocal <- df1$AlertTimeUTC <- 
  c.POSIXct(Map(as.POSIXct, df1$AlertTime, tz = df1$TimeZone, format = "%d %b %Y, %I:%M %p"))
attr(df1$AlertTimeUTC, "tzone") <- "UTC"
attr(df1$AlertTimeLocal, "tzone") <- "US/Mountain"
df1
#               AlertTime            TimeZone        AlertTimeUTC      AlertTimeLocal
# 1 11 May 2020, 06:22 PM      America/Denver 2020-05-12 00:22:00 2020-05-11 18:22:00
# 2 11 MAY 2020, 04:11 AM America/Los_Angeles 2020-05-11 11:11:00 2020-05-11 05:11:00
# 3 10 MAY 2020, 03:38 PM     America/Chicago 2020-05-10 20:38:00 2020-05-10 14:38:00

还有一点没有讨论过:在 R 中,POSIXt 的一个向量内不能有不同的时区。也就是说,在向量中,时区是 vector 的属性,而不是元素的属性。如果您需要为该列中的每个时间设置单独的时区,则需要创建一个列表列。这很有效,但在 data.frame 上运行的实用程序/功能并不总是能很好地支持。

【讨论】:

  • 因为在 OP 中引用了"MDT"。它只是一个占位符,提醒 OP 不能(轻松)在列的每个元素中获得不同的时区。
  • 我不知道怎么说更好:在一个简单的向量(列)中,R 不允许单个元素使用不同的时区。 "tzone" 的属性应用于整个向量。因此,OP 中每行可以有不同的本地时区的前提是有缺陷的(假设是向量/列而不是列表列)。您能否在数据中获得不同的区域?
  • 我知道那部分。但是,我很好奇为什么您选择本地作为特定的,因为我在 OP 的帖子中没有找到关于该参考的内容
  • 问题是正确的:AlertTimeLocal (desired) 在标题行,2020-05-11 18:22:00 MDT 在下一行。然后是 CDT 和 PDT。所以我只使用了第一个,部分是为了说明我的观点。
  • 是的,那是第一行,但是后来是CDT,所以不清楚
猜你喜欢
  • 2018-04-17
  • 2012-08-16
  • 1970-01-01
  • 2015-11-12
  • 2017-07-11
  • 1970-01-01
  • 1970-01-01
  • 2015-04-17
  • 1970-01-01
相关资源
最近更新 更多