3

当我放置一个要解析的日期时,它会准确解析

> ymd("20011001")
[1] "2001-10-01 UTC"

但是当我尝试创建一个日期向量时,它们都会出现一天:

> b=c(ymd("20111001"),ymd("20101001"),ymd("20091001"),ymd("20081001"),ymd("20071001"),ymd("20061001"),ymd("20051001"),ymd("20041001"),ymd("20031001"),ymd("20021001"),ymd("20011001"))
> b
 [1] "2011-09-30 19:00:00 CDT" "2010-09-30 19:00:00 CDT" "2009-09-30 19:00:00 CDT"
 [4] "2008-09-30 19:00:00 CDT" "2007-09-30 19:00:00 CDT" "2006-09-30 19:00:00 CDT"
 [7] "2005-09-30 19:00:00 CDT" "2004-09-30 19:00:00 CDT" "2003-09-30 19:00:00 CDT"
[10] "2002-09-30 19:00:00 CDT" "2001-09-30 19:00:00 CDT"

我怎样才能解决这个问题???非常感谢。

4

1 回答 1

7

我并没有声称完全了解这里发生了什么,但最接近的问题是c()剥离属性,因此c()在 POSIX[c?]t 向量上使用会将其从 UTC 更改为您的语言环境指定的时区剥离时区属性,搞砸了(即使您将时区设置为与您的语言环境指定的时区一致)。在我的系统上:

library(lubridate)
(y1 <- ymd("20011001"))
## [1] "2001-10-01 UTC"
(y2 <- ymd("20011002"))
c(y1,y2)
## now in EDT (and a day earlier/4 hours before UTC):
## [1] "2001-09-30 20:00:00 EDT" "2001-10-01 20:00:00 EDT"
(y12 <- ymd(c("20011001","20011002")))
## [1] "2001-10-01 UTC" "2001-10-02 UTC"
c(y12)
## back in EDT
## [1] "2001-09-30 20:00:00 EDT" "2001-10-01 20:00:00 EDT"

您可以明确设置时区...

y3 <- ymd("20011001",tz="EDT")
## [1] "2001-10-01 EDT"

但是c()还是有问题的。

(y3c <- c(y3))
## [1] "2001-09-30 20:00:00 EDT"

所以有两种解决方案

  • 转换一个字符向量,而不是在一个一个转换之后组合对象,或者
  • 组合后恢复tzone属性。

例如:

 attr(y3c,"tzone") <- attr(y3,"tzone")

@Joran 指出,这几乎可以肯定是应用于对象的一般属性c()POSIX[c?]t而不是具体lubridate相关的。我希望有人能插话并解释这是否是一个众所周知的设计决策/不合理/错误功能。

更新:在 2012 年的 R-help 上对此进行了一些讨论,Brian Ripley 评论道:

但无论如何,文档 (?c.POSIXct) 很清楚:

  Using ‘c’ on ‘"POSIXlt"’ objects converts them to the current time
  zone, and on ‘"POSIXct"’ objects drops any ‘"tzone"’ attributes
  (even if they are all marked with the same time zone).

所以推荐的方法是添加一个“tzone”属性,如果你知道你想要它是什么。POSIXct 对象是绝对时间:时区仅影响它们的转换方式(包括用于打印的字符)。

如果lubridate添加一个方法来做到这一点可能会很好......

于 2013-12-31T21:21:59.093 回答