0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

ICS to CSV コンバータ icsconvcsv テクニカルメモ

0
Last updated at Posted at 2025-12-17

はじめに

別途提供するICSファイルをGaroon形式のCSVに変換するプログラicsconvcsvの資料の一部になります。(ソフトウエア名を変更してます。旧名はics2gacsvです。)

1. iCalendar(ICS)の仕様書

  • iCalendar(ICS)の仕様は以下のRFC5545によってます。

日本語版

軽く目を通してから、本文章を参照ください。

2. 本文章で取り上げるソフトウエア

  • グループウエアCybozu Garoon(Version 5.0.2)
    以降「Garoon」と略記します。

    有償ソフトです。スケジュール表を作る機能があります。スケジュール表をICS形式およびCSV形式で出力する機能があります。

    アプリ「icsconvcsv」はGaroonが生成するCSVと同一フォーマットのファイルを生成可能です。

  • Webブラウザ版のOutlook
    以降「Outlook(Web)」と略記します。

    有償版のMicrosoft365で提供されるバージョンと、無料版のOutlookで提供されるバージョンがあります。若干挙動が異なります。

    Outlookは本来メールソフトですが、スケジュール表を作る機能がありす。スケジュール表をICS形式で出力する機能があります。

  • Windowsアプリ版 のOutlook(new)
    以降「Outlook(new)」と略記します。

    スケジュール表をICS形式で出力する機能があります。主観ですが、いろいろな挙動がOutlook(Web)と同じようです。Outlook(Web)関係の記述はOutlook(new)とほぼ同じとお考えください。

  • Windowsアプリ版 のOutlook(classic)
    以降「Outlook(classic)」と略記します。

    有償ソフトです。Microsoft365で提供されるバージョンで確認してます。ケジュール表をICS形式およびCSV形式で出力する機能があります。但しCSVの出力形式はGaroonと異なります。

上記で3種類のOutlookを取り上げていますが、同一のアカウントでログインすることにより、異なるアプリ間でスケジュール表を共有することができます。

※バージョンアップなどで挙動が変更になる可能性があります。2025年9月から12月ごろの挙動に沿って説明しています。

3. 終日スケジュールについて

時刻指定がない、日付のみのスケジュールを「終日スケジュール」と呼ぶことにします。アプリでいろいろと挙動が異なりますので、注意が必要になります。

3.1 終日スケジュール(時刻なし)

例えば

  • 時刻情報がない2025年11月11日の24時間の終日スケジュール

ですが、これを「終日スケジュール(時刻なし)」とよぶ事にします。Garoonでは「時」と「分」の入力で数字を選択せず「--」を選択する事により入力できます。

Outlook(classic)とOutlook(Web)では「終日」をクリックする事により入力できます。

上記方法で入力した「終日スケジュール(時刻なし)」のファイル出力時の内部表現として、下記の3種類を把握してます。

  • 「時刻あり」 開始:2025年11月11日0:00、 終了:2025年11月12日0:00
    → Outlook(classic)が生成するCSVファイル

  • 「時刻なし1」 開始:2025年11月11日、 終了:2025年11月11日 (開始と同じ日)
    → Garoonが生成するCSVファイル

  • 「時刻なし2」 開始:2025年11月11日、 終了:2025年11月12日 (翌日)
    → アプリ問わずICSファイルは本形式になります。

上記のようにアプリによって様々です。

3.2 終日スケジュール(時刻あり)

次に、各種カレンダーアプリのスケジュール表に明示的に

  • 0:00開始、翌日0:00終了

と入力しても終日スケジュール扱いとなる場合があります。例えばOutlook(Web)はアプリ上で表記が「終日」になります。

これを「終日スケジュール(時刻あり)」とよぶ事にします。

この場合のファイル出力時の内部表現は、確認した範囲のすべてのICSとCSVで「時刻あり」となります。

上記をまとめると、Outlook(classic)が出力するCSVファイルはアプリ入力時に

  • 「終日スケジュール(時刻なし)」

であっても、

  • 「終日スケジュール(時刻あり)」

であってもファイル出力時は常に「時刻あり」になります。

但しOutlook(classic)のCSVのヘッダに"終日イベント"というのがありまして、そのデータを使って区別することはできます。

