POSIXct origin 基类型导致时区差异

POSIXct origin base type causes time zone differences

我 运行 遇到了在 R 中使用 POSIXct 管理时区的问题。我已经将 TZ 选项全局设置为 "Europe/London" 但是因为我们已经切换回 GMT have 运行 as.POSIXct 不再将数值向量转换回正确的时间。

深入探究为什么我发现时区差异可能是由用于设置起始日期的对象类型引起的。

例如:

# Date time is set as 1 second after 1970-01-01
as.POSIXct(1, origin = "1970-01-01")
# [1] "1970-01-01 01:00:01 BST"

# Same numeric value, but one hour less now that the origin is set using a POSIXct
as.POSIXct(1, origin = as.POSIXct("1970-01-01"))
# [1] "1970-01-01 00:00:01 BST"

鉴于查询是在英国夏令时以外进行的,因此第一个值实际上没有意义,但这些是在格林威治标准时间进行的(参见下面的结果):

Sys.timezone()
# [1] "Europe/London"

Sys.time()
# [1] "2018-10-31 11:05:36 GMT"

即使您在每个阶段明确说明时区,时差仍然存在:

as.POSIXct(1, origin = "1970-01-01", tz = "Europe/London")
# [1] "1970-01-01 01:00:01 BST"

as.POSIXct(1, origin = as.POSIXct("1970-01-01", tz = "Europe/London"), "Europe/London")
# [1] "1970-01-01 00:00:01 BST"

更糟糕的是,?as.POSIXct 生成的文档对时区管理非常含糊,特别是:

If a time zone is needed and that specified is invalid on your system, what happens is system-specific but attempts to set it will probably be ignored.

鉴于此,我有一系列的问题:

1) 为什么as.POSIXct(1, origin = "1970-01-01", tz = "Europe/London")要加一个小时?即使原始日期将被解析为 GMT 时间并且时区已明确设置。

2) 从 R 中的数字转换时确保 R 中时区一致的最佳方法是什么?

3) 在 R 中管理时区的最佳实践是什么?有没有好的参考,尤其是POSIXct日期类型。

关于问题 1,您在这里了解了一些历史。请参阅下面 BST、GMT 和 UTC 的所有结果。 UTC 和 GMT 应该(并且是)相同。 现在,为什么第一行代码得到BST?

那是因为在 1970 年,英国全年都在使用 BST。实际上,英国从 1968-02-18 到 1971-10-31 一直在使用 BST。这意味着当您为 "Europe/London" 提供时区时,R 返回“1970-01-01 01:00:01 BST”是正确的。有关 this wikipedia page.

的详细信息,请参阅

次数:

as.POSIXct(1, origin = "1970-01-01", tz = "Europe/London")
[1] "1970-01-01 01:00:01 BST"
as.POSIXct(1, origin = "1970-01-01", tz = "GMT")
[1] "1970-01-01 00:00:01 GMT"
as.POSIXct(1, origin = "1970-01-01", tz = "UTC")
[1] "1970-01-01 00:00:01 UTC"

Q2:首先你需要知道日期来自哪个时区。然后要么继续在该时区工作,要么将时区更改为您当地的时区。或者去除日期时间对象的时区,这将强制一切为 UTC。

我会说 lubridate 的 force_tzwith_tz 函数强制时区。但是由于您不想要 lubridate,请将您的本地时区设置为您需要的任何时间。如果我正在处理股票数据,我倾向于使用 Sys.setenv(TZ = "UTC"),这样当我有不同的当地时间时 xts 对象就不会抱怨。

Q3:这里有一点来自 R for Data Science 这是一个 SO post on time zones