カレンダーの予定のような繰り返しのデータ定義を実装するにあたり、RFC5545(旧RFC2445)のRRULEというのがあるのを知ったので
それについて調べたメモ。中でも 3.3.10. Recurrence Rule
についてのみ取り扱っている。
比べると、記述方法が若干変わっていた。RFC5545の方が説明が増えて読みやすくなっている。
今回は繰り返しのデータ定義方法の参考にしたいだけなのでどちらでも特に問題はない。
書式
/
は ORの意味
recur = recur-rule-part *( ";" recur-rule-part )
recur-rule-part
を ;
で区切りながら連続表記する。
- ルールの順序は考慮しない
FREQ
ルールは必須。ただし複数回登場してはならない
- UNTIL または COUNTはオプション。ただし、UNTIL と COUNT は同時には指定できない
- それ以外はオプションで指定可能。ただし複数回登場してはならない
recur-rule-part = ( "FREQ" "=" freq )
/ ( "UNTIL" "=" enddate )
/ ( "COUNT" "=" 1*DIGIT )
/ ( "INTERVAL" "=" 1*DIGIT )
/ ( "BYSECOND" "=" byseclist )
/ ( "BYMINUTE" "=" byminlist )
/ ( "BYHOUR" "=" byhrlist )
/ ( "BYDAY" "=" bywdaylist )
/ ( "BYMONTHDAY" "=" bymodaylist )
/ ( "BYYEARDAY" "=" byyrdaylist )
/ ( "BYWEEKNO" "=" bywknolist )
/ ( "BYMONTH" "=" bymolist )
/ ( "BYSETPOS" "=" bysplist )
/ ( "WKST" "=" weekday )
ぱっと見わかりにくいのだけど、続く文章で各項目を説明している。
freq(周期)
SECONDLY
/ MINUTELY
/ HOURLY
/ DAILY
/ WEEKLY
/ MONTHLY
/ YEARLY
のいずれか
enddate (終了日)
日付または日時
enddate = date / date-time
byseclist (秒指定)
秒を指定。秒をカンマ区切りで複数回指定できる。
byseclist = ( seconds *("," seconds) )
seconds = 1*2DIGIT ;0 to 60 1から2桁の整数。0 〜 60まで。0と60の違いは不明。
byminlist (分指定)
分を指定。分をカンマ区切りで複数回指定できる
byminlist = ( minutes *("," minutes) )
minutes = 1*2DIGIT ;0 to 59 #1から2桁の整数。0 〜 59まで
byhrlist (時間指定)
時間を指定。カンマ区切りで複数回指定できる。
byhrlist = ( hour *("," hour) )
hour = 1*2DIGIT ;0 to 23 # 1から2桁の整数。0〜23まで
bywdaylist(曜日指定)
weekdaynumをカンマ区切りで複数回指定できる。
bywdaylist = ( weekdaynum *("," weekdaynum) )
weekdaynum = [[plus / minus] ordwk] weekday # その年の何週目の何曜日か。
plus = "+"
minus = "-"
ordwk = 1*2DIGIT ;1 to 53 # 年の何週目か。1または2桁。1から53まで
weekday = "SU" / "MO" / "TU" / "WE" / "TH" / "FR" / "SA"
(それぞれ SUNDAY, MONDAY, TUESDAY, WEDNESDAY, THURSDAY, FRIDAY, SATURDAY に対応)
bymodaylist (月日指定)
月の何日目かを指定する。複数回指定可能
bymodaylist = ( monthdaynum *("," monthdaynum) )
monthdaynum = [plus / minus] ordmoday # 何日目かを指定する
ordmoday = 1*2DIGIT ;1 to 31 # 1または2桁。1から31まで
byyrdaylist(年の何日目かを指定)
yeardaynum
を複数回指定できる
byyrdaylist = ( yeardaynum *("," yeardaynum) )
yeardaynum = [plus / minus] ordyrday # 年の何日目か
ordyrday = 1*3DIGIT ;1 to 366 # 1桁から3桁。 1から366まで
bywknolist(何番目の週か)
bywknolist = ( weeknum *("," weeknum) )
weeknum = [plus / minus] ordwk
ordwk #1または2桁。1から53まで
bymolist(月指定)
bymolist = ( monthnum *("," monthnum) ) # 月をカンマ区切りで複数回
monthnum = 1*2DIGIT ;1 to 12 #1桁または2桁。 1から12
bysplist(日の位置指定)
bysplist = ( setposday *("," setposday) ) # 何番目の日かを指定
setposday = yeardaynum
yeardaynum = [plus / minus] ordyrday # 年の何日目か
ordyrday = 1*3DIGIT ;1 to 366 # 1桁から3桁。 1から366まで
FREQ
- SECONDLY、1秒以上の間隔に基づいて繰り返しイベントを指定
- MINUTELY、1分以上の間隔に基づいて繰り返しイベントを指定
- HOURLY、1時間以上の間隔に基づいて繰り返しイベントを指定
- DAILY、1日以上の間隔に基づいて繰り返しイベントを指定
- WEEKLY、1週間以上の間隔に基づいて繰り返しイベントを指定
- MONTHLY、1ヶ月以上の間隔に基づいて繰り返しイベントを指定
- YEARLY、1年以上の間隔に基づいて繰り返しイベントを指定
INTERVAL
どの間隔で繰り返すかを指定。デフォルトは1で、毎秒、毎分、毎時、毎日、毎週、毎月、毎年を表す。
例えば FREQ=DAILY;INTERVAL=8
は8日ごとを表す。
UNTIL
- 繰り返しの終了日('DATE')または終了日時(
DATE-TIME
)を表す。
UNTIL
ルール部は、繰り返しルールの境界を含むDATEまたはDATE-TIME値を包括的に定義する
UNTIL
で指定された値が指定された繰り返しと同期している場合は、この'DATE'または'DATE-TIME'が繰り返しの最後のインスタンスになる
- 'UNTIL'ルールパートの値は
DTSTART
プロパティと同じ値型を持たなければならない。
さらに、 DTSTART
プロパティが現地時間の日付として指定されている場合、UNTIL
ルール部分も現地時間の日付として指定されなければならない
DTSTART
プロパティがUTC時間付きの日付または現地時間とタイムゾーン参照付きの日付として指定されている場合、UNTIL
ルール部分はUTC時間付きの日付として指定されなければならない
STANDARD
とDAYLIGHT
サブコンポーネントの場合、UNTILルールパートは常にUTC時間付きの日付として指定されなければならない
DATE-TIME
値として指定されているなら、それはUTC時間フォーマットで指定されなければならない
UNTIL
が存在しない場合、およびCOUNT
ルール部分も存在しない場合、RRULE
は永遠に繰り返されると見なされる。
COUNT
- 出現回数を定義
DTSTART
の値は最初の出現としてカウントされる
BYSECOND
- 1分以内の秒。カンマ区切りのリストで表される
- 有効な値は0から60
DTSTART
が DATE
の場合は指定できない
BYMINUTE
- 1時間以内の分。カンマ区切りのリストで表される
- 有効な値は 0 - 59
DTSTART
が DATE
の場合は指定できない
BYHOUR
- 1日の時間。カンマ区切りのリストで表される
- 有効な値は 0 - 23
DTSTART
が DATE
の場合は指定できない
BYDAY
- カンマ区切りの曜日のリストを表す
FREQ=MONTHLY
ルールでは +1MO
はその月の最初の月曜日を意味し、 -1MO
は最後の月曜を意味する
FREQ=YEARLY
の場合、BYMONTH
で指定した月のオフセットに対応し、 BYWEEKNO
または BYMONTH
が存在する年内のオフセットに対応する。
(注:仕様書上BYMONTHが2回出てくるので文章が間違ってるかも)
- 数値が指定されていない場合、毎週実行される
FREQ=MONTHLY
またはYEARLY
でない場合は数値は指定できない
FREQ=YEARLY
で BYWEEKNO
が指定されている場合は BYDAY
に数値は指定できない
BYMONTHDAY
- カンマ区切りの月の日のリストを表す
- 有効な値は1から31または-31から-1
- -10はその月の最後の日から10日を表す
FREQ=WEEKLY
の場合には指定できない
BYYEARDAY
- カンマ区切りの年の通算日を表す
- 有効な値は1から366または-366から-1
- -1は年の最後の日(12月31日)を表す
- -306は、その年の最後の日から306日前(3月1日)を表す
FREQ
が DAILY
,WEEKLY
, MONTHLY
のいずれかの場合は指定できない
BYWEEKNO
- カンマ区切りの年の何番目の週かを表す
- 有効値は1〜53 または-53から-1
- 週は
WKST
で定義された曜日から始まる7日間を表す
- 暦年の週番号1は、その暦年の最低4日を含む最初の週
FREQ=YEARLY
以外では指定できない
BYWEEKNO=3
は年の3番目の週を表す
BYMONTH
WKST
- 週の始まりの曜日を指定する(MO, TU, WE, TH, FR, SA, and SU)
- デフォルトは月曜
BYSETPOS
- ルールで指定された繰り返しのn番目の発生に対応する値をカンマ区切りで指定する
- 1つの
INTERVAL
内の一連の繰り返しに対して処理する
- 例えば
FREQ=WEEKLY
の場合、毎週の先頭に対して作用する
- 有効な値は1から366または-366から-1
BYxxx
と共に使用される必要がある
- もし指定された場合、特定のルールの条件を満たすもののなかでn番目に発生するものを示す
例:月の最終就業日
FREQ=MONTHLY;BYDAY=MO,TU,WE,TH,FR;BYSETPOS=-1
その他
- 繰り返しルールは無効な繰り返しインスタンスを生成する可能性がある
- それらは無視し、ルールとしてカウント対象として認めない。
- ルールに含まれない情報は
DTSTART
から派生(継承)する
FREQ=YEARLY;BYMONTH=1
は月の何日かを指定していないが、DTSTART
の日が使われる
- BYxxxは何らかの方法で繰り返し回数を修正する。
- frequencyより大きいBYxxxの指定は通常発生回数を減らす
FREQ = DAILY; BYMONTH = 1
は毎日→1月のみになる
- frequencyより小さいBYxxxの指定は通常発生回数を増やす
FREQ = YEARLY; BYMONTH = 1,2
は 毎年1回から2回になる
評価順について
- 複数のBYxxxが指定されている場合、
FREQ
と INTERVAL
が評価されたあとで以下の順に適用される
- BYMONTH
- BYWEEKNO
- BYYEARDAY
- BYMONTHDAY
- BYDAY
- BYHOUR
- BYMINUTE
- BYSECOND
- BYSETPOS
- COUNT / UNTIL
依存関係
表の意味
N/A
はそのFREQ
では使用できない
BYDAY
はFREQ
に応じて特殊な振る舞いをする(Note1, 2を参照)
- LimitはFREQの対象が狭まる
- ExpandはFREQの対象が広がる
SECONDLY |
MINUTELY |
HOURLY |
DAILY |
WEEKLY |
MONTHLY |
YEARLY |
BYMONTH |
Limit |
Limit |
Limit |
Limit |
Limit |
Limit |Expand |
BYWEEKNO |
N/A |
N/A |
N/A |
N/A |
N/A |
N/A |Expand |
BYYEARDAY |
Limit |
Limit |
Limit |
N/A |
N/A |
N/A |Expand |
BYMONTHDAY |
Limit |
Limit |
Limit |
Limit |
N/A |
Expand |Expand |
BYDAY |
Limit |
Limit |
Limit |
Limit |
Expand |
Note 1 |Note 2 |
BYHOUR |
Limit |
Limit |
Limit |
Expand |
Expand |
Expand |Expand |
BYMINUTE |
Limit |
Limit |
Expand |
Expand |
Expand |
Expand |Expand |
BYSECOND |
Limit |
Expand |
Expand |
Expand |
Expand |
Expand |Expand |
BYSETPOS |
Limit |
Limit |
Limit |
Limit |
Limit |
Limit |Limit |
- Note 1. BYMONTHDAYがある場合は制限される。そうでなければMONTHLY用にExpandされる
- Note 2. BYYEARDAY or BYMONTHDAY がある場合は制限される。
- そうでなく
BYWEEKNO
がある場合は WEEKLY
が拡張される
- そうでなく
BYMONTH
がある場合は MONTHLY
が拡張される
- そうでない場合は
YEARLY
が拡張される
参考