使用 seq() 创建常规的日期时间序列 (POSIXct)
我的目标是创建一个 POSIXct 时间戳向量,给定开始、结束和增量(15 分钟、1 小时、1 天)。我希望我可以使用 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"
在此转换过程中丢失了一个小时。我做错了什么?
My goal is to create a vector of POSIXct time stamps given a start, an end and a delta (15min, 1hour, 1day). I hoped I could use seq
for this, but I have a problem converting between the numeric and POSIXct representation:
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"
One hour gets lost during this conversion. What am I doing wrong?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(6)
"POSIXt"
类的对象有一个seq()
方法,该类是"POSIXlt"
和" 的超类POSIXct"
类。因此,您不需要进行任何转换。There is a
seq()
method for objects of class"POSIXt"
which is the super class of the"POSIXlt"
and"POSIXct"
classes. As such you don't need to do any conversion.您必须注意,当从 POSIXct 转换为数字时,R 会考虑时区,但始终从 GMT 原点开始计数:
如您所见,EST 时间被认为比 GMT 时间早五个小时,这是两个时区之间的时差。这是内部保存的值。
as.POSIXCT()
函数只是添加一个包含时区的属性。它不会改变该值,因此您会得到以 GMT 时间显示的时间,但有一个属性告诉它是 EST。这也意味着,一旦从POSIXct
转换为数字时间,您就应该将数据视为 GMT 时间。 (它比这要复杂得多,但这是总体思路)。因此,您必须按如下方式计算偏移量:无论您所在区域的时区如何(在我的情况下,实际上是 CET),这都有效。另请注意,时区数据的行为在系统之间可能有所不同。
You have to be aware that when converting from POSIXct to numeric, R takes the timezone into account but always starts counting from a GMT origin :
As you see, the time in EST is conceived to be five hours earlier than the time in GMT, which is the time difference between both timezones. It's that value that is saved internally.
The
as.POSIXCT()
function just adds an attribute containing the timezone. It doesn't alter the value, so you get the time presented in GMT time, but with an attribute telling it is EST. This also means that once you go fromPOSIXct
to numeric, you should treat your data as if it's GMT time. (It's a whole lot more complex than that, but it's the general idea). So you have to calculate the offset as follows:This works whatever the timezone is in your locale (in my case, that's actually CET). Also note that behaviour of timezone data can differ between systems.
这些时区问题总是很棘手,但我认为问题在于您的原产地是在错误的时区中计算的(因为字符串仅指定日期)。
尝试使用
origin <- now - as.numeric(now)
。或者,使用
lubridate::origin
,它是字符串“1970-01-01 UTC”
。完整的解决方案,再次使用
lubridate
。These time zone issues are always fiddly, but I think the problem is that your origin is being calculated in the wrong time zone (since the string only specifies the date).
Try using
origin <- now - as.numeric(now)
.Alternatively, use
lubridate::origin
, which is the string"1970-01-01 UTC"
.A full solution, again using
lubridate
.我没有解决您的问题,但我确实有另一种方法来创建 POSIXct 对象的向量。例如,如果您想从现在开始创建一个包含 1000 个时间戳的向量,
delta_t
为 15 分钟:技巧是您可以将秒向量添加到
POSIXct
目的。I do not have an answer to your problem, but I do have an alternative way of creating vectors of
POSIXct
objects. If, for example, you want to create a vector of 1000 timestamps from now with adelta_t
of 15 minutes:The trick is you can add a vector of seconds to a
POSIXct
object.使用
seq.POSIXt
的替代方法是xts::timeBasedSeq
,它允许您将序列指定为字符串:An alternative to using
seq.POSIXt
isxts::timeBasedSeq
, which allows you to specify the sequence as a string:您需要使用 seq(from=start,to=end, by=step)。请注意,在步骤中,您可以使用“天”或一个整数来定义从一个项目到另一个项目经过的秒数。
You need to use seq(from=start,to=end, by=step). Note that in step you can either use "days" or an integer defining how many seconds elapse from item to item.