【发布时间】:2017-05-11 15:35:37
【问题描述】:
再一次,我在 R 中遇到日期和时间问题。 我有一个这样的数据集:
> dput(df)
structure(list(event.time.utc = structure(c(1471407324, 1489129025,
1480714809, 1471111613, 1472965336, 1484421419, 1475607466, 1475476528,
1473041225, 1487378311), class = c("POSIXct", "POSIXt"), tzone = ""),
time.verify = c("15:15:24", "16:57:05", "07:40:09", "05:06:53",
"16:02:16", "05:16:59", "05:57:46", "17:35:28", "13:07:05",
"10:38:31")), class = "data.frame", .Names = c("event.time.utc",
"time.verify"), row.names = c(NA, -10L))
> str(df)
'data.frame': 10 obs. of 2 variables:
$ event.time.utc: POSIXct, format: "2016-08-16 22:15:24" "2017-03-09 23:57:05" "2016-12-02 14:40:09" "2016-08-13 12:06:53" ...
$ time.verify : chr "15:15:24" "16:57:05" "07:40:09" "05:06:53" ...
我想将event.time.utc 转换为我的本地时区:美国/埃德蒙顿 (UTC-07:00)。变量time.verify 只是为了验证结果。首先,我验证了我的时区存在:
> tzfile <- "F:/PortableApps/R/R-3.4.0/share/zoneinfo/zone.tab"
> tzones <- read.delim(tzfile, row.names = NULL, header = FALSE,
+ col.names = c("country", "coords", "name", "comments"),
+ as.is = TRUE, fill = TRUE, comment.char = "#")
> tzones %>% filter(str_detect(name, "Edmonton"))
country coords name comments
1 CA +5333-11328 America/Edmonton Mountain - AB; BC (E); SK (W)
我还验证了我的默认时区:
> Sys.timezone()
[1] "America/Edmonton"
在我的操作系统上做同样的事情:
C:\Users\tspeidel>tzutil /g
Mountain Standard Time
好的,到目前为止,一切都很好。现在我想将event.time.utc 转换为我的时区:
> df$new.time <- as.POSIXct(df$event.time.utc, tz = "America/Edmonton")
> head(df)
event.time.utc time.verify new.time
1 2016-08-16 22:15:24 15:15:24 2016-08-16 22:15:24
2 2017-03-09 23:57:05 16:57:05 2017-03-09 23:57:05
3 2016-12-02 14:40:09 07:40:09 2016-12-02 14:40:09
4 2016-08-13 12:06:53 05:06:53 2016-08-13 12:06:53
5 2016-09-03 23:02:16 16:02:16 2016-09-03 23:02:16
6 2017-01-14 12:16:59 05:16:59 2017-01-14 12:16:59
这并没有产生我所期望的。我做错了什么?
更新 1 只是根据其中一个 cmets 中链接的帖子对此进行跟进:
> df$time.edmonton <- as.POSIXct(as.integer(df$event.time.utc), origin="1970-01-01", tz="America/Edmonton")
>
> df$time.la <- as.POSIXct(as.integer(df$event.time.utc), origin="1970-01-01", tz="America/Los_Angeles")
>
> df
event.time.utc time.verify time.edmonton time.la
1 2016-08-16 22:15:24 15:15:24 2016-08-16 22:15:24 2016-08-16 21:15:24
2 2017-03-09 23:57:05 16:57:05 2017-03-09 23:57:05 2017-03-09 22:57:05
3 2016-12-02 14:40:09 07:40:09 2016-12-02 14:40:09 2016-12-02 13:40:09
4 2016-08-13 12:06:53 05:06:53 2016-08-13 12:06:53 2016-08-13 11:06:53
5 2016-09-03 23:02:16 16:02:16 2016-09-03 23:02:16 2016-09-03 22:02:16
6 2017-01-14 12:16:59 05:16:59 2017-01-14 12:16:59 2017-01-14 11:16:59
7 2016-10-04 12:57:46 05:57:46 2016-10-04 12:57:46 2016-10-04 11:57:46
8 2016-10-03 00:35:28 17:35:28 2016-10-03 00:35:28 2016-10-02 23:35:28
9 2016-09-04 20:07:05 13:07:05 2016-09-04 20:07:05 2016-09-04 19:07:05
10 2017-02-17 17:38:31 10:38:31 2017-02-17 17:38:31 2017-02-17 16:38:31
更新 2 通过在日期时间向量上强制时区,我似乎更接近了一点:
df$event.time.utc <- force_tz(df$event.time.utc, tzone = "UTC")
df$time.edmonton <- as.POSIXct(as.integer(df$event.time.utc), origin="1970-01-01", tz="America/Edmonton")
df
event.time.utc time.verify time.edmonton
1 2016-08-16 22:15:24 15:15:24 2016-08-16 16:15:24
2 2017-03-09 23:57:05 16:57:05 2017-03-09 16:57:05
3 2016-12-02 14:40:09 07:40:09 2016-12-02 07:40:09
4 2016-08-13 12:06:53 05:06:53 2016-08-13 06:06:53
5 2016-09-03 23:02:16 16:02:16 2016-09-03 17:02:16
6 2017-01-14 12:16:59 05:16:59 2017-01-14 05:16:59
7 2016-10-04 12:57:46 05:57:46 2016-10-04 06:57:46
8 2016-10-03 00:35:28 17:35:28 2016-10-02 18:35:28
9 2016-09-04 20:07:05 13:07:05 2016-09-04 14:07:05
10 2017-02-17 17:38:31 10:38:31 2017-02-17 10:38:31
更新 3 非常接近,除了 DST 问题:
> df$time.edmonton <- format(df$event.time.utc, tz="America/Edmonton",usetz=TRUE)
> df
event.time.utc time.verify time.edmonton
1 2016-08-16 22:15:24 15:15:24 2016-08-16 16:15:24 MDT
2 2017-03-09 23:57:05 16:57:05 2017-03-09 16:57:05 MST
3 2016-12-02 14:40:09 07:40:09 2016-12-02 07:40:09 MST
4 2016-08-13 12:06:53 05:06:53 2016-08-13 06:06:53 MDT
5 2016-09-03 23:02:16 16:02:16 2016-09-03 17:02:16 MDT
6 2017-01-14 12:16:59 05:16:59 2017-01-14 05:16:59 MST
7 2016-10-04 12:57:46 05:57:46 2016-10-04 06:57:46 MDT
8 2016-10-03 00:35:28 17:35:28 2016-10-02 18:35:28 MDT
9 2016-09-04 20:07:05 13:07:05 2016-09-04 14:07:05 MDT
10 2017-02-17 17:38:31 10:38:31 2017-02-17 10:38:31 MST
【问题讨论】:
-
你期待什么?
-
我希望
new.time的时间部分与time.verify相同 -
即使我这样做:
df$new.time <- as.POSIXct(as.integer(df$event.time.utc), origin="1970-01-01", tz="America/Edmonton")它也不会改变。 -
我想我找到了一个很快就会发布的解决方案。这是因为没有定义您的时区。
-
这基本上是我的解决方案(明确定义时区)。您看到的其他差异是因为您在
time.verify中没有考虑夏令时。
标签: r datetime timezone posixct