Guide
繰り返しカレンダー予定:RRULE 解説
毎週のスタンドアップはデータベース上では1件、画面上では52件の予定です。すべてのカレンダーシステムはこのギャップを繰り返しルール — RFC 5545 の RRULE 文字列 — で処理しており、どの連携も最終的に同じ疑問に行き着きます:ルール構文の意味、シリーズをインスタンスに展開するのは誰か、1回のオカレンスが移動したらどうなるか。このガイドは Google、Microsoft Graph、CalDAV の仕様を並べて、この3つすべてに答えます。
Written by Hazik Director of Product Management
このガイドで使用するコマンドリファレンス: nylas calendar events list と nylas calendar events show。
RRULE とは?
RRULE は RFC 5545(iCalendar 仕様)で定義された繰り返しルールの文法で、繰り返しのスケジュールを1つの文字列で記述します。1つの ルールが何百もの保存行を置き換えます:予定は一度だけ存在し、ソフトウェアがオカレンスを導出します。 主要な3つのカレンダーシステムはすべて、RRULE をそのまま保存するか、境界で RRULE との相互変換を行います。
この文法には必須パートが1つ(FREQ)と、一連の修飾子があります。実際に使うのは以下の6つです — そしてどの修飾子よりも重要なのが RFC の1つの制約です:仕様は UNTIL と COUNT のパートは「同じ 'recur' に出現してはならない(MUST NOT)」と定めています。ルールの終わり方は ちょうど3通りのいずれかです:終わらない、N 回のオカレンスの後、または特定の日付。
| パート | 意味 | 例 |
|---|---|---|
FREQ | 基本の周期(必須) | FREQ=WEEKLY |
INTERVAL | N 周期ごと(デフォルト1) | INTERVAL=2 — 隔週 |
BYDAY | 曜日セレクタ。序数にも対応 | BYDAY=MO,WE,FR または BYDAY=-1FR(最終金曜日) |
BYMONTHDAY | 月内の日付セレクタ | BYMONTHDAY=15 |
COUNT | N 回のオカレンスで終了 | COUNT=12 |
UNTIL | UTC タイムスタンプで終了 | UNTIL=20261231T235959Z |
# Every Monday and Wednesday for 12 occurrences
RRULE:FREQ=WEEKLY;BYDAY=MO,WE;COUNT=12
# Biweekly Friday, forever
RRULE:FREQ=WEEKLY;INTERVAL=2;BYDAY=FR
# Last Friday of each month through 2026
RRULE:FREQ=MONTHLY;BYDAY=-1FR;UNTIL=20261231T235959Zシリーズをインスタンスに展開するのは誰か?
展開、つまり1つのルールを日付付きのオカレンスに変換する処理は、API ごとに異なる場所で行われ、 その場所がどれだけの繰り返し処理コードを書くかを決めます。Google はリクエスト時にサーバー側で展開し、 Graph は構造化オブジェクトを保存して instances ビューを公開し、CalDAV は生のルールをそのまま返して 計算をクライアントに任せます。3つのモデルを簡潔にまとめると:
- Google Calendar API —
events.listにsingleEvents=trueを渡すと、レスポンスには指定した時間枠内の個別インスタンスが含まれ、 各インスタンスはrecurringEventIdを持ちます。Google の 繰り返しイベントガイド がマスターとインスタンスのモデルを解説しています。 - Microsoft Graph — イベントは生の RRULE 文字列の代わりに、
pattern(周期)とrange(範囲)を持つ patternedRecurrence オブジェクトを保存します。インスタンス展開はシリーズマスターのinstancesビューから取得し、開始・終了パラメータで範囲を指定します。 - CalDAV — サーバーは VEVENT を RRULE 込みでそのまま返し、 タイムゾーン計算を含めてクライアントが展開します。これを自力で正しく実装するのが最も困難な道です。 RFC 5545 の繰り返しセクションが数十ページに及ぶのには理由があります。
実用的なルールはこうです:連携に必要なのが「今週何があるか」だけなら、展開を代行してくれる API(またはツール)を 選びましょう。正しいクライアント側エクスパンダを書くのは関数ではなくプロジェクトです。この3つの API の 繰り返し以外の違い(認証、空き状況、Webhook)については カレンダー API 比較を参照してください。このページは繰り返しの問題に集中します。
1回のオカレンスが移動・キャンセルされるとどうなるか?
変更された単一のオカレンスは例外(exception)になります:1つの日付についてルールを上書きする独立した レコードで、シリーズの残りはマスターに従います。各システムのエンコード方法は異なります — Google は originalStartTime フィールドを持つ別イベントを作成し、Graph は exception というオカレンスタイプとしてモデル化し、iCalendar は移動したインスタンスに一致する RECURRENCE-ID を持つ2つ目の VEVENT を追加します。
例外は素朴な同期コードが壊れる場所です。バグの大半は2つの失敗モードに起因します:例外を完全な新規イベントとして 扱う(ルール展開で1回、上書きで1回と、会議が二重に表示される)ことと、例外の上にシリーズ編集を適用する (ユーザーの一回限りの会議室変更が無言で元に戻る)ことです。同期ロジックはどちらのパスを適用する前にも 例外マーカーを確認する必要があります — 重複会議のサポートチケットよりはるかに安上がりな、2分岐のチェックです。
CLI から繰り返し予定を読み取るには?
nylas calendar events list コマンドは、指定した期間内の展開済みインスタンスを返すため、 毎週のシリーズは RRULE のパースを一切せずに日付付きのオカレンスとして表示されます。繰り返しシリーズの 各インスタンスはシリーズマスターにリンクする master_event_id を持ち、インスタンス自身の ID にはオカレンスのタイムスタンプが 埋め込まれています — どちらも JSON 出力で確認できます。
# Expanded instances for the next 30 days
nylas calendar events list --days 30 --json | jq '.[] | {
id: .id,
title: .title,
master: .master_event_id,
start: .when.start_time
}'
# Group instances by series to spot every recurring meeting
nylas calendar events list --days 30 --json | jq '
[.[] | select(.master_event_id != null)]
| group_by(.master_event_id)
| map({series: .[0].title, occurrences: length})'この2つのコマンドは Google、Microsoft、iCloud アカウントに対して同じように動作するため、 読み取りパスでは前のセクションで述べた API ごとの展開の違いが解消されます。正直な制限を1つ:CLI の calendar events create コマンドには繰り返しフラグがありません — シリーズの作成はプロバイダの UI または API で行い、 CLI は読み取り、フィルタリング、スクリプティング側を担当します。
繰り返し予定がサマータイム前後でずれるのはなぜか?
毎週9:00の会議は、固定の UTC オフセットではなく、名前付きタイムゾーンでの9:00です — つまり年に2回、 その UTC 時刻が1時間移動します。生の UTC に対して展開したルールは DST 切り替えのたびにずれます。 正しい展開は各オカレンスをタイムゾーンデータベース(UTC-5 ではなく America/Toronto)で解決します。これがクライアント側の CalDAV 展開が難しい主な理由であり、 RFC 5545 が UNTIL のタイムスタンプは UTC、イベント開始時刻はタイムゾーン参照付き、と 定めている点にも表れています。
3月や11月に発生する同期バグを調査するときは、何よりも先にエクスパンダがどの時計を使ったかを確認してください。 上のインスタンス JSON には期間イベントの start_timezone が含まれるため、期待と異なる タイムゾーンを持つインスタンスを1行の jq フィルタで抽出すれば、ずれたシリーズをすばやく特定できます。
次のステップ
- カレンダー API 比較:Google、Microsoft、CalDAV — 認証、空き状況、繰り返しの違いを1ページで
- プロバイダ間でカレンダーを同期 — 繰り返しの例外が最も痛手になる場所
- CLI から Google Calendar を管理 — Google 固有のイベントワークフロー
- CLI から Yahoo カレンダーを管理 — Yahoo の CalDAV ベースのカレンダーでの繰り返し読み取り
- コマンドリファレンス全体 — すべての calendar events フラグを文書化