3.3 終日スケジュールのまとめ

以降、終日スケジュールを以下のように表記します。

スケジュール入力時の表現:

  • 終日スケジュール(時刻あり)
  • 終日スケジュール(時刻なし)

内部表現(ファイルに出力時の表現):

  • 終日スケジュール内部表現(時刻あり)
  • 終日スケジュール内部表現(時刻なし1)
  • 終日スケジュール内部表現(時刻なし2)

と表記します。

※終日スケジュールは業務記録の視点から見ると注意が必要になります。「終日スケジュール(時刻あり)」は特別な扱いをしないと、24時間連続勤務との区別が出来なくなります。

4. TimeZone

日本国内に住んでるとTimeZoneについて意識する事は少ないかと思いますが、ICSの処理ではTimeZone、具体的にはローカルタイムゾーン(日本標準時など)と協定世界時(UTC/GMT)の時差について正しく掌握してないと、正しく変換できない場合があります。具体的には後述してますが、繰返し命令RRULEのUNTILの処理で誤ったCSVを生成する可能性があります。

次に、おそらくサマータイム(夏時間)の切り替わり時に発生する1日が25時間/23時間の日の処理は正しくできないと思います。

※最低限のTimeZone関係の処理をいれてますが、真面目にデバッグしてないので、ご承知ください。

4.1 Floating Time

ICSファイルにTimeZoneが一切定義されてない場合があります。TimeZoneが無いICSファイルは「Floating Time」と呼ばれます。(Ref: RFC5545, 3.3.12. TIME)

4.2 引数「-T」で指定可能なTimeZoneについて

引数「-T」で指定可能な値は、ICSファイルのVTIMEZONEで定義されているTimeZoneと、Pythonのライブラリtzdateに定義されているTimeZoneです。tzdateに定義されているTimeZoneは以下のコードでダンプできます。Windowsでは、ライブラリtzdateをインストールしてない場合は下記の出力は空ですので、TimeZoneの指定をする場合はtzdateライブラリを導入してください。

./tminezone-dump.py
import zoneinfo
print(zoneinfo.available_timezones())

5. Garoonの出力するCSVの形式

Garoonで作成したスケジュール表が生成するCSVは下記の形式になっています。

文字コード: ShiftJIS + 改行(CR+LF)
※ダブルクオート内部の改行はLFになってる。
※ガルーンのCSVにはTimeZone情報は一切無い。

以下の対応で出力される。タイトルが分割されることにご留意ください。

Garoonの入力値 → CSVの出力値

開始日時  →  開始日,開始時刻
終了日時  →  終了日,終了時刻
タイトルの選択肢:「出張」 → 予定: 「出張」
タイトルの本文:「東京特許許可局」 →予定詳細: 「東京特許許可局」
メモ → メモ.

CSVの出力の例は下記のようになる。(エディタEmacs利用者向けコメント1)

CSVの出力の具体例
"開始日","開始時刻","終了日","終了時刻","予定","予定詳細","メモ"(改行CR+LF)
"2025/10/10","13:00:00","2025/10/10","16:00:00","出張","東京特許許可局","1234(業務番号)(改行LF)
(改行LF)
業務内容。この枠内は可能ならプレインテキストで入れてください。"(改行CR+LF)

※メモ欄の記入内容は職場の指定書式ですので気にしないでください。

5.1 TimeZone

TimeZone関係の情報は一切含まれません。

5.2 終日スケジュール(時刻なし)

終日スケジュール(時刻なし)は、終日スケジュール内部表現(時刻なし1)として出力されます。

Garoon入力例1

Garoon入力例1: 1日(24時間の予定)
開始日: 2025/11/28
開始時刻: (空)
終了日: 2025/11/28
終了時刻: (空)
CSVの出力の具体例:
"2025/11/28","","2025/11/28","","","(テスト)時刻指定なしスケジュール",""

Garoon入力例2

Garoon入力例2: 2日(48時間の予定)
開始日: 2025/11/26
開始時刻: (空)
終了日: 2025/11/27
終了時刻: (空)
CSVの出力の具体例
"2025/11/26","","2025/11/27","","","(テスト)時刻指定なしスケジュール2日以上",""

