在R中,我有一堆我在GMT中测量的日期时间值。我一直遇到一些事故,其中一些功能或其他功能失去了我的价值观的时区,甚至失去了班级名称。即使是基本功能c()
和unlist()
:
> dput(x)
structure(1317830532, class = c("POSIXct", "POSIXt"), tzone = "GMT")
> dput(c(x))
structure(1317830532, class = c("POSIXct", "POSIXt"))
> dput(list(x))
list(structure(1317830532, class = c("POSIXct", "POSIXt"), tzone = "GMT"))
> dput(unlist(list(x)))
1317830532
如果这种情况发生在我最不期望的时候,我觉得我的头发宽度远离真正的Mars Climate Orbiter时刻。任何人都有任何策略来确保他们的日期“保持”?
答案 0 :(得分:6)
?c
,?DateTimeClasses
和?unlist
中记录了此行为:
来自?DateTimeClasses
:
在“
c
”对象上使用POSIXlt
会将其转换为当前时区,而“POSIXct
”对象会删除所有“tzone
”属性(即使他们都标有相同的时区)。*
来自?c
:
c
有时用于删除除名称以外的属性的副作用。*
尽管如此,我的测试表明,尽管使用c
或unlist
,数据的完整性仍然完好无损。例如:
x <- structure(1317830532, class = c("POSIXct", "POSIXt"),
tzone = "GMT")
y <- structure(1317830532+3600, class = c("POSIXct", "POSIXt"),
tzone = "PST8PDT")
x
[1] "2011-10-05 16:02:12 GMT"
y
[1] "2011-10-05 10:02:12 PDT"
strftime(c(x, y), format="%Y/%m/%d %H:%M:%S", tz="GMT")
[1] "2011/10/05 16:02:12" "2011/10/05 17:02:12"
strftime(c(x, y), format="%Y/%m/%d %H:%M:%S", tz="PST8PDT")
[1] "2011/10/05 09:02:12" "2011/10/05 10:02:12"
strftime(unlist(y), format="%Y/%m/%d %H:%M:%S", tz="PST8PDT")
[1] "2011/10/05 10:02:12"
如果您使用R来跟踪日期,那么您的火星漫游者应该没问题。
答案 1 :(得分:4)
为什么不为你的R会话设置你的时区GMT呢?如果某些东西被转换为“当前”时区,它仍然是正确的。
答案 2 :(得分:2)
鉴于这是记录在案的行为,并且要么应该避免这样的行为,要么就这些行为进行防御性编码,那么你需要机制来支持这两种方法。对于这样的事情,我建议写一个“穷人的棉绒”;有了这样的棉绒探测器,你就可以恢复理智了另外,对于lint探测,有几种方法可以避免火星极地轨道飞行器坠毁,有些是彼此独立的,有些依赖:
find
和grep
函数,或者以其他方式(例如R中的grep
)来查找导致问题的特定函数。找到后,删除或使用防御性编码方法(例如#1中的包装器)。Runit
或testthat
开发测试,确保在使用您的函数或包时保持时区属性。每次出现新错误时,都要创建一个新测试,以确保在发布的版本中不再出现错误。我为#s 1-4做了其他所有问题,但是,正如它们很容易适应时区检查一样,它们可以很好地重复使用许多火星轨道飞行器避免目标。我这样做的确是为了避免编码下一个这样的火星轨道器。 (对于我们所有使用数字数据的人来说,这是一个昂贵的教训。:))