// 2007.06.03 間瀬茂

SIZE(22){COLOR(BLUE){日付・時間関数Tips大全}}

Rには日付(date)オブジェクトを表すクラス "Date" と,日付時分秒(date-time)オブジェクトを表すクラス "POSIXlt", "POSIXct" がある.

*クラス "Date" [#x876570b]

クラス "Date" は date オブジェクト(年月日)を表し,1970-01-01 以来の経過日数(負の値は過去に遡る)で表現される.内部的には実数で表現されるが,表示の際は整数値とされる.日数との加減算,比較演算が可能である.format(), plot(), hist(), seq(), cut(), round() 関数は"Date" クラス用のメソッド関数を持つ.as.Date() は数値を "Date" オブジェクトに変換する.weekdays(), months() はそれぞれ曜日と月を返す.
 > (today <- Sys.Date())                      # 現在の日付
 [1] "2007-06-02"                             # 表示の際は整形される
 > str(today)                                 # 1970/1/1以来の経過日数値で表現されている
 Class 'Date'  num 13666
 > start <- 0; class(start) <- "Date"; start  # 起点年月日
 [1] "1970-01-01"
 > format(today, "%d %b %Y")                  # 月数を文字で表示
 [1] "02  6月 2007"
 > (weeks <- seq(today, len=5, by="1 week"))  # 次の5日
 [1] "2007-06-02" "2007-06-09" "2007-06-16" "2007-06-23" "2007-06-30"
 > weekdays(today)                            # 曜日
 [1] "土曜日"
 > months(weeks)                              # 月 
 [1] "6月" "6月" "6月" "6月" "6月"
 > as.Date(.leap.seconds)                     # 閏秒
 [1] "1972-07-01" "1973-01-01" "1974-01-01" "1975-01-01" "1976-01-01"
       (以下略)
 > (z <- Sys.Date())
 [1] "2007-06-02"
 > z + 10                                     # 10日後
 [1] "2007-06-12"
 > z < c("2006-06-01", "2007-01-01", "2010-01-01")  # 大小比較
 [1] FALSE FALSE  TRUE

* クラス "POSIXct", "POSIXlt","POSIXt" [#f389f5b3]

年月日時分秒を表すクラスには "POSIXlt" (1970年元旦からの符号付き経過秒)と,名前ラベル
年月日時分秒を表すクラスには "POSIXct" (1970年元旦からの符号付き経過秒)と,名前ラベル
   'sec' 0-61: 秒                            'min'  0-59: 分
  'hour' 0-23: 時                            'mday' 1-31: (一月中の)日
   'mon' 0-11: 月                            'year' 1900年からの経過年数
  'wday' 0-6:  一週中の日,日曜日から始まる  'yday' 0-365: 一年の間の日
 'isdst' サマータイム(daylight saving time)フラグ.正は有効,0は無効,負は不明
を持つ文字列リストである "POSIXct" の2種類がある.それぞれ ANSI C の "local time" (struct tm データタイプ) と "calendar time" (time-t データタイプ) に基づき,名前もそれらに由来する.クラス "POSIXt" は両者を含むクラスである."POSIXct" オブジェクトはデータフレーム中で使うのにより便利であるが,"POSIXlt" オブジェクトはより可読性が高い.オブジェクト同士の論理比較演算と,限定された算術演算(時間差を加減する)が定義されている.data-time オブジェクト同士の差には difftime() 関数が使われる.その際,"POSIXlt" オブジェクトはタイムゾーンを明示しない限り,現在のタイムゾーンが使われることに注意しよう.date-time オブジェクトの操作はタイムゾーン(サマータイムの有無を含む)と閏秒(これまで計23日)の存在によりかなり複雑になり,システムによっては不完全になる可能性がある.特にLinuxを含むUnix風システムでは,タイムゾーン環境変数 "TZ" を正しく設定する必要がある.date-time オブジェクトは環境変数 TZ から決まる属性 "tzone" をしばしば持つことがある.
を持つ文字列リストである "POSIXlt" の2種類がある.それぞれ ANSI C の "calendar time" (time-t データタイプ) と "local time" (struct tm データタイプ) に基づき,名前もそれらに由来する.クラス "POSIXt" は両者を含むクラスである."POSIXct" オブジェクトはデータフレーム中で使うのにより便利であるが,"POSIXlt" オブジェクトはより可読性が高い.オブジェクト同士の論理比較演算と,限定された算術演算(時間差を加減する)が定義されている.data-time オブジェクト同士の差には difftime() 関数が使われる.その際,"POSIXlt" オブジェクトはタイムゾーンを明示しない限り,現在のタイムゾーンが使われることに注意しよう.date-time オブジェクトの操作はタイムゾーン(サマータイムの有無を含む)と閏秒(これまで計23日)の存在によりかなり複雑になり,システムによっては不完全になる可能性がある.特にLinuxを含むUnix風システムでは,タイムゾーン環境変数 "TZ" を正しく設定する必要がある.date-time オブジェクトは環境変数 TZ から決まる属性 "tzone" をしばしば持つことがある.
 > (z <- Sys.time())                          # 現在の時間,クラス"POSIXct"オブジェクト
 [1] "2007-05-31 21:30:45 JST"
 > str(z)
 'POSIXct', format: chr "2007-05-31 21:38:07"
 > z - 3600                                   # 一時間前
 [1] "2007-05-31 21:30:45 JST"
 > as.POSIXlt(Sys.time(), "GMT")              # GMTでの現在の時間
 [1] "2007-05-31 12:38:07 GMT"
 > print(.leap.seconds)                       # 日本標準時での全ての閏秒
 [1] "1972-07-01 09:00:00" "1973-01-01 09:00:00" "1974-01-01 09:00:00"
 (途中略)
 [22] "1999-01-01 09:00:00" "2006-01-01 09:00:00"
 > print(.leap.seconds, tz="PST8PDT")         # Seattle標準時では
 [1] "1972-06-30 17:00:00 PDT" "1972-12-31 16:00:00 PST"
 (途中略)
 [23] "2005-12-31 16:00:00 PST"

* 時間差 difftime() [#uf575c93]

関数 difftime() は二つのdateもしくはdate-timeオブジェクトの差分を計算する.
結果はクラス "difftime",時間単位を表す属性 units (units()関数で操作できる)を持つ.
date-timeオブジェクト同士の差はこの関数をオプション units="auto" で呼び出す.
関数 as.difftime() は数値もしくは時間差の文字列表現を "difftime" オブジェクトに変換する.
"difftime" オブジェクトに対しては限定された算術演算(加減,スカラ−による乗除算)と,比較演算が可能である.
 書式:  time1 - time2
        difftime(time1, time2, tz = "",
                 units = c("auto", "secs", "mins", "hours", "days", "weeks"))
        as.difftime(time, format = "%X", units="auto")
        units(x),  units(x) <- value
 引数: time1,time2,time date, もしくは date-time オブジェクト
                     tz タイムゾーン.""は現在のタイムゾーンを表す
                  units 時間単位を表す文字列        

 > (z <- Sys.time() - 3600)
 [1] "2007-06-02 06:35:26 JST"
 > Sys.time() - z                              # 丁度3600秒
 Time difference of 1.000018 hours
 > ISOdate(2001, 4, 26) - ISOdate(2001, 2, 26) # R1.2.2とR1.2.3のリリース期間差
 Time difference of 59 days
 > as.difftime(c("0:3:20", "11:23:15"))        # 時間を文字列で与える
 Time differences in mins
 [1]   3.333333 683.250000
 attr(,"tzone")
 [1] ""

 > (z <- as.difftime(c(0,30,60), units="mins")) 秒,分,時間単位での表示.
 Time differences in mins
 [1]  0 30 60
 > as.numeric(z, units="secs")
 [1]    0 1800 3600
 > as.numeric(z, units="hours")
 [1] 0.0 0.5 1.0
 > format(z)
 [1] " 0 mins" "30 mins" "60 mins"

* date-timeクラスオブジェクトと文字列間の変換 [#k08f6c1b]

format(), as.character(), strftime() は date-time オブジェクトを文字列ベクトルに変換する.strptime() は逆に文字列を "POSIXlt" クラスオブジェクトに変換する.strftime() は format.POSIXlt() の別名である.変換はタイムゾーンに依存する.ISOdatetime() と ISOdate() は strptime() 関数のラッパ関数であり,既定値だけが異なる.サマータイムの開始と終了に伴い,存在しない時間,二度登場する時間があることに注意しよう.これらの関数はタイムゾーンを指定する引数 tz や,書式引数 format を持つ(ISO C/POSIX 標準に従う).詳細はhelp(ISOdate) を参照.
 > format(Sys.time(), "%a %b %d %X %Y %Z")        # date()関数のロケール依存版
 [1] "土  6月 02 07時42分03秒 2007 JST"
 > format(Sys.time(), "%H:%M:%OS3")               # 0.1秒単位の表示(OSがサポートすれば)
 [1] "07:42:03.220"
 > dates <- c("02/27/92", "02/27/92", "01/14/92") # 書式'm/d/y h:m:s'使用例     
 > times <- c("23:03:20", "22:29:56", "01:03:30")
 > strptime(paste(dates, times), "%m/%d/%y %H:%M:%S")
 [1] "1992-02-27 23:03:20" "1992-02-27 22:29:56" "1992-01-14 01:03:30"

*ジュリアン通日 (Julian date) [#xa0f86d3]

計算機による日付の処理では「ジュリアン通日(Julian date)」と呼ばれる,ある起点日付からの正負の経過日数で表す流儀が普通である.日付・時間専用のRパッケージ date にはジュリアン通日を年月日形式に変換する date.mmddyyyy() 関数がある.注意すべきは
 > date.mmddyyyy(0)           # dateパッケージの起点年月日
 [1] "1/1/1960"
と起点年月日が異なること.Unix界では 1970/1/1/0:00:00} からの経過秒数で年月日時分秒を表す慣習があり,POSIX規約はこれを継承している.一方 SAS では 1960/1/1 からの経過日数を使い,date パッケージはこれを継承している.Julian date を扱うときは,まず起点年月日そして時刻を確認する必要がある.なお,年月日をどういう順序で並べるかも国により微妙に違い.ロケール(言語や国・地域ごとに異なる単位,記号,日付,通貨などの表記規則の集合) で決められている.

注:ジュリアン通日とは,本来 BC 4713/1/1 の正午を起点とする主に天文学で使われる日付計算用の単位で,1583年に Joseph Justus Scaliger により,ユリウス暦,グレゴリオ暦双方での日付の変換や,日数計算のために提案され,天文学者ジョン・ハーシェルがその著書で使って以来広まった.通説では Julian とは Scaliger の父親の名前に由来し,ユリウス暦の Julius(つまりシーザー)とは無関係である.

*タイムゾーン [#i728473c]

当然だが,同じ日付・時間でもタイムゾーンにより異なる.異なったタイムゾーンでの日付・時間データを扱うときはこの点に注意が必要になる."POSIXlt" オブジェクトはタイムゾーンを表すタイム属性 "tzone" を持つ.
 > ( z <- Sys.time() )
 [1] "2007-06-03 22:32:06 JST"
 > attributes(z)
 $class
 [1] "POSIXt"  "POSIXct"           # POSIXctオブジェクト,タイムゾーン属性は無い
 > ( zz <- as.POSIXlt(z, "GMT") )  # POSIXltオブジェクトに変換,タイムゾーンはGMT
 [1] "2007-06-03 13:32:06 GMT"
 > attributes(zz)
 $names
 [1] "sec"   "min"   "hour"  "mday"  "mon"   "year"  "wday"  "yday"  "isdst"
 $class
 [1] "POSIXt"  "POSIXlt"
 $tzone                             # タイムゾーン属性が付け加わる
 [1] "GMT"
 > (zzz <- as.POSIXlt(zz, "JST"))   # タイムゾーンをJSTに戻す ※少なくとも2.13.2ではunknown timezoneとされるので、Asia/Tokyoを入力
 [1] "2007-06-03 13:32:06 GMT"      # タイムゾーンは依然GMTのまま
 > attributes(zzz)
 $names
 [1] "sec"   "min"   "hour"  "mday"  "mon"   "year"  "wday"  "yday"  "isdst"
 $class
 [1] "POSIXt"  "POSIXlt"
 $tzone
 [1] "GMT"
 > (zzzz <- as.POSIXct(zz, "JST"))  # POSIXctオブジェクトへ,タイムゾーンはJST
 [1] "2007-06-03 13:32:06 JST"
 > attributes(zzzz)
 $class
 [1] "POSIXt"  "POSIXct"
 $tzone
 [1] "JST"                          # タイムゾーン属性JSTが付く

*連続する日付の生成 [#p4cb3ccb]
 > seq(as.Date("2010-07-31"), as.Date("2010-08-10"), by="days")
  [1] "2010-07-31" "2010-08-01" "2010-08-02" "2010-08-03" "2010-08-04"
  [6] "2010-08-05" "2010-08-06" "2010-08-07" "2010-08-08" "2010-08-09"
 [11] "2010-08-10"

既出でした~
 > library(chron)
 > seq.dates("05/03/2002", "05/08/2002")
 [1] 05/03/02 05/04/02 05/05/02 05/06/02 05/07/02 05/08/02
月日の順序はアメリカ式とイギリス式とか。文字列にしたいなら,as.character()


*日付・時間用のパッケージ [#b12ebd67]

Rの貢献パッケージには chron, date, fCalendar といった日付・時間専用のパッケージがある。例えば、パッケージの date には次の関数がある.
 as.date        データをdateオブジェクトに強制変換
 date.ddmmmyy   Julian dateを/dd/mm/yy形式に整形
 date.mdy       Julian dateを月日年(曜日)文字列リストに変換
 date.mmddyy    Julian dateをmm/dd/yy 形式に整形
 date.mmddyyyy  Julian dateをmm/dd/yyyy 形式に整形
 is.date        Dateオブジェクト検査
 mdy.date       Julian dateに変換

トップ   編集 差分 バックアップ 添付 複製 名前変更 リロード   新規 一覧 検索 最終更新   ヘルプ   最終更新のRSS