5.3 繰り返し予定

Garoonで「繰り返し予定」を設定したとき、CSVにエクスポートしたときは繰り返し命令などは使わずに展開された状態で出力されます。

6. Outlook(Web)の出力するICSの形式

文字コード: UTF-8 + CR+LF

ICSはプレインテキストですので、テキストエディタで閲覧できます。個々のスケジュールは「BEGIN:VEVENT」「END:VEVENT」でくくられています。先ほどのGaroonと同等のスケジュールは以下のような形で出力されています。

BEGIN:VEVENT
DESCRIPTION:1234(業務番号)\n\n業務内容。この枠内は可能な
 らプレインテキストで入れてください。\n
UID:XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
SUMMARY:出張:東京特許許可局
DTSTART;TZID=Tokyo Standard Time:20251010T130000
DTEND;TZID=Tokyo Standard Time:20251010T160000
CLASS:PUBLIC
PRIORITY:5
DTSTAMP:20250924T030059Z
(省略)
END:VEVENT

非常に長い文章の場合は行分割がある。改行して空白1文字入れて継続行となる。LDAPのLDIF形式と同じ。

6.1 TimeZone

TimeZoneの定義はICSファイルの冒頭部分に定義があります。

ICSのヘッダのTimeZoneの定義「Tokyo Standard Time」
BEGIN:VTIMEZONE
TZID:Tokyo Standard Time
BEGIN:STANDARD
DTSTART:16010101T000000
TZOFFSETFROM:+0900
TZOFFSETTO:+0900
END:STANDARD
BEGIN:DAYLIGHT
DTSTART:16010101T000000
TZOFFSETFROM:+0900
TZOFFSETTO:+0900
END:DAYLIGHT
END:VTIMEZONE

このTimeZoneがDTSTARTやDTENDに以下のような形で設定されています。

スケジュールの開始時間
DTSTART;TZID=Tokyo Standard Time:20251010T130000
スケジュールの終了時間
DTEND;TZID=Tokyo Standard Time:20251010T160000

他のTimeZoneを設定したOutlookのIDで生成されるICSファイル、例えばアメリカ東部時間では次のような定義になっています。

アメリカ東部時間「Eastern Standard Time」
BEGIN:VTIMEZONE
TZID:Eastern Standard Time
BEGIN:STANDARD
DTSTART:16010101T020000
TZOFFSETFROM:-0400
TZOFFSETTO:-0500
RRULE:FREQ=YEARLY;INTERVAL=1;BYDAY=1SU;BYMONTH=11
END:STANDARD
BEGIN:DAYLIGHT
DTSTART:16010101T020000
TZOFFSETFROM:-0500
TZOFFSETTO:-0400
RRULE:FREQ=YEARLY;INTERVAL=1;BYDAY=2SU;BYMONTH=3
END:DAYLIGHT
END:VTIMEZONE

夏時間があるTimeZoneのため、少々複雑な定義になっています。

6.2 終日スケジュール

ICSでは常に終日スケジュール(時刻なし)は終日スケジュール内部表現(時刻なし2)として出力されます。また時刻がない場合はTimeZone情報がつきません。

例: 1日(24時間の予定)
開始日: 2025/11/28
開始時刻: (空)
終了日: 2025/11/28
終了時刻: (空)
ICSの出力の具体例:
BEGIN:VEVENT
DESCRIPTION:\n
SUMMARY:(テスト)時刻指定なしスケジュール
DTSTART;VALUE=DATE:20251128
DTEND;VALUE=DATE:20251129
END:VEVENT
例: 2日(48時間の予定)
開始日: 2025/11/26
開始時刻: (空)
終了日: 2025/11/27
終了時刻: (空)
ICSの出力の具体例:
BEGIN:VEVENT
DESCRIPTION:\n
SUMMARY:(テスト)時刻指定なしスケジュール2日以上
DTSTART;VALUE=DATE:20251126
DTEND;VALUE=DATE:20251128
END:VEVENT

6.3 繰り返しスケジュール(RRULE)の上書きスケジュール(RECURRENCE-ID)

