【问题标题】:as.POSIXct gives an unexpected timezoneas.POSIXct 给出了一个意外的时区
【发布时间】:2011-07-01 13:29:23
【问题描述】:

我正在尝试将 yearmon 日期(来自 zoo 包)转换为 UTC 时区中的 POSIXct。 这是我试图做的:

> as.POSIXct(as.yearmon("2010-01-01"), tz="UTC")
[1] "2010-01-01 01:00:00 CET"

我在转换日期时得到相同的结果:

> as.POSIXct(as.Date("2010-01-01"),tz="UTC")
[1] "2010-01-01 01:00:00 CET"

让它工作的唯一方法是传递一个字符作为参数:

> as.POSIXct("2010-01-01", tz="UTC")
[1] "2010-01-01 UTC"

我查看了DateTimeClassestzsettimezones 的文档。我的 /etc/localtime 设置为 Europe/Amsterdam。除了设置 TZ 环境变量之外,我找不到将 tz 设置为 UTC 的方法:

> Sys.setenv(TZ="UTC")
> as.POSIXct(as.Date("2010-01-01"),tz="UTC")
[1] "2010-01-01 UTC"

从yearmon或Date创建POSIXct时是否可以直接设置时区?

编辑:

我检查了函数 as.POSIXct.yearmon。这个传递给 as.POSIXct.Date。

> zoo:::as.POSIXct.yearmon
function (x, tz = "", ...) 
as.POSIXct(as.Date(x), tz = tz, ...)
<environment: namespace:zoo>

就像 Joshua 说的那样,时区在 as.POSIXct.Date 中丢失了。现在我将使用 Richies 的建议手动设置 tzone:

attr(x, "tzone")

这解决了丢失 tzone 的问题,它仅用于演示,而不像 Grothendieck 和 Dwin 建议的那样在内部使用。

【问题讨论】:

    标签: r zoneinfo posixct


    【解决方案1】:

    这是因为as.POSIXct.Date 没有将... 传递给.POSIXct

    > as.POSIXct.Date
    function (x, ...) 
    .POSIXct(unclass(x) * 86400)
    <environment: namespace:base>
    

    【讨论】:

      【解决方案2】:

      正在在代码中正确设置时区。 您所感知的问题仅在输出阶段。 POSIX 值均参考 UTC/GMT。日期假定为午夜时间。 UTC 午夜 1 AM CET(这显然是所在的地方)。

      > as.POSIXct(as.yearmon("2010-01-01"), tz="UTC")
      [1] "2009-12-31 19:00:00 EST"     # R reports the time in my locale's timezone
      > dtval <- as.POSIXct(as.yearmon("2010-01-01"), tz="UTC")
      > format(dtval, tz="UTC")         # report the date in UTC  note it is the correct date ... there
      [1] "2010-01-01"
      > format(dtval, tz="UTC", format="%Y-%m-%d ")
      [1] "2010-01-01 "                 # use a format string
      > format(dtval, tz="UTC", format="%Y-%m-%d %OS3")
      [1] "2010-01-01 00.000"           # use decimal time
      

      请参阅?strptime 了解许多其他格式的可能性。

      【讨论】:

      • as.POSIXct 忽略时区,因为as.yearmon 不存储时间。使用tz="CET 尝试您的第一个示例。它将给出与您指定UTC 相同的结果。有关更多解释,请参阅我的答案。
      • 好的。那么问题是传递给 as.POSIXct 的日期值将始终假定为格林威治标准时间午夜。 (在第二次阅读时,我发现您正在为我阅读 FM。)再次抱歉,我很迟钝。
      【解决方案3】:

      在帮助页面 ?as.POSIXct 中,对于 tz 参数它说

      要使用的时区规范 对于转换,如果是 需要。系统特定(见时间 区域),但“”“”是当前 时区,'"GMT"' 是 UTC (世界时,协调)。

      as.POSIXct(as.yearmon("2010-01-01"), tz="GMT") 适合你吗?


      仔细阅读文档后,我们在详细信息部分看到:

      没有时间的日期被视为 在 UTC 午夜。

      因此,在您的示例中,tz 参数被忽略。如果您使用as.POSIXlt,则更容易看到时区发生了什么。以下都应该给出相同的答案,以 UTC 作为时区。

      unclass(as.POSIXlt(as.yearmon("2010-01-01")))
      unclass(as.POSIXlt(as.yearmon("2010-01-01"), tz = "UTC"))
      unclass(as.POSIXlt(as.yearmon("2010-01-01"), tz = "GMT"))
      unclass(as.POSIXlt(as.yearmon("2010-01-01"), tz = "CET"))
      

      事实上,由于您使用的是as.yearmon(它会取消超时),因此您永远无法设置时区。比较,例如,

      unclass(as.POSIXlt(as.yearmon("2010-01-01 12:00:00"), tz = "CET"))
      unclass(as.POSIXlt("2010-01-01 12:00:00", tz = "CET"))
      

      【讨论】:

      • 我不太明白“如果需要的话”是什么意思。当我尝试转换为 GMT 时,我仍然会得到 CET [1] "2010-01-01 01:00:00 CET"
      • 实际上,unclass(as.POSIXlt(x)) 可能有点过头了。 attr(x, "tzone") 就足够了。
      【解决方案4】:

      这似乎是日期/时间"POSIXct" 类方法的奇怪之处。尝试先格式化"Date""yearmon" 变量,以便调度as.POSIXct.character 而不是as.POSIXct.{Date, yearmon}

      日期

      > d <- as.Date("2010-01-01")
      > as.POSIXct(format(d), tz = "UTC")
      [1] "2010-01-01 UTC"
      

      年月

      > library(zoo)
      > y <- as.yearmon("2010-01")
      > as.POSIXct(format(y, format = "%Y-%m-01"), tz = "UTC")
      [1] "2010-01-01 UTC"
      > # or
      > as.POSIXct(format(as.Date(y)), tz = "UTC")
      [1] "2010-01-01 UTC"
      

      【讨论】:

        猜你喜欢
        • 2020-04-05
        • 2016-11-01
        • 2020-04-21
        • 1970-01-01
        • 2016-03-11
        • 2013-07-15
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多