【发布时间】:2014-05-14 12:50:54
【问题描述】:
我正在开发一个执行一些时间序列操作的软件。我最近在我开发的 R 脚本方面发现了一个严重的问题;在具有Europe/Moscow 语言环境的特定机器上隔离了意外行为。问题归结为以下 sn-p:
strange_days <- c("2/1/1984", "3/1/1984", "4/1/1984", "5/1/1984", "6/1/1984")
Sys.setenv(TZ='Europe/Moscow')
d <- strptime(strange_days, '%m/%d/%Y')
d
[1] "1984-02-01 MSK" "1984-03-01 MSK" "1984-04-01" "1984-05-01 MSD" "1984-06-01 MSD"
一切似乎都能被正确识别。我认为由于这是每日数据,因此时区属性没有太大区别;痛苦的错误:
as.numeric(d)
[1] 444430800 446936400 NA 452203200 454881600
在转换为xts 对象之后显然会失败。
当前的解决方法是通过strptime(strange_days, '%m/%d/%Y', tz='GMT') 甚至Sys.setenv(TZ='GMT') 强制所有时区为格林威治标准时间;问题就这样消失了。
这是一个好习惯吗?代码在所有情况下都可靠吗?您会推荐哪些技术来避免类似问题?
1984 年 4 月 1 日发生了什么事?
编辑:this 和 this 问题表明这可能是导致问题的夏令时。
sessionInfo()
R version 3.1.0 (2014-04-10)
Platform: x86_64-w64-mingw32/x64 (64-bit)
locale:
[1] LC_COLLATE=English_United Kingdom.1252 LC_CTYPE=English_United Kingdom.1252 LC_MONETARY=English_United Kingdom.1252
[4] LC_NUMERIC=C LC_TIME=English_United Kingdom.1252
attached base packages:
[1] stats graphics grDevices utils datasets methods base
loaded via a namespace (and not attached):
[1] tools_3.1.0
编辑 2:问题显然是特定于 Windows 的,未在具有这些规范的 linux 上重现:
R version 3.1.0 (2014-04-10)
Platform: i686-pc-linux-gnu (32-bit)
locale:
[1] LC_CTYPE=en_US.UTF-8 LC_NUMERIC=C LC_TIME=en_US.UTF-8 LC_COLLATE=en_US.UTF-8
[5] LC_MONETARY=en_US.UTF-8 LC_MESSAGES=en_US.UTF-8 LC_PAPER=en_US.UTF-8 LC_NAME=C
[9] LC_ADDRESS=C LC_TELEPHONE=C LC_MEASUREMENT=en_US.UTF-8 LC_IDENTIFICATION=C
attached base packages:
[1] stats graphics grDevices utils datasets methods base
loaded via a namespace (and not attached):
[1] tools_3.1.0
【问题讨论】:
-
Daylight Saving Time started in 1984 in Russia 的确切日期是 4 月 1 日...
-
在这种情况下,为什么不使用
as.Date? -
另外:您使用的是哪个 R / OS 版本?对我来说,在带有 R 2.14.2 的 Mac OS X 10.7.5 上,我得到了
as.numeric(d) [1] 444430800 446936400 449611200 452203200 454881600 -
@plannapus 谢谢,cmets 非常有帮助。您想发布这些作为答案吗?添加了 SessionInfo()。