RECURRENCE-IDで上書きされたスケジュールのDESCRIPTIONおよびSUMMARYは常に入ってます。そのため参照元の繰返しスケジュール(RRULE)の情報を参照する必要はありません。

6.4 繰り返しスケジュール(RRULE)の終日スケジュール(時刻なし)のTimeZoneの奇怪な仕様

毎週月曜日2026年4月27日(月)-6月1日(月)の終日スケジュール(時刻なし)で、5月4日を除外日(EXDATE)とすると以下のようなICSが生成されます。

RRULE:FREQ=WEEKLY;UNTIL=20260531T150000Z;INTERVAL=1;BYDAY=MO;WKST=SU
EXDATE;TZID=Tokyo Standard Time:20260504T000000
DTSTART;VALUE=DATE:20260427
DTEND;VALUE=DATE:20260428

上記繰返し日程の5月25日(月)を修正する上書きスケジュール(RECURRENCE-ID)は

RECURRENCE-ID;TZID=Tokyo Standard Time:20260525T000000

となります。

DTSTARTおよびDTENDは日付情報とTimeZoneが無いです。しかし除外日である、EXDATEおよび上書きスケジュールのRECURRENCE-IDはTimeZoneありで日本時間(Tokyo Standard Time)になっています。

また繰返し日程の終了日であるUNTILは「Z」が最後についてますがこれはUTC(協定世界時)となっています。

UTCと日本時間の時差は+9時間ですので、最終日(UNTIL)で指定されている「20260531T150000Z」は日本時間に変換すると、2026年6月1日の0:00になります。もし誤って2026年5月31日として扱ってしまうと、繰り返しスケジュールの最終日である6月1日が欠落します。

以上のように、混在しています。そのため、繰返しスケジュール(RRULE)を処理するためにはTimeZoneを正しく掌握しておく必要があります。

6.5 その他(セキュリティ上の留意点)

スケジュール機能でTeams会議などを開催すると、メモ欄(DESCRIPTION)にTeams会議のパスワードが記載されます。うかつにICSファイルを公開すると、セキュリティ上の問題が発生します。

7. Outlook(classic)の出力するICSの形式

7.1 TimeZone

日本語環境ではICSのヘッダのVTIMEZONEにTimeZoneが2個定義されています。

  • TZID:東京 (標準時)
  • TZID:Tokyo Standard Time

どちらも同じ定義となってますが、同一視してよいかのチェックが難しいため、TimeZoneが二個定義されている旨の警告を出すようにしています。

ICSファイル抜粋
BEGIN:VTIMEZONE
TZID:Tokyo Standard Time
BEGIN:STANDARD
DTSTART:16010101T000000
TZOFFSETFROM:+0900
TZOFFSETTO:+0900
END:STANDARD
END:VTIMEZONE

BEGIN:VTIMEZONE
TZID:東京 (標準時)
BEGIN:STANDARD
DTSTART:16010101T000000
TZOFFSETFROM:+0900
TZOFFSETTO:+0900
END:STANDARD
END:VTIMEZONE
BEGIN:VEVENT

7.2 繰返しスケジュール(RRULE)の終日スケジュールのTimeZone

Outlook(Web)ではTimeZoneが複雑な奇怪なICSが生成されてましたが、Outlook(classic)ではわりと素直なICSが生成されます。

毎週月曜日2026年4月27日(月)-6月1日(月)の終日スケジュール(時刻なし)で、5月4日を除外日(EXDATE)とすると以下のようなICSが生成されます。

ICSファイル抜粋
DTSTART;VALUE=DATE:20260427
EXDATE;VALUE=DATE:20260504
RRULE:FREQ=WEEKLY;COUNT=6;BYDAY=MO

上記繰返し日程の5月25日(月)を修正する上書きスケジュール(RECURRENCE-ID)は

RECURRENCE-ID;VALUE=DATE:20260525

となります。Outlook(Web)とはことなりOutlook(classic)ではTimeZoneは不要となります。

また繰返し日程の終了日はUNTILではなく、繰返し回数を示すCOUNTになっています。

7.3 繰返しスケジュール(RRULE)の上書きスケジュール(RECURRENCE-ID)

