as.POSIXct给出了一个意想不到的时区

时间:2011-07-01 13:29:23

标签: r zoneinfo posixct

我正在尝试将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”)&lt; - 'UTC'

这解决了丢失tzone的问题,这个问题仅用于演示,而不是像Grothendieck和Dwin建议的那样。

4 个答案:

答案 0 :(得分:7)

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

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

答案 1 :(得分:5)

正在在您的代码中正确设置时区。 您感知的问题仅在输出阶段。 POSIX值均以UTC / GMT为参考。假设日期是午夜时间。午夜UTC 上午1点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了解许多其他格式的可能性。

答案 2 :(得分: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"))

答案 3 :(得分:3)

这似乎与日期/时间"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"

<强> yearmon

> 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"