在此奉上簡單的 ics 匯出實作程式
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
|
<?php
namespace Hdsbook\ICS; // 這裡請替換掉你自己要用的 namespace
class ICS
{
public $data = "";
public $start =
"BEGIN:VCALENDAR\n" .
"PRODID:-//Hdsbook Corporation//Test System//EN\n" . // 此行中間內容可自行替換,這行不加也行
"VERSION:2.0\n" .
"CALSCALE:GREGORIAN\n" . // 曆法:陽曆
"METHOD:REQUEST\n"; // 動作:新增、修改
public $timezone =
"BEGIN:VTIMEZONE\n\n" .
"TZID:Asia/Taipei\n\n" .
"X-LIC-LOCATION:Asia/Taipei\n\n" .
"BEGIN:STANDARD\n\n" .
"TZOFFSETFROM:+0800\n\n" .
"TZOFFSETTO:+0800\n\n" .
"TZNAME:CST\n\n" .
"DTSTART:19700101T000000\n\n" .
"END:STANDARD\n\n" .
"END:VTIMEZONE\n" ;
public $end = "END:VCALENDAR\n";
public function __construct()
{
}
/**
* add event
*
* @param string $start
* @param string $end
* @param string $name
* @param string $description
* @param string $location
* @param string $uid 設定該活動的唯一識別ID,用於針對該活動之後進行修改
* @return string
*/
public function add(
$start,
$end,
$name,
$description,
$location,
$uid = null
) {
// 公私 (CLASS): PUBLIC / PRIVATE
// 日期 (DTSTART/DTEND)
// 地點 (LOCATION)
$this->data .=
"BEGIN:VEVENT\n" .
"DTSTART;TZID=Asia/Taipei:" . date("Ymd\THis\Z", strtotime($start)) . "\n" .
"DTEND;TZID=Asia/Taipei:" . date("Ymd\THis\Z", strtotime($end)) . "\n" .
"LOCATION:" . $location . "\n" .
"TRANSP: OPAQUE\n" .
"SEQUENCE:0\n" .
"UID:" . ($uid ?? '') . "\n" .
"DTSTAMP:" . date("Ymd\THis\Z") . "\n" .
"SUMMARY:" . $name . "\n" .
"DESCRIPTION:" . $description . "\n" .
"PRIORITY:1\n" .
"CLASS:PUBLIC\n" .
// "BEGIN:VALARM\n" .
// "TRIGGER:-PT1D\n" .
// "ACTION:DISPLAY\n" .
// "DESCRIPTION:Reminder\n" .
// "END:VALARM\n" .
"END:VEVENT\n";
}
/**
* 將檔案存到 server
*
* @param string $file_path
*/
public function save($file_path)
{
file_put_contents($file_path, $this->getData());
}
/**
* 下載檔案
*
* @param string $file_name 檔案名稱,不用含 .ics 的副檔名
*/
public function download($file_name)
{
header("Content-type:text/calendar");
header('Content-Disposition: attachment; filename="' . $file_name . '.ics"');
Header('Content-Length: '.strlen($this->getData()));
Header('Connection: close');
echo $this->getData();
}
/**
* 取得檔案內容
*
* @return string
*/
public function getData()
{
return $this->start . $this->timezone . $this->data . $this->end;
}
}
|
使用方式
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
|
<?php
use Hdsbook\ICS\ICS;
// ...
$ics = new ICS();
foreach ($events as $evt) {
$ics->add(
$evt['start'],
$evt['end'],
$evt['title'],
$evt['description'],
$evt['location'],
$evt['uid']
);
}
$ics->download("行事歷匯出檔名");
|
提醒設定
1
2
3
4
5
6
7
8
9
10
11
|
// 10080 分鐘前提醒 (一周前提醒)
BEGIN:VALARM
TRIGGER:-PT10080M
ACTION:DISPLAY
DESCRIPTION:Reminder
END:VALARM
// 一天前提醒
TRIGGER:-PT1D
// 若拿掉這幾行(BEGIN:VALARM ~ END:VALARM),則匯入時會預先抓取google帳號所設定的預設提醒時
|
疑難排解
解決匯入後時間往後延了八小時的問題 (原因與台灣時區有關係)
1
2
3
4
5
6
7
|
// 一般教學文件只會寫
DTSTART: . date("Ymd\\THis\\Z", strtotime($start)) . "\\n" .
DTEND: . date("Ymd\\THis\\Z", strtotime($end)) . "\\n" .
// 改為
DTSTART;TZID=Asia/Taipei: . date("Ymd\\THis\\Z", strtotime($start)) . "\\n" .
DTEND;TZID=Asia/Taipei: . date("Ymd\\THis\\Z", strtotime($end)) . "\\n" .
|
參考
iCal Applicatoin - iCal Java API 研究與教學 - Soul & Shell Blog
MRBS 會議室預約管理系統 之 iCalendar檔案 - iT 邦幫忙::一起幫忙解決難題,拯救 IT 人的一天
ICS timezone not working