カレンダーのデータをエクスポートする際の”終日”の取り扱い

カレンダーのデータをエクスポートする際の”終日”の取り扱い

- Tatsuya Shirai の投稿
返信数: 9

 Moodleのカレンダーの機能が充実してきましたので,本格的に使ってみようかと思い始めました.

 近頃,Googleカレンダーを少しずつ使い始めました.iPod touchのカレンダーとの同期もなんとかできるようになってきました.さて,URIでMoodleのカレンダーをGoogleカレンダーに読み込むことができて喜んでいたのも束の間.いわゆる”終日”のイベントの問題に気付きました.

 Moodleのカレンダーには”終日”という概念がありません.2010/4/8 00:00 のような開始日時で登録したイベントは,Googleカレンダー側で見ると,まさに真夜中から1時間のイベントになっています.”編集”で”終日”のチェックボックスをOnにすれば一つ上の行に移動します.

 皆さん,この問題についてどのように対処しているのでしょうか?


 対処方法として,iCalendar形式でのデータ出力を操作する手が考えられます.

 たとえば1日のみのイベントの場合,開始時刻が00:00で期間が無指定の場合はGoogleカレンダーが”終日”と判断するようなデータ形式で出力する.複数日に亘るイベントの場合は開始時刻が00:00かつ終了時刻が23:55ならば”終日”とする,です.
 この方法ですと,本当に00:00から始まるイベントが”終日”扱いになるという問題がありますが...

Tatsuya Shirai への返信

Re: カレンダーのデータをエクスポートする際の”終日”の取り扱い

- Tatsuya Shirai の投稿

 とりあえず分かってきたこと.

 MoodleではiCalendar形式のデータ出力にbennuというプロジェクトのライブラリを用いていること.

 そのパッケージ内のexample.phpにあるように,1日単位の終日イベントは,

// Start-end date
$ev->add_property('class', 'PRIVATE');
$ev->add_property('dtstart', '20050623', array('value' => 'DATE'));
$ev->add_property('dtend', '20050624', array('value' => 'DATE'));

$ev->add_property('dtstamp', '20050622T235601Z');

このように記述することで,

DTSTART;VALUE=DATE:20100405
DTEND;VALUE=DATE:20100406

このような形式の(値は別のicsファイルからコピーしたのでexample.phpとは異なります)ように,DTSTARTは開始日,DTENDは翌日に設定される.なお,時間指定された単一日のイベントは,

DTSTART:20100409T030000Z
DTEND:20100409T040000Z

このように明らかに異なる形式になる.VALUE=DATEが終日のキーワードと見た.そしてそれを実現するには,array('value' => 'DATE').あとは試しに実装して見ます.

Tatsuya Shirai への返信

Re: カレンダーのデータをエクスポートする際の”終日”の取り扱い

- Tatsuya Shirai の投稿

 ちなみにMoodleのカレンダーのエクスポートはmoodle/calendar/export_execute.php内に記述されている.日時形式の出力にはbennuのクラスが使用されている.bennuのクラスはmoodle/lib/bennuフォルダにある.

    $ev->add_property('dtstart', Bennu::timestamp_to_datetime($event->timestart)); // when event starts
    $ev->add_property('dtend', Bennu::timestamp_to_datetime($event->timestart + $event->timeduration));

example.phpとは異なり,timestamp_to_datetime()というメソッドを利用する.これはmoodle/lib/bennu/bennu/bennu.class.php内に宣言されており,以下の通りのシンプルな関数.

    function timestamp_to_datetime($t = NULL) {
        if($t === NULL) {
            $t = time();
        }
        return gmstrftime('%Y%m%dT%H%M%SZ', $t);
    }

日付の部分を作るのであれば,gmstrftime('%Y%m%d')だけで良い,と.

Tatsuya Shirai への返信

Re: カレンダーのデータをエクスポートする際の”終日”の取り扱い

- Tatsuya Shirai の投稿
 とりあえず00:00から開始する期間なし(durationtime == 0)はGoogleカレンダーで'終日'と認識させることに成功しました.あとは複数日に亘るイベントですね.
Tatsuya Shirai への返信

Re: カレンダーのデータをエクスポートする際の”終日”の取り扱い

