いくつかのPOSIXlt
DateTimeオブジェクトを操作しています。たとえば、1時間追加したいとします。
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
に戻しますが、これを実現するためのよりエレガントで効率的な方法はありますか?
短い答え:いいえ
長い答え:
POSIXct
およびPOSIXlt
オブジェクトは、より一般的なPOSIXt
クラスの2つの特定のタイプです(厳密にオブジェクト指向の継承という意味ではなく、準オブジェクト指向の実装という意味で)。コードはこれらを自由に切り替えます。 POSIXlt
オブジェクトに追加する場合、実際に使用される関数は+.POSIXt
、POSIXlt
専用ではありません。この関数内では、引数はPOSIXct
に変換されてから処理(追加)されます。
さらに、POSIXct
は特定の日時からの秒数です。 POSIXlt
は日付部分(秒、分、時間、日、月、年、曜日、年、DST情報)のリストであるため、これに直接追加しても意味がありません。それを秒数(POSIXct
)に変換し、それに追加することには意味があります。
POSIXct
- classedオブジェクトは、内部的には数値計算を可能にする数値です。 POSIXlt
- objectsは内部的にリストです。残念ながら、Ops.POSIXt
( "+"を使用すると呼び出される)は、次のコードでPOSIXctに強制変換します。
if (inherits(e1, "POSIXlt") || is.character(e1))
e1 <- as.POSIXct(e1)
幸いなことに、1時間だけしたい場合は、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"
それほどエレガントではないかもしれませんが、
seq.POSIXt( from=Sys.time(), by="1 hour", length.out=2 )[2]
私見はより説明的です
Sys.time()+3600; # 60 minutes * 60 seconds
コード自体が、「POSIX」「seq」の単位が「1時間ずつ」増加することを文書化しているためですが、それは好みの問題です。 POSIXltでは問題なく動作しますが、どちらの方法でもPOSIXctを返すことに注意してください。 「日」でも機能します。月や夏時間などの処理方法の詳細については、help(seq.POSIXt)を参照してください。
?POSIXlt
は次のように説明しています。
2つの日時クラス間を移動する必要がある変換にはタイムゾーンが必要です。「POSIXlt」から「POSIXct」への変換では、選択したタイムゾーンの時刻が検証されます。
したがって、3600はPOSIXlt
オブジェクトではなく、自動変換があると思います。
私は単純に固執します:
new.lt = as.POSIXlt(my.lt + 3600)
class(new.lt)
[1] "POSIXlt" "POSIXt"
時間操作の前にas.POSIXlt
を追加するのはそれほど面倒ではありません。