防止意外时区转换
在 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
我觉得我距离真正的 火星气候轨道器时刻,如果这种情况发生在我最意想不到的时候。有人有什么策略可以确保他们的约会“保持不变”吗?
In R, I have a bunch of datetime values that I measure in GMT. I keep running into accidents where some function or another loses the timezone on my values, or even loses the class name. Even on functions so basic as c()
and 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
I feel like I'm a hair's breadth away from having a real Mars Climate Orbiter moment if this happens when I least expect it. Anyone have any strategies for making sure their dates "stay put"?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
此行为记录在
?c
、?DateTimeClasses
和?unlist
中:来自
?DateTimeClasses
:来自
?c
:也就是说,我的测试表明,尽管使用
c
或,数据的完整性仍然完好无损>取消列出
。例如:如果您使用 R 来跟踪日期,您的火星漫游车应该没问题。
This behaviour is documented in
?c
,?DateTimeClasses
and?unlist
:From
?DateTimeClasses
:From
?c
:That said, my testing indicates that the integrity of your data remains intact, despite using
c
orunlist
. For example:Your Mars Rover should be OK if you use R to keep track of dates.
那么为什么不将 R 会话的时区设置为 GMT呢?如果某些内容转换为“当前”时区,它仍然是正确的。
Why not set your timezone to GMT for your R sessions, then? If something gets converted to the "current" timezone, it is still right.
鉴于这是记录在案的行为,并且应该避免此类函数或围绕此类行为进行防御性编码,那么您需要支持这两种方法的机制。对于这样的事情,我建议写一个“poor man's lint”;有了这样的 lint 探测器,您就可以恢复理智了。此外,对于 lint 检测,有多种方法可以避免火星极地轨道飞行器崩溃,有些是相互独立的,有些是相互依赖的
find
和grep
函数,或以其他方式(例如 R 中的grep
),查找那些导致问题的特定函数。一旦发现,请删除或使用防御性编码方法(例如#1 中的包装器)。Runit
或testthat
)开发测试,确保在使用函数或包时维护时区属性。每次出现新的错误时,创建一个新的测试以确保该错误不会在发布的版本中再次出现。我针对其他问题执行了所有#s 1-4,但是,正如它们很容易适应时区检查一样,它们对于许多避开火星轨道飞行器的目标来说是相当可重复使用的。我做这种事情正是为了避免编写下一个这样的火星轨道飞行器。 (对于我们所有使用数值数据的人来说,这是一个昂贵的教训。:))
Given that this is documented behavior and one should either avoid such functions or else defensively code around such behavior, then you need mechanisms to support either approach. For things like this, I would recommend writing a "poor man's lint"; with such a lint detector, you can go about restoring sanity In addition, to lint detection, there are several approaches to avoiding Mars Polar Orbiter crashes, some are independent of each other, others dependent:
find
andgrep
functions, or in some other manner (e.g.grep
in R), to find those particular functions that are causing you problems. When found, either remove or use a defensive coding method (e.g. the wrapper in #1).Runit
ortestthat
, develop tests that ensure that timezone properties are maintained when using your functions or package. Every time there's a new bug, create a new test to ensure that bug doesn't appear again in released versions.I do all of #s 1-4 for other issues, but, just as they're easily adapted to timezone checking, they're fairly reusable for lots of Mars Orbiter-avoiding objectives. I do this kind of thing precisely to avoid coding the next such Mars Orbiter. (That was an expensive lesson for all of us that work with numerical data. :))