参考 `lubridate` 将 UTC date/time 调整为不同的时区
Adjusting UTC date/time to different time zones by reference in `lubridate`
我有一个 data.table
具有跨越多个时区的 UTC 日期时间戳记录,我想创建一个新列来显示日期时间戳,但在特定时区每个观察值,由相同的变量指定 table:
require("lubridate")
require("data.table")
dt <- data.table(A = 1:5, B = rep(ymd_hms("2016-03-24 17:15:12", tz = "UTC"), 5), timezone = c("America/Indiana/Vincennes", "Australia/North", "Pacific/Palau", "Antarctica/Macquarie", "Asia/Nicosia"))
我试图通过以下方式完成此操作,但它似乎不起作用:
dt[, B_local := with_tz(B, tz = timezone)]
dt
Error in as.POSIXlt.POSIXct(x, tz) : invalid 'tz' value
当我尝试在命令中添加 by
规范时,它更接近所需的输出,但不正确,我认为不知何故是由于日期时间和时区的非唯一对,例如此示例 table,即:
dt[, B_local := with_tz(B, tz = timezone), by = .(B, timezone)]
dt
A B timezone B_local
1: 1 2016-03-24 17:15:12 America/Indiana/Vincennes 2016-03-24 19:15:12
2: 2 2016-03-24 17:15:12 Australia/North 2016-03-24 19:15:12
3: 3 2016-03-24 17:15:12 Pacific/Palau 2016-03-24 19:15:12
4: 4 2016-03-24 17:15:12 Antarctica/Macquarie 2016-03-24 19:15:12
5: 5 2016-03-24 17:15:12 Asia/Nicosia 2016-03-24 19:15:12
即使我在 dt[, B_local := with_tz(B, tz = timezone), by = .(A)]
中更改 by = .(A)
,将 table 子集放入每一行,输出也与上面相同。
NB:我很乐意使用 lubridate
以外的东西,但我更愿意工作在 data.table
内以提高效率,因为我有一个大型数据集。
这东西超级凌乱和挑剔。我在包 RcppCCTZ 中写了一个时区 'shifter' 作为底层 CCTZ 库使它可行/可能。
一个巨大警告:时区仅出现在格式化输出中,所以我在这里为您提供了一个解决方案,但目标输出是现在 文本。 已编辑: 其中,再分析 anytime()
,当然可以 POSIXct
(在您当地的 TZ)。
另请注意,我使用了 anytime 中的辅助函数来设置时间。
代码
suppressMessages({
library("data.table")
library("RcppCCTZ")
library("anytime")
})
dt <- data.table(A = 1:5,
B = rep(utctime("2016-03-24 17:15:12", tz="UTC"), 5),
timezone = c("America/Indiana/Vincennes", "Australia/North",
"Pacific/Palau", "Antarctica/Macquarie",
"Asia/Nicosia"))
dt[ , newTime := format(toTz(B, "UTC", timezone), tz=timezone), by=A ]
dt[ , pt := anytime(newTime), by=A ]
输出
R> dt <- data.table(A = 1:5,
+ B = rep(utctime("2016-03-24 17:15:12", tz="UTC"), 5),
+ timezone = c("America/Indiana/Vincennes", "Australia/North",
+ "Pacific/Palau", "Antarctica/Macquarie",
+ "Asia/Nicosia"))
R> dt[ , newTime := format(toTz(B, "UTC", timezone), tz=timezone), by=A ]
R> dt[ , pt := anytime(newTime), by=A ]
R> dt
A B timezone newTime pt
1: 1 2016-03-24 22:15:12 America/Indiana/Vincennes 2016-03-24 18:15:12 2016-03-24 18:15:12
2: 2 2016-03-24 22:15:12 Australia/North 2016-03-25 07:45:12 2016-03-25 07:45:12
3: 3 2016-03-24 22:15:12 Pacific/Palau 2016-03-25 07:15:12 2016-03-25 07:15:12
4: 4 2016-03-24 22:15:12 Antarctica/Macquarie 2016-03-25 09:15:12 2016-03-25 09:15:12
5: 5 2016-03-24 22:15:12 Asia/Nicosia 2016-03-25 00:15:12 2016-03-25 00:15:12
R>
我有一个 data.table
具有跨越多个时区的 UTC 日期时间戳记录,我想创建一个新列来显示日期时间戳,但在特定时区每个观察值,由相同的变量指定 table:
require("lubridate")
require("data.table")
dt <- data.table(A = 1:5, B = rep(ymd_hms("2016-03-24 17:15:12", tz = "UTC"), 5), timezone = c("America/Indiana/Vincennes", "Australia/North", "Pacific/Palau", "Antarctica/Macquarie", "Asia/Nicosia"))
我试图通过以下方式完成此操作,但它似乎不起作用:
dt[, B_local := with_tz(B, tz = timezone)]
dt
Error in as.POSIXlt.POSIXct(x, tz) : invalid 'tz' value
当我尝试在命令中添加 by
规范时,它更接近所需的输出,但不正确,我认为不知何故是由于日期时间和时区的非唯一对,例如此示例 table,即:
dt[, B_local := with_tz(B, tz = timezone), by = .(B, timezone)]
dt
A B timezone B_local
1: 1 2016-03-24 17:15:12 America/Indiana/Vincennes 2016-03-24 19:15:12
2: 2 2016-03-24 17:15:12 Australia/North 2016-03-24 19:15:12
3: 3 2016-03-24 17:15:12 Pacific/Palau 2016-03-24 19:15:12
4: 4 2016-03-24 17:15:12 Antarctica/Macquarie 2016-03-24 19:15:12
5: 5 2016-03-24 17:15:12 Asia/Nicosia 2016-03-24 19:15:12
即使我在 dt[, B_local := with_tz(B, tz = timezone), by = .(A)]
中更改 by = .(A)
,将 table 子集放入每一行,输出也与上面相同。
NB:我很乐意使用 lubridate
以外的东西,但我更愿意工作在 data.table
内以提高效率,因为我有一个大型数据集。
这东西超级凌乱和挑剔。我在包 RcppCCTZ 中写了一个时区 'shifter' 作为底层 CCTZ 库使它可行/可能。
一个巨大警告:时区仅出现在格式化输出中,所以我在这里为您提供了一个解决方案,但目标输出是现在 文本。 已编辑: 其中,再分析 anytime()
,当然可以 POSIXct
(在您当地的 TZ)。
另请注意,我使用了 anytime 中的辅助函数来设置时间。
代码
suppressMessages({
library("data.table")
library("RcppCCTZ")
library("anytime")
})
dt <- data.table(A = 1:5,
B = rep(utctime("2016-03-24 17:15:12", tz="UTC"), 5),
timezone = c("America/Indiana/Vincennes", "Australia/North",
"Pacific/Palau", "Antarctica/Macquarie",
"Asia/Nicosia"))
dt[ , newTime := format(toTz(B, "UTC", timezone), tz=timezone), by=A ]
dt[ , pt := anytime(newTime), by=A ]
输出
R> dt <- data.table(A = 1:5,
+ B = rep(utctime("2016-03-24 17:15:12", tz="UTC"), 5),
+ timezone = c("America/Indiana/Vincennes", "Australia/North",
+ "Pacific/Palau", "Antarctica/Macquarie",
+ "Asia/Nicosia"))
R> dt[ , newTime := format(toTz(B, "UTC", timezone), tz=timezone), by=A ]
R> dt[ , pt := anytime(newTime), by=A ]
R> dt
A B timezone newTime pt
1: 1 2016-03-24 22:15:12 America/Indiana/Vincennes 2016-03-24 18:15:12 2016-03-24 18:15:12
2: 2 2016-03-24 22:15:12 Australia/North 2016-03-25 07:45:12 2016-03-25 07:45:12
3: 3 2016-03-24 22:15:12 Pacific/Palau 2016-03-25 07:15:12 2016-03-25 07:15:12
4: 4 2016-03-24 22:15:12 Antarctica/Macquarie 2016-03-25 09:15:12 2016-03-25 09:15:12
5: 5 2016-03-24 22:15:12 Asia/Nicosia 2016-03-25 00:15:12 2016-03-25 00:15:12
R>