如何解决将UTC日期时间转换为带有时区的本地日期时间
我有一个包含start_time
和timezone
列的数据框(如下所示的示例)。 start_time
以UTC记录。我想创建一个名为start_time_local
的新列,其中包含该记录在本地时区内的开始时间。
我尝试了很多示例,包括format()
,force_tz()
,with_tz()
等,但是我见过的大多数示例都展示了如何将所有时间戳转换为相同时区,而不是每个时间戳分别为其相应的时区
+---------------------+---------------------+
| start_time | timezone |
+---------------------+---------------------+
| 2020-07-07 16:01:15 | Europe/Dublin |
| 2020-07-07 21:01:28 | America/Los_Angeles |
| 2020-07-20 12:45:33 | America/New_York |
| 2020-07-24 16:00:32 | America/Los_Angeles |
| 2020-07-09 14:00:39 | Europe/London |
| 2020-07-16 20:30:30 | America/Los_Angeles |
| 2020-07-29 14:03:09 | Europe/London |
| 2020-07-27 20:59:32 | America/Los_Angeles |
| 2020-07-20 16:09:54 | America/Denver |
| 2020-07-21 09:51:04 | Europe/Dublin |
+---------------------+---------------------+
# example data
df <- structure(list(start_time = structure(c(1594162875,1594180888,1595274333,1595631632,1594328439,1594956630,1596056589,1595908772,1595286594,1595350264),class = c("POSIXct","POSIXt"),tzone = ""),timezone = c("Europe/Dublin","America/Los_Angeles","America/New_York","Europe/London","America/Denver","Europe/Dublin")),row.names = c(NA,-10L),class = "data.frame")
解决方法
不幸的是,在单个POSIXct向量中不能有不同的时区,因为时区是作为应用于整个向量的单个原子属性存储的。如果您尝试对此属性写入多个时区,则POSIXct的S3方法将停止工作。
如果您热衷于此,可以编写一个新的S3类来处理此类问题。这样一类的裸露骨头看起来像这样:
POSIX_multi_tz <- function(UTC_times,time_zones)
{
structure(as.numeric(UTC_times),class = c("POSIXmulti","POSIXt"),tz = time_zones)
}
format.POSIXmulti <- function(x,...)
{
unlist(mapply(function(a,b) {
format(as.POSIXct(a,origin = "1970-01-01"),tz = b,usetz = TRUE)
},a = x,b = attr(x,"tz"),SIMPLIFY = FALSE))
}
print.POSIXmulti <- function(x,...)
{
print(format(x,...))
}
这将允许以下行为:
df$new_time <- POSIX_multi_tz(df$start_time,df$timezone)
df
#> start_time timezone new_time
#> 1 2020-07-08 00:01:15 Europe/Dublin 2020-07-08 00:01:15 IST
#> 2 2020-07-08 05:01:28 America/Los_Angeles 2020-07-07 21:01:28 PDT
#> 3 2020-07-20 20:45:33 America/New_York 2020-07-20 15:45:33 EDT
#> 4 2020-07-25 00:00:32 America/Los_Angeles 2020-07-24 16:00:32 PDT
#> 5 2020-07-09 22:00:39 Europe/London 2020-07-09 22:00:39 BST
#> 6 2020-07-17 04:30:30 America/Los_Angeles 2020-07-16 20:30:30 PDT
#> 7 2020-07-29 22:03:09 Europe/London 2020-07-29 22:03:09 BST
#> 8 2020-07-28 04:59:32 America/Los_Angeles 2020-07-27 20:59:32 PDT
#> 9 2020-07-21 00:09:54 America/Denver 2020-07-20 17:09:54 MDT
#> 10 2020-07-21 17:51:04 Europe/Dublin 2020-07-21 17:51:04 IST
尽管要注意-您仍然需要做一些工作才能以使用POSIXct对象的方式使用此类。您仍然可以使用算术函数来添加和减去秒,但是如果您使用lubridate
包或类似的包,则除非定义了各种Ops
来处理添加持续时间,否则许多方法都不适用于此类。时间段等。
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。