MobileCal.appの使うデータベースを探検してみた

iPod touchのカレンダー(MobileCal.app)のデータをGoogleCalendarと同期させたいなと思ったので、中身を探ってみた。*1ソフトを組める段階にはならなかったが、いろいろわかったので、メモ。

ぐぐってみるとメモ帳やカレンダーはsqlite3を使っているらしく、sqlite3コマンドを使えばデータベースの中身を見られるらしい。というわけでsqlite3を入れて、探検してみた。

参考 > http://eternalbeta.openprocess.jp/archives/88

# sqlite3 /private/var/mobile/Library/Calendar/Calendar.sqlitedb
SQLite version 3.4.1
Enter ".help" for instructions
sqlite> .tables
Alarm                      OccurrenceCache
AlarmChanges               OccurrenceCacheDays
Calendar                   Recurrence
CalendarChanges            RecurrenceChanges
Event                      Task
EventChanges               TaskChanges
EventExceptionDate         _SqliteDatabaseProperties

予定が作成されるEventテーブルの中身はこんなかんじ。

sqlite> select * from Event where description like "%Google%";
ROWID|summary|location|description|start_date|start_tz|end_date|all_day|calendar_id|orig_event_id|orig_start_date
2|てすてす|todai|GoogleCalendar|227397600|Asia/Tokyo|227401200|0|1|0|0

ここでstart_date, end_dateが変な数字として登録されている。数字の羅列だからunixtimeかと思ったけどそうでもなさそう。

で、とある日時から3600や86400をかけたり引いたりして調べたら2001年1月1日0時0分0秒を基準にしている秒数だった。しかもJST(日本標準時)だとさらに9時間ずれるので、9*3600を引いているのだった。

こんなのをいちいち手で計算するのが面倒なのでdateコマンドをPerlから呼び出して計算するスクリプトを書いた。Perlを選んだのはシェルスクリプトは数字の計算に向かなそうだったので。

#!/usr/bin/perl -w
# Calculate seconds of MobileCal.app

if (!$ARGV[0]) {
  exit;
}

$str = 'date --date="2008'. $ARGV[0]. '" +"%s"';
$target = `$str`;
$offset = `date --date='20010101 00:00' +"%s"`;

# For MobileCal.app seconds must be subbed by 3600*9 (Tokyo/Japan)
print $target - $offset - 3600*9;

print "\n";

シェルの出力を取り出すバッククォートを使ってみました。きっとPerlのdate関数でもいけるんだろうな。

使い方はこんなの。2008年の時間しかだせません。

/home/tsuzuki% perl date.pl "0404 10:00"
228963600

はい、どうでもいいですね。

今日はこんなスクリプトを使ってsqliteからMobileCal.appの予定を追加することに成功しました、という話です。

ちなみにMobileCal.appのデータベースに予定を追加したときは、追加したことを表すテーブル(EventChanges)や、予定のサマリーを入れているテーブル(OccurrenceCache, OccurrenceCacheDays)も更新しないといけないようです。Eventテーブルだけを更新すると、MobileCal.appの「月」タブでは表示されている予定が「リスト」タブでは表示されない、などといったことが起こります。逆に言えばsqliteを使ってデータベース内の必要なテーブルを変更してしまえば、カレンダーのデータをいじくることができます。

*1:SyncML2iPhone.comというそれっぽいソフトがあったのだが、うまく動かないので自分で作ってみようかなと思ったり。