POSIXct的seq()

Kar*_* W. 17 r date posixct

我的目标是在给定开始,结束和增量(15分钟,1小时,1天)的情况下创建POSIXct时间戳的向量.我希望我可以使用seq它,但我在数字和POSIXct表示之间转换时遇到问题:

now <- Sys.time()
now
# [1] "2012-01-19 10:30:39 CET"
as.POSIXct(as.double(now), origin="1970-01-01", tz="CET")
# [1] "2012-01-19 09:30:39 CET"
as.POSIXct(as.double(now), origin=as.POSIXct("1970-01-01", tz="CET"), tz="CET")
# [1] "2012-01-19 09:30:39 CET"
Run Code Online (Sandbox Code Playgroud)

转换期间会丢失一小时.我究竟做错了什么?

Rei*_*son 23

seq()类的对象有一个方法,"POSIXt"它是"POSIXlt""POSIXct"类的超类.因此,您无需进行任何转换.

> now <- Sys.time()
> tseq <- seq(from = now, length.out = 100, by = "mins")
> length(tseq)
[1] 100
> head(tseq)
[1] "2012-01-19 10:52:38 GMT" "2012-01-19 10:53:38 GMT"
[3] "2012-01-19 10:54:38 GMT" "2012-01-19 10:55:38 GMT"
[5] "2012-01-19 10:56:38 GMT" "2012-01-19 10:57:38 GMT"
Run Code Online (Sandbox Code Playgroud)

  • 这在seq()的文档中有所指出,我应该首先查看.谢谢! (3认同)

Jor*_*eys 10

您必须注意,当从POSIXct转换为数字时,R会考虑时区,但始终从GMT原点开始计算:

> xgmt <- as.POSIXct('2011-01-01 14:00:00',tz='GMT')
> xest <- as.POSIXct('2011-01-01 14:00:00',tz='EST')
> (as.numeric(xgmt) - as.numeric(xest)) / 3600
[1] -5
Run Code Online (Sandbox Code Playgroud)

如你所见,美国东部时间的时间设想比格林尼治标准时间早5个小时,这是两个时区之间的时差.这是内部保存的值.

as.POSIXCT()函数只添加一个包含时区的属性.它不会改变值,所以你得到的时间是GMT时间,但是有一个属性告诉它是EST.这也意味着一旦你从POSIXct数字转到数字,你应该把你的数据视为GMT时间.(这比这复杂得多,但这是一般的想法).所以你必须按如下方式计算偏移量:

> nest <- as.numeric(xest)
> origin <- as.POSIXct('1970-01-01 00:00:00',tz='EST')
> offset <- as.numeric(origin)
> as.POSIXct(nest-offset,origin=origin)
[1] "2011-01-01 14:00:00 EST"
Run Code Online (Sandbox Code Playgroud)

这适用于您的语言环境中的任何时区(在我的情况下,实际上是CET).另请注意,时区数据的行为可能因系统而异.


Ric*_*ton 8

这些时区问题总是很繁琐,但我认为问题是您的来源是在错误的时区计算的(因为字符串只指定了日期).

尝试使用origin <- now - as.numeric(now).

或者,使用lubridate::origin,这是字符串"1970-01-01 UTC".


完整的解决方案,再次使用lubridate.

start <- now()
seq(start, start + days(3), by = "15 min")
Run Code Online (Sandbox Code Playgroud)