2012-01-13 55 views
13

我正在操縱一些POSIXlt DateTime對象。例如,我想補充一個小時:如何在POSIXlt時間增加/減少時間,同時保持R的類別?

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,但是有沒有更優雅更高效的方法來實現這一目標?

回答

12

簡短的回答:沒有

龍答:

POSIXctPOSIXlt對象是兩種特定類型的更一般POSIXt類(不嚴格的面向對象的繼承感,但在準面向對象實現意義)。代碼在這些之間自由切換。當添加到POSIXlt對象時,實際使用的功能是+.POSIXt,而不是專門用於POSIXlt。在這個函數內部,參數被轉換成一個POSIXct然後處理(添加到)。

此外,POSIXct是從特定日期和時間開始的秒數。 POSIXlt是日期部分(秒,分鐘,小時,月,月,年,一週中的某一天,一年中的某一天,DST信息)的列表,因此直接添加到這些內容中沒有任何意義。將其轉換爲秒數(POSIXct),並添加到這一點是有道理的。

+1

Brian,據我所知,POSIXct是數字,POSIXlt是一個列表。然而,在這兩者之間不能總是自由地編碼。例如,當您轉換時區時,您必須使用日曆時間而不是本地時間(http://blog.revolutionanalytics.com/2009/06/converting-time-zones.html)。另一件事是在本地時間和字符之間進行轉換要比在日曆時間和字符之間進行轉換快得多。 – sunt 2012-01-13 21:38:17

5

?POSIXlt告訴你:

需要兩個日期,時間課間去任何轉換需要一個時區:從「POSIXlt」轉換爲「POSIXct」將在選定的時區驗證時間。

所以我猜,3600不是POSIXlt對象,有一個自動轉換。

我要堅持簡單:

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

這不是麻煩了你的時間操作之前添加as.POSIXlt

14

POSIXct -classed對象在內部是一個允許數字計算的數值。 POSIXlt - 對象是內部列表。不幸的是,你的願望,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" 
+0

其實R足夠聰明,可以在第二天如果需要: > 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」 對不起,似乎我不能給它一個很好的格式在評論中... – sunt 2012-01-13 22:08:50

+0

對,其實這是我的觀點。如果你增加25小時,你會得到第二天,再增加一小時。但是如果您添加100天並因此跨越DST邊界,則不會放棄添加一小時。 – 2012-01-14 01:08:17

7

它可能不是顯著更優雅,但

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

恕我直言比

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

更具描述性的,因爲代碼本身文檔你會爲一個「 POSIX「」seq「有效性增加了」1小時「,但這是一個品味問題。在POSIXlt上工作得很好,但請注意它會以任何方式返回POSIXct。也適用於「天」。請參閱幫助(seq.POSIXt)瞭解有關如何處理月,夏令時等的詳細信息。