- Tatsuya Shirai の投稿

 どちらもうまく行ったような感じです.とりあえずMoodleのカレンダーに"終日イベント"のつもりで入力した一日のイベントと,”終日のイベント”のつもりで入力した複数日に亘るイベントが入力された状態で,iCalendar形式でエクスポートし,それをGoogleカレンダーにインポートしたら"終日"扱いでインポートされました.

 ちょっとイベントの入力方法に制約があります(そのルールに従えばOKという意味での制約).

 単一日の終日イベントは,開始日の時刻を00:00に設定し,期間は”なし”にチェック(ラジオボックス).
 複数日の終日イベントは,開始日の時刻を00:00に設定し,終了日の時刻を23:55に設定する.

 昨日,ちょっと気にしていた本当に0時から始まるイベントは,開始日の時刻を00:00に合わせた上で,期間を”なし”ではなく終了日あるいは期間(分)を設定して貰えば良いだけのことでした.だって,たとえば8時から始まるイベントであってもGoogleカレンダーにインポートする時には08:00から09:00の1時間のイベントとして読み込まれるのですから,0時からのイベントを00:00から01:00と入力して貰うのは異常では無いですよね?

 修正点は以下の通りです.効率は悪いですが,とりあえず分かり易さ重視のコードということで.moodle/calendar/export_execute.phpです.まだデバッグは不十分かも知れませんので,多少のリスクは覚悟して下さい.でも,これで既にMoodleのカレンダーをGoogleカレンダーに同期している方,あるいはこれから検討する方にとっては大きな前進だと思います.

 なお,複数日に亘るイベントの終了日の時刻を23:55に合わせるのは面倒くさい,という方もいるかも知れませんね.昨日公開したfs_moodle4.03.00では期間の終了日の時刻の初期値を23:55に設定する改良が加えられています.楽です.とっても楽です.なお,以下の修正されたコードは次回公開予定のfs_moodle4.04.00に搭載の予定です.


     $ev->add_property('description', $event->description);
    $ev->add_property('class', 'PUBLIC'); // PUBLIC / PRIVATE / CONFIDENTIAL
    $ev->add_property('last-modified', Bennu::timestamp_to_datetime($event->timemodified));
    $ev->add_property('dtstamp', Bennu::timestamp_to_datetime()); // now
// (Shirai): ここからコメントアウト
//
  $ev->add_property('dtstart', Bennu::timestamp_to_datetime($event->timestart)); // when event starts
//  if ($event->timeduration > 0) {
//      //dtend is better than duration, because it works in Microsoft Outlook and works better in Korganizer
//      $ev->add_property('dtend', Bennu::timestamp_to_datetime($event->timestart + $event->timeduration));
//  }
// (Shirai): ここまでコメントアウト
// (Shirai): ここから追加
    $startdate = usergetdate($event->timestart);
    $allday = 0;  // 0: not all day, 1: all day(one day) 2: all day(some days)
    if (($startdate['hours'] == '00') and ($startdate['minutes'] == '00')) {
        if ($event->timeduration > 0) {
            $enddate = usergetdate($event->timestart + $event->timeduration);
            if (($enddate['hours'] == '23') and ($enddate['minutes'] == '55')) $allday = 2;
        } else $allday = 1;
    }
    if ($allday == 0) {
        $ev->add_property('dtstart', Bennu::timestamp_to_datetime($event->timestart)); // when event starts
    } else {
        $ev->add_property('dtstart', $startdate['year'].$startdate['mon'].$startdate['mday'], array('value' => 'DATE'));
    }
    if ($event->timeduration > 0) {
        //dtend is better than duration, because it works in Microsoft Outlook and works better in Korganizer
        $timeend = $event->timestart + $event->timeduration;
        if ($allday == 1) {
            $enddate = usergetdate($event->timestart + 60*60*24);
            $ev->add_property('dtend', $enddate['year'].$enddate['mon'].$enddate['mday'], array('value' => 'DATE'));
        } else if ($allday == 2) {
            $enddate = usergetdate($timeend + 60*5);
            $ev->add_property('dtend', $enddate['year'].$enddate['mon'].$enddate['mday'], array('value' => 'DATE'));
        } else {
            $ev->add_property('dtend', Bennu::timestamp_to_datetime($timeend));
        }
    }
// (Shirai): ここまで追加
    if ($event->courseid != 0) {
        $ev->add_property('categories', $courses[$event->courseid]->shortname);
    }
    $ical->add_component($ev);
}

Tatsuya Shirai への返信

Re: カレンダーのデータをエクスポートする際の”終日”の取り扱い

- Tatsuya Shirai の投稿

URIでのエクスポート(Googleカレンダー側ではインポート)も望みどおりに機能しました.

カラフル化とも合わせて,これでMoodleのカレンダー機能は十分に実用的になったでしょう.

欲を言えば,開始時刻が近づいたら通知が欲しいところですが...それはGoogleカレンダー側にお願いできないのかな?

添付 GoogleCalendar.jpg
Tatsuya Shirai への返信