上書きスケジュール(RECURRENCE-ID)で上書きされたスケジュールのDESCRIPTIONおよびSUMMARYは内容が修正された場合のみ入っています。

そのため日付のみ上書きされた場合は参照元の繰返しスケジュール(RRULE)のDESCRIPTIONおよびSUMMARYを参照する必要があります。

この処理のため、参照元の繰り返しスケジュールが入力元のICSファイルに含まれない場合は、復元に失敗します。

具体例を挙げると2025年11月中の繰り返しスケジュールの一部を上書きして12月に変更した場合、ICSファイルに12月の日付のデータに加えて11月分の参照元の繰り返しスケジュールが含まれる必要があります。

7.4 その他(セキュリティ上の留意点)

Outlook(Web)で指摘したようにスケジュール機能でTeams会議を主催すると、メモ欄(DESCRIPTION)にTeams会議のパスワードが記載されます。

加えて、Outlook(classic)では更に細かい情報が多数入っています。Teams会議の参加者のメールアドレス。ICSのヘッダ部分のX-OWNERに作成者のメールアドレス。

そのため、うかつにICSファイルを公開すると、Teams会議のパスワードに加えて、参加者などのメールアドレスがすべて漏洩するため、セキュリティ上の問題が発生します。

その他の点として、DESCRIPTIONと同じ内容がHTML形式でX-ALT-DESCに入っています。

8. Garoonの出力するICSの形式

8.1 TimeZone

TimeZoneは定義されてません。Floating Timeになっています。

8.2 繰返しスケジュール(RRULE)のEXDATE

繰り返すスケジュールの除外日を指定するEXDATEという命令があります。

Outlook(Web)およびOutlook(classic)が生成するEXDATEは日付情報のみの場合は「VALUE=DATE」という属性がつきますが、

ICSファイル抜粋
  EXDATE;VALUE=DATE:20251128

Garoonの場合は以下のようにこの属性がつきません。

ICSファイル抜粋
  EXDATE:20251128

この形式だと本ソフトウエアが利用しているライブラリvobject-0.99が例外を送出します。例外発生関数。

 vobject.readOne()

そのため、本ソフトウエアでは「VALUE=DATE」という属性を挿入する処理を行っています。関数PreSetup.bugfix_exdate_format()参照ください。

8.3 行分割処理は行われない。

DESCRIPTIONやSUMMARYの行の分割処理は無い模様です。常に一行となってます。

例えばOutlook(classic)やOutlook(web)では長い行は次のような分割処理があります。

ICSファイル抜粋Outlook(Web)
DESCRIPTION:1234(業務番号)\n\n業務内容。この枠内は可能な
 らプレインテキストで入れてください。\n

Garoonは常に一行になっています。

ICSファイル抜粋Garoon
DESCRIPTION:1234(業務番号)\n\n業務内容。この枠内は可能ならプレインテキストで入れてください。\n

8.4 繰返しスケジュール(RRULE)の上書きスケジュール(RECURRENCE-ID)

上書きスケジュール(RECURRENCE-ID)は生成されません。別のスケジュールとなります。

8.5 (Bug) 記号のクオート処理

RFC5545の定義によると、DESCRIPTIONやSUMMARYの行に記号「,」や「;」を用いる時はクオート処理を行なう必要があり、「,」や「;」とする必要があります。しかしGaroonではこの処理が行われません。そのため、ics2convcsvが生成するCSVで文章が途中で途切れる事があります。(Ref: RFC5545, 「3.1.11.Text」)

9. ICSの要素とCSVの要素の対応

9.1. CSVのSimple形式

以下の対応でICSからCSVへの変換を行う。

ICSの出力値→CSVへの変換値
  DTSTART → "DTSTART:DAY","DTSTART:TIME"
  DTEND  → "DTEND:DAY","DTEND:TIME"
  SUMMARY → "SUMMARY"
  DESCRIPTION → "DESCRIPTION"
  X-MICROSOFT-CDO-BUSYSTATUS → "X-MICROSOFT-CDO-BUSYSTATUS"
  CATEGORIES → "CATEGORIES"

