R中的日期时间转换

3

我知道类似的话题已经被讨论过了,但这里有一些我还没有找到答案的问题。

1:日期转换为POSIXct

> Sys.timezone()
[1] "EST"

> as.POSIXct("2011-01-30")
[1] "2011-01-30 EST"

> as.POSIXct(as.Date("2011-01-30"))
[1] "2011-01-29 19:00:00 EST"

> as.POSIXct(as.Date("2011-01-30"), tz="EST")
[1] "2011-01-29 19:00:00 EST"

> as.POSIXct(as.Date("2011-01-30"), tz="GMT")
[1] "2011-01-29 19:00:00 EST"

> as.POSIXct(as.Date("2011-01-30"), tz="America/New_York")
[1] "2011-01-29 19:00:00 EST"

> as.POSIXct(as.Date("2011-01-30"), tz="")
[1] "2011-01-29 19:00:00 EST"

请问为什么如果输入是一个日期,即使我指定了正确的时区,我还是无法得到1月30日午夜?但如果输入是字符字符串,那就可以。

2: 日期/字符转换

两者都非常慢。然后我发现将字符字符串转换为日期,通过先将其转换为POSIXlt实际上要快得多:

> d3.str = "2011-03-02 23:59:00";
> N=10000
> system.time(for(i in 1:N) r5.dt = as.Date(d3.str))
   user  system elapsed 
   1.25    0.00    1.24 
> system.time(for(i in 1:N) r6.dt = as.Date(strptime(d3.str, format="%Y-%m-%d")))
   user  system elapsed 
   0.37    0.00    0.38 
> r5.dt
[1] "2011-03-02"
> r5.dt==r6.dt
[1] TRUE

我现在有些困惑。有没有更快、更优雅的方法将一个字符转换为日期?还有,将日期转换为字符,而不是像as.character一样很慢的方法?谢谢!

嘿,Gavin,感谢你的编辑!现在看起来好多了。 - sunt
3个回答

7

在as.POSIXct帮助页面的早期,我们可以看到:“没有时间的日期被视为UTC午夜。”你认为'tz'参数会修改这一点是错误的。如果您指定输出为UCT,则可以获得原始日期:

 strftime(as.POSIXct(as.Date("2011-01-30")), format="%Y-%m-%d %H:%M:%S", tz="UCT")
#[1] "2011-01-30 00:00:00"

如果你只想要一个日期,那么你应该使用 as.Date

1
+1 -- 如果你想使用你的时区的午夜时间,请使用 ISODatetime(2012,1,11,0,0,0)(或任何其他日期)。 - Dirk Eddelbuettel
谢谢。需要注意的是,strftime 生成的是“字符”结果,而 ISOdatetime(请注意,“d”没有大写)返回类“POSIXct”,因此可能更理想。 - IRTFM

4
关于你的第二个问题,如果你比较as.Date.characteras.Date.POSIXlt的代码,很多东西可能会更清晰。其中一个需要进行更多的检查,因为你没有指定格式。
至于一般速度,你没有将转换向量化。as.Datestrptime以及大多数其他日期/时间转换函数都接受日期和日期时间的向量。这种方式会更快。

闰秒是在年末新增的,夏令时变化从未发生在一月份,因此我认为您应该删除最后一句话。 - IRTFM
我刚刚找到了类似的函数,比如as.character.Date、as.POSIXlt.POSIXct等等,通常指定格式可以大大加快速度。在我的情况下,我必须使用循环。这是非常好的东西,感谢大家的帮助! - sunt

2
< p > as.POSIXct 的 tz 参数只用于字符串,如果不是字符串则会静默忽略。您可能需要查看专门用于操作日期的软件包,例如 lubridate 包中的 with_tz 函数。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接