どちらもうまく行ったような感じです.とりあえず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);
}