17

我正在操作一些POSIXltDateTime 对象。例如我想增加一个小时:

my.lt = as.POSIXlt("2010-01-09 22:00:00")
new.lt = my.lt + 3600
new.lt
# [1] "2010-01-09 23:00:00 EST"
class(new.lt)
# [1] "POSIXct" "POSIXt" 

问题是我想new.lt成为一个POSIXlt对象。我知道我可以用as.POSIXlt它来将它转换回POSIXlt,但是有没有更优雅和有效的方法来实现这一点?

4

4 回答 4

16

POSIXct-classed 对象在内部是一个允许数值计算的数值。POSIXlt-objects 是内部列表。不幸的是,出于您的愿望,Ops.POSIXt(当您使用“+”时,这就是所谓的)使用以下代码强制转换为 POSIXct:

if (inherits(e1, "POSIXlt") || is.character(e1)) 
        e1 <- as.POSIXct(e1)

幸运的是,如果你只是想要一个小时,还有一个方便的替代方法来添加 3600。而是使用列表结构并将 1 添加到小时元素:

> my.lt$hour <- my.lt$hour +1
> my.lt
[1] "2010-01-09 23:00:00"

当您想避免有关 DST 更改的棘手问题时,这种方法非常方便,至少如果您想增加天数以提供相同的时间。

编辑(添加@sunt 的代码来证明对Ops.POSIXlt时间“溢出”要小心。))

my.lt = as.POSIXlt("2010-01-09 23:05:00") 
my.lt$hour=my.lt$hour+1 
my.lt
# [1] "2010-01-10 00:05:00"
于 2012-01-13T21:28:02.517 回答
13

简短的回答:没有

长答案:

POSIXctPOSIXlt对象是更通用POSIXt类的两种特定类型(不是严格的面向对象的继承意义,而是准面向对象的实现意义)。代码在这些之间自由切换。添加到POSIXlt对象时,实际使用的功能是+.POSIXt,而不是专门用于POSIXlt. 在这个函数内部,参数被转换为a POSIXct,然后处理(添加到)。

此外,POSIXct是从特定日期和时间开始的秒数。POSIXlt是日期部分的列表(秒、分钟、小时、月中的某天、月、年、周中的某天、年中的某天、DST 信息),因此直接添加它没有任何意义。将其转换为秒数 ( POSIXct) 并添加到其中确实有意义。

于 2012-01-13T21:27:16.883 回答
9

它可能不会更优雅,但

seq.POSIXt( from=Sys.time(), by="1 hour", length.out=2 )[2]

恕我直言,比

Sys.time()+3600;  # 60 minutes * 60 seconds

因为代码本身记录了您将使用“POSIX”“seq”uence 递增“1 小时”,但这是一个口味问题。在 POSIXlt 上工作得很好,但请注意,无论哪种方式,它都会返回一个 POSIXct。也适用于“天”。有关如何处理月份、夏令时等的详细信息,请参阅 help(seq.POSIXt)。

于 2014-04-18T04:27:34.637 回答
6

?POSIXlt告诉你:

任何需要在两个日期时间类之间进行的转换都需要一个时区:从“POSIXlt”到“POSIXct”的转换将验证所选时区的时间。

所以我猜3600不是一个POSIXlt对象,有一个自动转换。

我会坚持简单:

new.lt = as.POSIXlt(my.lt + 3600)
class(new.lt)
[1] "POSIXlt" "POSIXt"

as.POSIXlt在您的时间操作之前添加它并不是那么麻烦。

于 2012-01-13T21:26:39.747 回答