日付はISO8601(extended)形式になります。 2025-12-31, 12:31というような形になります。
X-MICROSOFT-CDO-BUSYSTATUSは在籍情報になります。Outlook(new)とOutlook(classic)が生成したICSファイルにはこのデータが含まれます。詳細は 13.2「在籍情報」参照ください。それ以外では"(N/A)"となります。

CATEGORIES は分類(色)です。Outlook(classic)が生成したICSファイルにはこのデータが含まれます。詳細は 13.1「 分類(色)」参照ください。それ以外では"(N/A)"となります。

9.2. CSVのGaroon形式

以下の対応でICSからCSVへの変換を行う。

ICSの出力値→CSVへの変換値
  DTSTART → "開始日","開始時刻"
  DTEND  → "終了日","終了時刻"
  SUMMARY → "予定"および"予定詳細"
  DESCRIPTION → "メモ"

日付は日本式の年月日の順序でスラッシュで区切った形式になります。 2025/12/31, 12:31というような形になります。

Garoonはタイトルは二種類の入力があり、

  タイトルの選択肢:'出張', '往訪', '来訪', '会議', '休み'
  タイトルの本文: 「東京特許許可局」

などの入力がある。CSVではそれぞれ"予定","予定詳細"と出力される。

ICSのSUMMARYにはこのような区別はないが、Garoon形式のCSVに変換するときにSUMMARYにコロン「:」があった場合は分割処理を行っている。

ICS
SUMMARY →"出張:東京特許許可局"
CSV
予定  → "出張"
予定詳細 → "東京特許許可局"

分割できなかった場合は"予定"には空文字が挿入されます。"(N/A)"は挿入されません。

9.3 その他CSV形式

容易に拡張しやすいよう設計したつもりです。概ね以下の手順で追加できるかと思います。

  • Enum型のAllDayFormatに名称追加

  • PreSetup.set_format()でCSVの要素の設定。
     冒頭のif/elifで文字コード、終日日程のフォーマット、日付のフォーマットを指定。後半のif/elifでCSVの要素のヘッダや順番などを設定。

CSVの順番の入れ替えなどでしたら上記の修正のみで対応可能です。既存で定義されてない要素を追加する場合は

  • Main.ics_parts_to_csv_buffer()で追加した要素のコードを追加。
     

という流れで対応可能かと思います。

10. icsconvcsvが出力する文字コード

10.1 文字コード

ICSの文字コードはUTF-8と決まってます。Garoonの出力するCSVの文字コードはShiftJISです。icsconvcsvはCSVの書式としてGaroonを指定した場合ShiftJISを出力します。

ただし元のICSの文字コードがUTF-8のため、一部はShiftJISに変換ができません。変換できなかった文字はXMLのエスケープ形式 "&#xxx" で出力します。下記のPythonのマニュアルで「xmlcharrefreplace」という名称で説明がなされている方式で出力します。

icsconvcsvにオプション「-Cutf_8」を指定するとUTF-8で出力します。

オプション「-Cutf_8_sig」を使うとWindows環境で使われるBOM(byte order mark)を挿入します。Linux/macOS環境では誤動作する可能性あります。

10.2 改行の扱い

icsconvcsvが出力するCSVの改行コードはGaroonと同じ仕様になってます。原則の改行コードは(CR+LF)です。しかし、ダブルクオート内部の改行はLFになっています。これが標準的な改行なのか、そうでないのかはよくわかりません。

11 ICSファイルでのスケジュール移行時の注意点。

11.1 終日スケジュールの問題

Garoonに終日スケジュール(時刻なし)を入力し、ICSで出力し、Outlook(Web)に読み込ませると、終日スケジュール(時刻あり)に変換されます。

前提として、GaroonはTimeZoneが無いFloatingTimeでOutlook(Web)はTimeZoneがあります。

FloatingTimeのICSファイルをOutlook(Web)に読み込ませると、終日スケジュール(時刻あり)に変更されるようです。

※業務記録の視点から見ると注意が必要になります。24時間連続勤務との区別が出来なくなります。

11.2 終了時刻のみ終日のスケジュール

Garoonでは始点時刻のみ指定で終了時刻なしが設定可能。たとえばGaroonに下記のスケジュールを入力すると、

  • 開始:10月10日 13:44
  • 終了:10月10日 (時刻指定なし)

