├── MyCal.ics ├── README.md ├── class.iCalReader.php └── example.php /MyCal.ics: -------------------------------------------------------------------------------- 1 | BEGIN:VCALENDAR 2 | PRODID:-//Google Inc//Google Calendar 70.9054//EN 3 | VERSION:2.0 4 | CALSCALE:GREGORIAN 5 | METHOD:PUBLISH 6 | X-WR-CALNAME:Testkalender 7 | X-WR-TIMEZONE:Europe/Berlin 8 | X-WR-CALDESC:Nur zum testen vom Google Kalender 9 | BEGIN:VEVENT 10 | DTSTART:20110105T090000Z 11 | DTEND:20110107T173000Z 12 | DTSTAMP:20110121T195741Z 13 | UID:15lc1nvupht8dtfiptenljoiv4@google.com 14 | CREATED:20110121T195616Z 15 | DESCRIPTION:This is a short description\nwith a new line. Some "special" 's 16 | igns' may be \, too. 17 | LAST-MODIFIED:20110121T195729Z 18 | LOCATION:Kansas 19 | SEQUENCE:2 20 | STATUS:CONFIRMED 21 | SUMMARY:My Holidays 22 | TRANSP:TRANSPARENT 23 | END:VEVENT 24 | BEGIN:VEVENT 25 | DTSTART;VALUE=DATE:20110112 26 | DTEND;VALUE=DATE:20110116 27 | DTSTAMP:20110121T195741Z 28 | UID:1koigufm110c5hnq6ln57murd4@google.com 29 | CREATED:20110119T142901Z 30 | DESCRIPTION:Project xyz Review Meeting Minutes\n 31 | Agenda\n1. Review of project version 1.0 requirements.\n2. 32 | Definition 33 | of project processes.\n3. Review of project schedule.\n 34 | Participants: John Smith, Jane Doe, Jim Dandy\n-It was 35 | decided that the requirements need to be signed off by 36 | product marketing.\n-Project processes were accepted.\n 37 | -Project schedule needs to account for scheduled holidays 38 | and employee vacation time. Check with HR for specific 39 | dates.\n-New schedule will be distributed by Friday.\n- 40 | Next weeks meeting is cancelled. No meeting until 3/23. 41 | LAST-MODIFIED:20110119T152216Z 42 | LOCATION: 43 | SEQUENCE:2 44 | STATUS:CONFIRMED 45 | SUMMARY:test 11 46 | TRANSP:TRANSPARENT 47 | END:VEVENT 48 | BEGIN:VEVENT 49 | DTSTART;VALUE=DATE:20110118 50 | DTEND;VALUE=DATE:20110120 51 | DTSTAMP:20110121T195741Z 52 | UID:4dnsuc3nknin15kv25cn7ridss@google.com 53 | CREATED:20110119T142059Z 54 | DESCRIPTION: 55 | LAST-MODIFIED:20110119T142106Z 56 | LOCATION: 57 | SEQUENCE:0 58 | STATUS:CONFIRMED 59 | SUMMARY:test 9 60 | TRANSP:TRANSPARENT 61 | END:VEVENT 62 | BEGIN:VEVENT 63 | DTSTART;VALUE=DATE:20110117 64 | DTEND;VALUE=DATE:20110122 65 | DTSTAMP:20110121T195741Z 66 | UID:h6f7sdjbpt47v3dkral8lnsgcc@google.com 67 | CREATED:20110119T142040Z 68 | DESCRIPTION: 69 | LAST-MODIFIED:20110119T142040Z 70 | LOCATION: 71 | SEQUENCE:0 72 | STATUS:CONFIRMED 73 | SUMMARY: 74 | TRANSP:TRANSPARENT 75 | END:VEVENT 76 | BEGIN:VEVENT 77 | DTSTART;VALUE=DATE:20110117 78 | DTEND;VALUE=DATE:20110118 79 | DTSTAMP:20110121T195741Z 80 | UID:up56hlrtkpqdum73rk6tl10ook@google.com 81 | CREATED:20110119T142034Z 82 | DESCRIPTION: 83 | LAST-MODIFIED:20110119T142034Z 84 | LOCATION: 85 | SEQUENCE:0 86 | STATUS:CONFIRMED 87 | SUMMARY:test 8 88 | TRANSP:TRANSPARENT 89 | END:VEVENT 90 | BEGIN:VEVENT 91 | DTSTART;VALUE=DATE:20110118 92 | DTEND;VALUE=DATE:20110120 93 | DTSTAMP:20110121T195741Z 94 | UID:8ltm205uhshsbc1huv0ooeg4nc@google.com 95 | CREATED:20110119T142014Z 96 | DESCRIPTION: 97 | LAST-MODIFIED:20110119T142023Z 98 | LOCATION: 99 | SEQUENCE:0 100 | STATUS:CONFIRMED 101 | SUMMARY:test 7 102 | TRANSP:TRANSPARENT 103 | END:VEVENT 104 | BEGIN:VEVENT 105 | DTSTART;VALUE=DATE:20110119 106 | DTEND;VALUE=DATE:20110121 107 | DTSTAMP:20110121T195741Z 108 | UID:opklai3nm8enffdf5vpna4o5fo@google.com 109 | CREATED:20110119T141918Z 110 | DESCRIPTION: 111 | LAST-MODIFIED:20110119T142005Z 112 | LOCATION: 113 | SEQUENCE:0 114 | STATUS:CONFIRMED 115 | SUMMARY:test 5 116 | TRANSP:TRANSPARENT 117 | END:VEVENT 118 | BEGIN:VEVENT 119 | DTSTART;VALUE=DATE:20110119 120 | DTEND;VALUE=DATE:20110120 121 | DTSTAMP:20110121T195741Z 122 | UID:kmbj764g57tcvua11hir61c4b8@google.com 123 | CREATED:20110119T141923Z 124 | DESCRIPTION: 125 | LAST-MODIFIED:20110119T141923Z 126 | LOCATION: 127 | SEQUENCE:0 128 | STATUS:CONFIRMED 129 | SUMMARY:test 6 130 | TRANSP:TRANSPARENT 131 | END:VEVENT 132 | BEGIN:VEVENT 133 | DTSTART;VALUE=DATE:20110119 134 | DTEND;VALUE=DATE:20110120 135 | DTSTAMP:20110121T195741Z 136 | UID:shvr7hvqdag08vjqlmj5lj0i2s@google.com 137 | CREATED:20110119T141913Z 138 | DESCRIPTION: 139 | LAST-MODIFIED:20110119T141913Z 140 | LOCATION: 141 | SEQUENCE:0 142 | STATUS:CONFIRMED 143 | SUMMARY:test 4 144 | TRANSP:TRANSPARENT 145 | END:VEVENT 146 | BEGIN:VEVENT 147 | DTSTART;VALUE=DATE:20110119 148 | DTEND;VALUE=DATE:20110120 149 | DTSTAMP:20110121T195741Z 150 | UID:77gpemlb9es0r0gtjolv3mtap0@google.com 151 | CREATED:20110119T141909Z 152 | DESCRIPTION: 153 | LAST-MODIFIED:20110119T141909Z 154 | LOCATION: 155 | SEQUENCE:0 156 | STATUS:CONFIRMED 157 | SUMMARY:test 3 158 | TRANSP:TRANSPARENT 159 | END:VEVENT 160 | BEGIN:VEVENT 161 | DTSTART;VALUE=DATE:20110119 162 | DTEND;VALUE=DATE:20110120 163 | DTSTAMP:20110121T195741Z 164 | UID:rq8jng4jgq0m1lvpj8486fttu0@google.com 165 | CREATED:20110119T141904Z 166 | DESCRIPTION: 167 | LAST-MODIFIED:20110119T141904Z 168 | LOCATION: 169 | SEQUENCE:0 170 | STATUS:CONFIRMED 171 | SUMMARY:test 2 172 | TRANSP:TRANSPARENT 173 | END:VEVENT 174 | BEGIN:VEVENT 175 | DTSTART;VALUE=DATE:20110119 176 | DTEND;VALUE=DATE:20110120 177 | DTSTAMP:20110121T195741Z 178 | UID:dh3fki5du0opa7cs5n5s87ca00@google.com 179 | CREATED:20110119T141901Z 180 | DESCRIPTION: 181 | LAST-MODIFIED:20110119T141901Z 182 | LOCATION: 183 | SEQUENCE:0 184 | STATUS:CONFIRMED 185 | SUMMARY:test 1 186 | TRANSP:TRANSPARENT 187 | END:VEVENT 188 | BEGIN:VEVENT 189 | DTSTART;VALUE=DATE:20400201 190 | DTEND;VALUE=DATE:20400202 191 | DTSTAMP:20400101T195741Z 192 | UID:dh3fki5du0opa7cs5n5s87ca01@google.com 193 | CREATED:20400101T141901Z 194 | DESCRIPTION: 195 | LAST-MODIFIED:20400101T141901Z 196 | LOCATION: 197 | SEQUENCE:0 198 | STATUS:CONFIRMED 199 | SUMMARY:Year 2038 problem test 200 | TRANSP:TRANSPARENT 201 | END:VEVENT 202 | BEGIN:VEVENT 203 | DTSTART;VALUE=DATE:19410512 204 | DTEND;VALUE=DATE:19410512 205 | DTSTAMP:19410512T195741Z 206 | UID:dh3fki5du0opa7cs5n5s87ca02@google.com 207 | CREATED:20400101T141901Z 208 | DESCRIPTION: 209 | LAST-MODIFIED:20400101T141901Z 210 | LOCATION: 211 | SEQUENCE:0 212 | STATUS:CONFIRMED 213 | SUMMARY:Before 1970-Test: Konrad Zuse invents the Z3, the first digital Computer 214 | TRANSP:TRANSPARENT 215 | END:VEVENT 216 | END:VCALENDAR 217 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | This ics-parser is under MIT license. You may use it for your own sites for 2 | free, but I would like to get a notice when you use it (info@martin-thoma.de). 3 | If you use it for another software project, please let the information / links 4 | to this project in the files. 5 | 6 | It is hosted at https://github.com/MartinThoma/ics-parser/ and PEAR coding standard is 7 | used. 8 | 9 | **This project will not be continued. [johngrogg/ics-parser](https://github.com/johngrogg/ics-parser) is based on this project, but still supported and a few features were added.** 10 | 11 | 12 | ## Requirements 13 | 14 | * PHP 15 | 16 | 17 | 18 | ## Installation 19 | 20 | * Copy all files to a folder where PHP can be executed 21 | * Include class.iCalReader.php to your project 22 | 23 | ## Credits 24 | 25 | * Martin Thoma (programming, bug-fixing, project management) 26 | * Frank Gregor (programming, feedback, testing) 27 | 28 | 29 | ## Basic Usage ## 30 | The ics-Parser should only provide a very basic object to work with: 31 | 32 | ``` 33 | require 'class.iCalReader.php'; 34 | 35 | $ical = new ical('MyCal.ics'); 36 | print_r($ical->events()); 37 | ``` 38 | 39 | ## What does $ical->events() return? ## 40 | ``` 41 | Array 42 | ( 43 | [0] => Array 44 | ( 45 | [DTSTART] => 20110105T090000Z 46 | [DTEND] => 20110107T173000Z 47 | [DTSTAMP] => 20110121T195741Z 48 | [UID] => 15lc1nvupht8dtfiptenljoiv4@google.com 49 | [CREATED] => 20110121T195616Z 50 | [DESCRIPTION] => This is a short description\nwith a new line. Some "special" 'signs' may be \, too. 51 | [LAST-MODIFIED] => 20110121T195729Z 52 | [LOCATION] => Kansas 53 | [SEQUENCE] => 2 54 | [STATUS] => CONFIRMED 55 | [SUMMARY] => My Holidays 56 | [TRANSP] => TRANSPARENT 57 | ) 58 | 59 | [1] => Array 60 | ( 61 | [DTSTART] => 20110112 62 | [DTEND] => 20110116 63 | [DTSTAMP] => 20110121T195741Z 64 | [UID] => 1koigufm110c5hnq6ln57murd4@google.com 65 | [CREATED] => 20110119T142901Z 66 | [DESCRIPTION] => 67 | [LAST-MODIFIED] => 20110119T152216Z 68 | [LOCATION] => 69 | [SEQUENCE] => 2 70 | [STATUS] => CONFIRMED 71 | [SUMMARY] => test 11 72 | [TRANSP] => TRANSPARENT 73 | ) 74 | ) 75 | ``` 76 | 77 | ## How do I get a Unix timestamp out of a ical date? ## 78 | If the date is before 1970, it returns false. 79 | 80 | ``` 81 | events(); 86 | 87 | // The ical date 88 | $date = $array[0]['DTSTART']; 89 | echo $date; 90 | 91 | // The Unix timestamp 92 | echo $ical->iCalDateToUnixTimestamp($date); 93 | 94 | ?> 95 | ``` 96 | 97 | ## How many events / todos are in the iCal? ## 98 | ``` 99 | event_count; 106 | 107 | // The number of events 108 | echo $ical->todo_count; 109 | 110 | ?> 111 | ``` -------------------------------------------------------------------------------- /class.iCalReader.php: -------------------------------------------------------------------------------- 1 | 11 | * @license http://www.opensource.org/licenses/mit-license.php MIT License 12 | * @version SVN: 13 | * @link http://code.google.com/p/ics-parser/ 14 | * @example $ical = new ical('MyCal.ics'); 15 | * print_r( $ical->events() ); 16 | */ 17 | 18 | error_reporting(E_ALL); 19 | 20 | /** 21 | * This is the iCal-class 22 | * 23 | * @category Parser 24 | * @package Ics-parser 25 | * @author Martin Thoma 26 | * @license http://www.opensource.org/licenses/mit-license.php MIT License 27 | * @link http://code.google.com/p/ics-parser/ 28 | * 29 | * @param {string} filename The name of the file which should be parsed 30 | * @constructor 31 | */ 32 | class ICal 33 | { 34 | /* How many ToDos are in this ical? */ 35 | public /** @type {int} */ $todo_count = 0; 36 | 37 | /* How many events are in this ical? */ 38 | public /** @type {int} */ $event_count = 0; 39 | 40 | /* The parsed calendar */ 41 | public /** @type {Array} */ $cal; 42 | 43 | /* Which keyword has been added to cal at last? */ 44 | private /** @type {string} */ $_lastKeyWord; 45 | 46 | /** 47 | * Creates the iCal-Object 48 | * 49 | * @param {string} $filename The path to the iCal-file 50 | * 51 | * @return Object The iCal-Object 52 | */ 53 | public function __construct($filename) 54 | { 55 | if (!$filename) { 56 | return false; 57 | } 58 | 59 | $lines = file($filename, FILE_IGNORE_NEW_LINES | FILE_SKIP_EMPTY_LINES); 60 | if (stristr($lines[0], 'BEGIN:VCALENDAR') === false) { 61 | return false; 62 | } else { 63 | // TODO: Fix multiline-description problem (see http://tools.ietf.org/html/rfc2445#section-4.8.1.5) 64 | foreach ($lines as $line) { 65 | $line = trim($line); 66 | $add = $this->keyValueFromString($line); 67 | if ($add === false) { 68 | $this->addCalendarComponentWithKeyAndValue($type, false, $line); 69 | continue; 70 | } 71 | 72 | list($keyword, $value) = $add; 73 | 74 | switch ($line) { 75 | // http://www.kanzaki.com/docs/ical/vtodo.html 76 | case "BEGIN:VTODO": 77 | $this->todo_count++; 78 | $type = "VTODO"; 79 | break; 80 | 81 | // http://www.kanzaki.com/docs/ical/vevent.html 82 | case "BEGIN:VEVENT": 83 | //echo "vevent gematcht"; 84 | $this->event_count++; 85 | $type = "VEVENT"; 86 | break; 87 | 88 | //all other special strings 89 | case "BEGIN:VCALENDAR": 90 | case "BEGIN:DAYLIGHT": 91 | // http://www.kanzaki.com/docs/ical/vtimezone.html 92 | case "BEGIN:VTIMEZONE": 93 | case "BEGIN:STANDARD": 94 | $type = $value; 95 | break; 96 | case "END:VTODO": // end special text - goto VCALENDAR key 97 | case "END:VEVENT": 98 | case "END:VCALENDAR": 99 | case "END:DAYLIGHT": 100 | case "END:VTIMEZONE": 101 | case "END:STANDARD": 102 | $type = "VCALENDAR"; 103 | break; 104 | default: 105 | $this->addCalendarComponentWithKeyAndValue($type, 106 | $keyword, 107 | $value); 108 | break; 109 | } 110 | } 111 | return $this->cal; 112 | } 113 | } 114 | 115 | /** 116 | * Add to $this->ical array one value and key. 117 | * 118 | * @param {string} $component This could be VTODO, VEVENT, VCALENDAR, ... 119 | * @param {string} $keyword The keyword, for example DTSTART 120 | * @param {string} $value The value, for example 20110105T090000Z 121 | * 122 | * @return {None} 123 | */ 124 | public function addCalendarComponentWithKeyAndValue($component, 125 | $keyword, 126 | $value) 127 | { 128 | if ($keyword == false) { 129 | $keyword = $this->last_keyword; 130 | switch ($component) { 131 | case 'VEVENT': 132 | $value = $this->cal[$component][$this->event_count - 1] 133 | [$keyword].$value; 134 | break; 135 | case 'VTODO' : 136 | $value = $this->cal[$component][$this->todo_count - 1] 137 | [$keyword].$value; 138 | break; 139 | } 140 | } 141 | 142 | if (stristr($keyword, "DTSTART") or stristr($keyword, "DTEND")) { 143 | $keyword = explode(";", $keyword); 144 | $keyword = $keyword[0]; 145 | } 146 | 147 | switch ($component) { 148 | case "VTODO": 149 | $this->cal[$component][$this->todo_count - 1][$keyword] = $value; 150 | //$this->cal[$component][$this->todo_count]['Unix'] = $unixtime; 151 | break; 152 | case "VEVENT": 153 | $this->cal[$component][$this->event_count - 1][$keyword] = $value; 154 | break; 155 | default: 156 | $this->cal[$component][$keyword] = $value; 157 | break; 158 | } 159 | $this->last_keyword = $keyword; 160 | } 161 | 162 | /** 163 | * Get a key-value pair of a string. 164 | * 165 | * @param {string} $text which is like "VCALENDAR:Begin" or "LOCATION:" 166 | * 167 | * @return {array} array("VCALENDAR", "Begin") 168 | */ 169 | public function keyValueFromString($text) 170 | { 171 | preg_match("/([^:]+)[:]([\w\W]*)/", $text, $matches); 172 | if (count($matches) == 0) { 173 | return false; 174 | } 175 | $matches = array_splice($matches, 1, 2); 176 | return $matches; 177 | } 178 | 179 | /** 180 | * Return Unix timestamp from ical date time format 181 | * 182 | * @param {string} $icalDate A Date in the format YYYYMMDD[T]HHMMSS[Z] or 183 | * YYYYMMDD[T]HHMMSS 184 | * 185 | * @return {int} 186 | */ 187 | public function iCalDateToUnixTimestamp($icalDate) 188 | { 189 | $icalDate = str_replace('T', '', $icalDate); 190 | $icalDate = str_replace('Z', '', $icalDate); 191 | 192 | $pattern = '/([0-9]{4})'; // 1: YYYY 193 | $pattern .= '([0-9]{2})'; // 2: MM 194 | $pattern .= '([0-9]{2})'; // 3: DD 195 | $pattern .= '([0-9]{0,2})'; // 4: HH 196 | $pattern .= '([0-9]{0,2})'; // 5: MM 197 | $pattern .= '([0-9]{0,2})/'; // 6: SS 198 | preg_match($pattern, $icalDate, $date); 199 | 200 | // Unix timestamp can't represent dates before 1970 201 | if ($date[1] <= 1970) { 202 | return false; 203 | } 204 | // Unix timestamps after 03:14:07 UTC 2038-01-19 might cause an overflow 205 | // if 32 bit integers are used. 206 | $timestamp = mktime((int)$date[4], 207 | (int)$date[5], 208 | (int)$date[6], 209 | (int)$date[2], 210 | (int)$date[3], 211 | (int)$date[1]); 212 | return $timestamp; 213 | } 214 | 215 | /** 216 | * Returns an array of arrays with all events. Every event is an associative 217 | * array and each property is an element it. 218 | * 219 | * @return {array} 220 | */ 221 | public function events() 222 | { 223 | $array = $this->cal; 224 | return $array['VEVENT']; 225 | } 226 | 227 | /** 228 | * Returns a boolean value whether thr current calendar has events or not 229 | * 230 | * @return {boolean} 231 | */ 232 | public function hasEvents() 233 | { 234 | return ( count($this->events()) > 0 ? true : false ); 235 | } 236 | 237 | /** 238 | * Returns false when the current calendar has no events in range, else the 239 | * events. 240 | * 241 | * Note that this function makes use of a UNIX timestamp. This might be a 242 | * problem on January the 29th, 2038. 243 | * See http://en.wikipedia.org/wiki/Unix_time#Representing_the_number 244 | * 245 | * @param {boolean} $rangeStart Either true or false 246 | * @param {boolean} $rangeEnd Either true or false 247 | * 248 | * @return {mixed} 249 | */ 250 | public function eventsFromRange($rangeStart = false, $rangeEnd = false) 251 | { 252 | $events = $this->sortEventsWithOrder($this->events(), SORT_ASC); 253 | 254 | if (!$events) { 255 | return false; 256 | } 257 | 258 | $extendedEvents = array(); 259 | 260 | if ($rangeStart !== false) { 261 | $rangeStart = new DateTime(); 262 | } 263 | 264 | if ($rangeEnd !== false or $rangeEnd <= 0) { 265 | $rangeEnd = new DateTime('2038/01/18'); 266 | } else { 267 | $rangeEnd = new DateTime($rangeEnd); 268 | } 269 | 270 | $rangeStart = $rangeStart->format('U'); 271 | $rangeEnd = $rangeEnd->format('U'); 272 | 273 | 274 | 275 | // loop through all events by adding two new elements 276 | foreach ($events as $anEvent) { 277 | $timestamp = $this->iCalDateToUnixTimestamp($anEvent['DTSTART']); 278 | if ($timestamp >= $rangeStart && $timestamp <= $rangeEnd) { 279 | $extendedEvents[] = $anEvent; 280 | } 281 | } 282 | 283 | return $extendedEvents; 284 | } 285 | 286 | /** 287 | * Returns a boolean value whether thr current calendar has events or not 288 | * 289 | * @param {array} $events An array with events. 290 | * @param {array} $sortOrder Either SORT_ASC, SORT_DESC, SORT_REGULAR, 291 | * SORT_NUMERIC, SORT_STRING 292 | * 293 | * @return {boolean} 294 | */ 295 | public function sortEventsWithOrder($events, $sortOrder = SORT_ASC) 296 | { 297 | $extendedEvents = array(); 298 | 299 | // loop through all events by adding two new elements 300 | foreach ($events as $anEvent) { 301 | if (!array_key_exists('UNIX_TIMESTAMP', $anEvent)) { 302 | $anEvent['UNIX_TIMESTAMP'] = 303 | $this->iCalDateToUnixTimestamp($anEvent['DTSTART']); 304 | } 305 | 306 | if (!array_key_exists('REAL_DATETIME', $anEvent)) { 307 | $anEvent['REAL_DATETIME'] = 308 | date("d.m.Y", $anEvent['UNIX_TIMESTAMP']); 309 | } 310 | 311 | $extendedEvents[] = $anEvent; 312 | } 313 | 314 | foreach ($extendedEvents as $key => $value) { 315 | $timestamp[$key] = $value['UNIX_TIMESTAMP']; 316 | } 317 | array_multisort($timestamp, $sortOrder, $extendedEvents); 318 | 319 | return $extendedEvents; 320 | } 321 | } 322 | ?> 323 | -------------------------------------------------------------------------------- /example.php: -------------------------------------------------------------------------------- 1 | 10 | * @license http://www.opensource.org/licenses/mit-license.php MIT License 11 | * @version SVN: 12 | * @link http://code.google.com/p/ics-parser/ 13 | * @example $ical = new ical('MyCal.ics'); 14 | * print_r( $ical->get_event_array() ); 15 | */ 16 | require 'class.iCalReader.php'; 17 | 18 | $ical = new ICal('MyCal.ics'); 19 | $events = $ical->events(); 20 | 21 | $date = $events[0]['DTSTART']; 22 | echo "The ical date: "; 23 | echo $date; 24 | echo "
"; 25 | 26 | echo "The Unix timestamp: "; 27 | echo $ical->iCalDateToUnixTimestamp($date); 28 | echo "
"; 29 | 30 | echo "The number of events: "; 31 | echo $ical->event_count; 32 | echo "
"; 33 | 34 | echo "The number of todos: "; 35 | echo $ical->todo_count; 36 | echo "
"; 37 | echo "

"; 38 | 39 | foreach ($events as $event) { 40 | echo "SUMMARY: ".$event['SUMMARY']."
"; 41 | echo "DTSTART: ".$event['DTSTART']." - UNIX-Time: ".$ical->iCalDateToUnixTimestamp($event['DTSTART'])."
"; 42 | echo "DTEND: ".$event['DTEND']."
"; 43 | echo "DTSTAMP: ".$event['DTSTAMP']."
"; 44 | echo "UID: ".$event['UID']."
"; 45 | echo "CREATED: ".$event['CREATED']."
"; 46 | echo "DESCRIPTION: ".$event['DESCRIPTION']."
"; 47 | echo "LAST-MODIFIED: ".$event['LAST-MODIFIED']."
"; 48 | echo "LOCATION: ".$event['LOCATION']."
"; 49 | echo "SEQUENCE: ".$event['SEQUENCE']."
"; 50 | echo "STATUS: ".$event['STATUS']."
"; 51 | echo "TRANSP: ".$event['TRANSP']."
"; 52 | echo "
"; 53 | } 54 | ?> 55 | --------------------------------------------------------------------------------