Re: カレンダーのデータをエクスポートする際の”終日”の取り扱い

- Tatsuya Shirai の投稿

 MoodleのカレンダーのiCal出力(ファイル出力,URI出力)を”終日イベント(all day)”に対応させるパッチです.修正は,moodle/calendar/event.php(2箇所:追加)とexport_execute.php(1箇所:修正)の二つのファイルのみです.

 ポイントはイベントの時刻入力(duration)です.

 終日のイベントには二種類あります.単一日のイベントと複数日に亘るイベントです.

 単一日の場合,いままでは”日付”を設定し,時刻は00:00,期間を”期間なし”に設定していたと思います.これをiCalエクスポートすると00:00から01:00までの1時間のイベントとして出力されていました.これを開始日時はいままで通りにイベントの日付と開始時刻を00:00lに設定し,期間を同日の23:55に設定して下さい.これで単一日の終日イベントとして出力されます.

例) 会議
   日付: [2010] [4月] [22] 時間 [00] [00]
   期間: (*) 期間なし
   を
   日付: [2010] [4月] [22] 時刻 [00] [00]
   期間: (*) 終了日 [4月] [22] 時刻 [23] [55]

 複数日の場合,いままでは開始日時は単一日同様にイベントの日付と開始時刻00:00で設定し,期間を”終了日”の日付を設定し,時刻をデフォルトの00:00に設定すると....1日短いイベントになってしまうので,例えば23:55などの時刻に設定していたと思います.そう,このように設定すれば指定した期間の終日イベントとして出力されます.

例) 定期テスト
   日付: [2010] [4月] [22] 時間 [00] [00]
   期間: (*) 終了日 [4月] [29] 時刻 [23] [55]
 このままでOK

 標準のMoodleでは期間:終了日の時刻は[00] [00]です.これを[23] [55]に変更することで,入力を楽にしています.どのみち終了時刻が 00:00 なんて夜更かしなイベントは滅多にありませんので,大抵の人は何らかの時刻に設定し直すので手間が増える訳ではありませんね.(分の55は億劫?)

 パッチおよびオリジナル(original_moodle)と修正版(ical_moodle)のcalendar/event.phpとcalendar/export_execute.phpを貼付します.お手元のMoodleサイトで正常に動作するかどうか確認して頂けないでしょうか? もし正常に動作するという報告が得られましたら,Moodle TrackerとUsing moodleに報告します.
 なお,対象となるカレンダーアプリケーションとして,Googleカレンダーでのみ動作を確認していますので,他のiCal入力が可能なアプリケーションでの動作報告あるいは不具合報告もお待ちしております.

Tatsuya Shirai への返信

Re: カレンダーのデータをエクスポートする際の”終日”の取り扱い

- Tatsuya Shirai の投稿

本パッチをMDL-22378およびUsing moodleに報告しました.

実際には00:00から23:55といった指定の仕方ではなく,[期間]に”終日”というチェックボックスを追加してくれるのが一番使い易いのですけれども,とりあえず提案した方法で.
(終日をチェックすると,日時の時刻のプルダウンが消える)

先日公開したfs_moodle4.04.00にはこの修正を適用済みです.

Tatsuya Shirai への返信

Re: カレンダーのデータをエクスポートする際の”終日”の取り扱い

- Tatsuya Shirai の投稿

これもリバイバルですが,Moodle2.6に対応させました.

http://www.suzuka-ct.ac.jp/mech/moodle2/mod/wiki/view.php?pageid=2946

http://www.suzuka-ct.ac.jp/mech/moodle2/mod/forum/discuss.php?d=3993

ちょっと面白い(?)のは,Moodle2で,イベントの「期間」の終了日時の初期値が入力している「いま」である点.バグというほどのことではないですが,未来の予定を入力している時でも「いま」が終了日時の初期値というのはどうなんでしょうね.せめてその開始日時にするべきでしょう.

という訳で,以上の(Shirai022)を適用することで二つの問題が同時に片付きます.追加は1行のみ.これはTrackerに報告した方が良さそうです.

Tatsuya Shirai への返信

Re: カレンダーのデータをエクスポートする際の”終日”の取り扱い

- Tatsuya Shirai の投稿

https://tracker.moodle.org/browse/MDL-45306

Trackerに投稿しました.意図が通じると良いのですが.本当はこの改善,

https://moodle.org/mod/forum/discuss.php?d=75286

↑こちらの機能(Moodle1.9からのリバイバルなので下の方にスクロールして下さい)と組み合わせた時に無双になるのです.セットでご利用下さい.本家にはとりあえずこちらの問題だけTrackerで提案しましたが.