ICSに出力すると開始時刻と終了時刻が同じになります。

ICSファイル抜粋
  DTSTART: 20251010T134400
  DTEND:   20251010T134400

11.3 繰返し日程の分割

Garoonは期間指定して、ICSファイルへの出力が可能です。

繰返し日程(RRULE)の繰返し期間を分割するような形でICSファイルを出力し、Outlook(Web)に読み込ませると、正常にOutlook(web)に登録されません。

例: Garoonに2026年10月から2027年2月の毎週月曜日の繰返しスケジュールを入力します。そしてICSファイルを出力するときに、2026年分と2027年分に分割して出力します。すると、以下のようなファイルが生成されます。

2026年分はUNTILの終端日が正しくありません。

2026年(抜粋)/UNTILの終端日が正しくない
BEGIN:VEVENT
UID:1234567890ABCDEF
DTSTART:20261005T085000
DTEND:20261005T102000
RRULE:FREQ=WEEKLY;BYDAY=MO;UNTIL=20270222T102000;WKST=SU
SUMMARY:学生実験(テーマXY)
DESCRIPTION:
END:VEVENT

2027年分は各種日時の範囲が正しいです。

2027年(抜粋)
BEGIN:VEVENT
UID:1234567890ABCDEF
DTSTART:20270104T085000
DTEND:20270104T102000
RRULE:FREQ=WEEKLY;BYDAY=MO;UNTIL=20270222T102000;WKST=SU
SUMMARY:学生実験(テーマXY)
DESCRIPTION:
END:VEVENT

上記のICSファイルを用いて、Outlook(Web)に2026年分のICSを読み込ませると、2026年10月から2027年2月の毎週月曜日の繰返しスケジュールが登録されます。UNTILの指定が2027年2月22日になってるため、Outlook(web)として正常な挙動です。次に2026年分のICSを読み込ませると2026年10月から12月のスケジュールが消去されてしまいます。どうやらUIDが同じスケジュールを読み込むと、古い方は消去されてしまうようです。

そのため、繰返しスケジュールは極力分割されないような注意が必要になります。

12. 補助プログラム

CSVをdiff等で比較する場合、CSVにダブルクオートで囲まれた複数行の文字列があると比較しにくいです。下記のプログラムで複数行の文字列の2行目以降を除去できます。またCSVの日付順のソートや、未定義を示す"(N/A)"を空文字に置換するなども行っています。利用法などはプログラムのソースのコメント参照ください。

文字コードはUTF-8を想定しているため、ShiftJISのCSVの場合は 「nkf -w」 等でUTF-8に変換ください。

  • normal_csv.py

13.その他雑多な話

13.1 分類(色)

Outlook(Web)およびOutlook(classic)では、スケジュールに分類(色)の指定が
可能です。この情報はOutlook(classic)が生成するICSでは下記のような形で
出力されます。しかし、Outlook(Web)ではこの情報は出力されません。

ICSファイル抜粋
CATEGORIES:青の分類

上記は日本語環境での出力になります。英語環境のOutlookでは英語で出力されます。

13.2 在室情報

在室情報のステータスはOutlook(new)とOutlook(classic)双方で出力されます。

- 仮の予定
X-MICROSOFT-CDO-BUSYSTATUS:TENTATIVE

- 他の場所で作業中
X-MICROSOFT-CDO-BUSYSTATUS:WORKINGELSEWHERE

- 空き時間
X-MICROSOFT-CDO-BUSYSTATUS:FREE

- 外出中
X-MICROSOFT-CDO-BUSYSTATUS:OOF

- 予定あり(default)
X-MICROSOFT-CDO-BUSYSTATUS:BUSY

以上です。

脚注

  1. Emacsでは改行が混ざったファイル、例えば CR+LFとLFが混ざった場合、改行はLFと扱われCRがEmacs上に表示される。Emacs上ではCRは「^M」と表示される。Garoonが出力したファイルは本文中の改行はCR+LFで、ダブルクオート内部の改行はLFになってる。そのため、Emacsで閲覧すると本文中のほとんどの行にCR「^M」が表示される。ダブルクオート内部のみCR「^M」は表示されない。

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?