13

我正在尝试将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") <- 'UTC'

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

4

4 回答 4

7

这是因为as.POSIXct.Date不传递....POSIXct.

> as.POSIXct.Date
function (x, ...) 
.POSIXct(unclass(x) * 86400)
<environment: namespace:base>
于 2011-07-01T13:45:36.400 回答
5

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

> 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许多其他格式的可能性。

于 2011-07-01T13:57:52.880 回答
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"))
于 2011-07-01T13:34:40.967 回答
3

这似乎是日期/时间"POSIXct"类方法的一个奇怪之处。尝试首先格式化"Date"or"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"
于 2011-07-01T14:48:04.473 回答