Logical Rabbit.

さくらのVPS

ics

ICS形式のカレンダーデータをJavaScriptでいじるときのメモ。

…これ、結局「Ical」と「Webcal」って何がどう違うんでしょうね…。何度調べてもよく分からん。ともあれ、扱うデータは「*.ics」なので「ICS形式」と呼んでおけば間違いなかろう、と。

某所で提案しようと下調べしていたのだけど、概ねめどが経ったところで募集状況を見に行くと既に終わっていたいつものパターンでしたとさ。まあフルタイム職が終盤に差し掛かってちょいと忙しかったしね…。というところで調べた成果の記録と供養など。

実行環境と使用ライブラリ

実行環境としてはNW.jsを使用して、Node.jsで実装しています。NW.jsはJavaScriptとHTMLとCSSでお手軽に書けるうえ、JavaScriptなのでWebアクセス系は楽々扱え、しかも実行バイナリはWindows、Mac OS X、Linuxと幅広く対応できるのがとても良いと思います。

コンパイラ系言語を使わなくて良いというより、クロスプラットフォームが簡単に実現できる、モノによってはWebアプリケーション化まで視野に入れることができるという点が気に入っています。

でも最近Go言語も気になっているのだけど、あっちとの比較はどんなもんだろう…?

もとい。

使用ライブラリは icalパッケージ。加えて、画面制御系としてjQueryも使います。

実装

icalパッケージでWeb上のICS形式読み取りとオブジェクト化は容易に実現できます。

問題はICSから読み取ったイベント情報が「繰り返し」だった場合。

例えばGoogleカレンダーで「2016年1月1日から12月30日まで、毎週金曜日に「今日は金曜日!」とセットした場合、ICSデータには「毎週金曜日に「今日は金曜日!」と追加されるのではなく、開始が1月1日、終了が12月30日、かつ「週ごとの繰り返しで金曜日のみ有効」というルールが付与されたイベントが1件だけ追加されます。

このようなイベントをicalパッケージで処理した場合、rruleプロパティ内に繰り返し情報が格納されます。さらに rrule.all() とすると具体的な日付に展開したArrayが返ってきますので、これを使用することで他のイベントと同じように日付として扱うことが可能になります。

(以下のCALENDAR_URLで指定しているカレンダーは、非公開(ICSのURLを知っている人のみ参照可)として実際に置いてあります。

var ICal = require( 'ical' );

var CALENDAR_URL =
  'https://calendar.google.com/calendar/ical/u78uo80t8b784ojbbf265tpkv4%40group.calendar.google.com/private-8d07e17f65ddac761f8cf190f3e69fee/basic.ics';

ICal.fromURL( CALENDAR_URL, {}, function( error, data ) {
  if( error ) {
    console.log( error );
  }
  else {
    var keys = Object.keys( data ).sort();
    keys.forEach( function( key ) {
      var friday = data[key];
      if( friday.rrule ) {
        friday.rrule.all().forEach( function( realDay ) {
          console.log( [
            friday.summary, realDay.toLocaleDateString()
          ].join( ' ' ) );
        } );
      }
    } );
  }
} );

なお、rruleがあるデータの場合なぜかstart, endにはtoLocaleDateString()等が使用可能なデータが入っていませんので注意。