This commit is contained in:
root 2018-05-17 15:41:10 +02:00
parent d206c242ca
commit 1490a96f14
42 changed files with 4705 additions and 0 deletions

View File

@ -12,5 +12,6 @@ else
mv /tmp/chch_$RAND.ical $CHCH_ICAL
fi
# this requires -> icalparser from https://github.com/OzzyCzech/icalparser.git
head $CHCH_ICAL -n1 >/dev/null 2>&1 && php /etc/chch/chch_ical2mediawiki.php $CHCH_ICAL 2>/dev/null | php /var/www/chch/maintenance/edit.php -m -b --no-rc -s "automatische Aktualisierung aus dem ical feed" "Aktuelle_ChCh-Termine" >/dev/null 2>&1
echo "Hauptseite" | php /var/www/chch/maintenance/purgeList.php --purge > /dev/null 2>&1

27
icalparser/.travis.yml Normal file
View File

@ -0,0 +1,27 @@
language: php
php:
- 5.6
- 7.0
- 7.1
- 7.2
- hhvm
matrix:
allow_failures:
- php: 7.1
- php: 7.2
- php: hhvm
include:
- php: 5.6
env: dependencies="--prefer-lowest --prefer-stable"
script:
- vendor/bin/tester tests -s -p php
after_failure:
- for i in $(find tests -name \*.actual); do echo "--- $i"; cat $i; echo; echo; done
before_script:
- composer self-update
- composer update --no-interaction --prefer-source $dependencies

24
icalparser/LICENSE Normal file
View File

@ -0,0 +1,24 @@
Copyright (c) 2014, Roman Ožana
All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
* Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the distribution.
* Neither the name of the <organization> nor the
names of its contributors may be used to endorse or promote products
derived from this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL <COPYRIGHT HOLDER> BE LIABLE FOR ANY
DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

28
icalparser/composer.json Normal file
View File

@ -0,0 +1,28 @@
{
"name": "om/icalparser",
"description": "Simple ical parser",
"keywords": [
"ical",
"calendar",
"parser"
],
"license": ["BSD-3-Clause"],
"authors": [
{
"name": "Roman Ožana",
"email": "ozana@omdesign.cz"
}
],
"require": {
"php": ">=5.6.0"
},
"autoload": {
"classmap": ["src/"]
},
"require-dev": {
"nette/tester": "v2.0.1"
},
"scripts": {
"tests": ["./vendor/bin/tester tests -s -p php"]
}
}

View File

@ -0,0 +1,32 @@
<!DOCTYPE html>
<html lang="cs-CZ">
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Ical Parser example</title>
<link href="//netdna.bootstrapcdn.com/bootstrap/3.0.3/css/bootstrap.min.css" rel="stylesheet">
</head>
<body>
<div class="container">
<h1>Czech holidays</h1>
<ul>
<?php
require_once __DIR__ . '/../vendor/autoload.php';
$cal = new \om\IcalParser();
$results = $cal->parseFile(
'https://www.google.com/calendar/ical/cs.czech%23holiday%40group.v.calendar.google.com/public/basic.ics'
);
foreach ($cal->getSortedEvents() as $r) {
echo sprintf(' <li>%s - %s</li>' . PHP_EOL, $r['DTSTART']->format('j.n.Y'), $r['SUMMARY']);
}
?></ul>
</div>
</body>
</html>

44
icalparser/readme.md Normal file
View File

@ -0,0 +1,44 @@
# PHP iCal Parser
[![Build Status](https://travis-ci.org/OzzyCzech/icalparser.svg?branch=master)](https://travis-ci.org/OzzyCzech/icalparser) [![Latest Stable Version](https://poser.pugx.org/om/icalparser/v/stable.png)](https://packagist.org/packages/om/icalparser) [![Total Downloads](https://poser.pugx.org/om/icalparser/downloads.png)](https://packagist.org/packages/om/icalparser) [![Latest Unstable Version](https://poser.pugx.org/om/icalparser/v/unstable.png)](https://packagist.org/packages/om/icalparser) [![License](https://poser.pugx.org/om/icalparser/license.png)](https://packagist.org/packages/om/icalparser)
Internet Calendaring Parser [rfc2445](http://www.ietf.org/rfc/rfc2445.txt) or iCal parser is simple PHP 5.6+ class for parsing format into array.
## How to install
```bash
composer require om/icalparser
```
## Usage
```php
<?php
require_once '../vendor/autoload.php';
$cal = new \om\IcalParser();
$results = $cal->parseFile(
'https://www.google.com/calendar/ical/cs.czech%23holiday%40group.v.calendar.google.com/public/basic.ics'
);
foreach ($cal->getSortedEvents() as $r) {
echo sprintf(' <li>%s - %s</li>' . PHP_EOL, $r['DTSTART']->format('j.n.Y'), $r['SUMMARY']);
}
```
## Requirements
- PHP 5.6+
## Run tests
iCal parser using [Nette Tester](https://github.com/nette/tester).
The tests can be invoked via [composer](https://getcomposer.org/).
```bash
composer update
composer tests
```
## TODO
- add ATTENDEE support http://www.kanzaki.com/docs/ical/attendee.html

600
icalparser/src/Freq.php Normal file
View File

@ -0,0 +1,600 @@
<?php
namespace om;
/**
* Class taken from https://github.com/coopTilleuls/intouch-iCalendar.git (Freq.php)
*
* @author PC Drew <pc@schoolblocks.com>
*/
/**
* A class to store Frequency-rules in. Will allow a easy way to find the
* last and next occurrence of the rule.
*
* No - this is so not pretty. But.. ehh.. You do it better, and I will
* gladly accept patches.
*
* Created by trail-and-error on the examples given in the RFC.
*
* TODO: Update to a better way of doing calculating the different options.
* Instead of only keeping track of the best of the current dates found
* it should instead keep a array of all the calculated dates within the
* period.
* This should fix the issues with multi-rule + multi-rule interference,
* and make it possible to implement the SETPOS rule.
* By pushing the next period onto the stack as the last option will
* (hopefully) remove the need for the awful simpleMode
*
* @author Morten Fangel (C) 2008
* @author Michael Kahn (C) 2013
* @license http://creativecommons.org/licenses/by-sa/2.5/dk/deed.en_GB CC-BY-SA-DK
*/
class Freq {
protected $weekdays = [
'MO' => 'monday', 'TU' => 'tuesday', 'WE' => 'wednesday', 'TH' => 'thursday', 'FR' => 'friday', 'SA' => 'saturday',
'SU' => 'sunday'
];
protected $knownRules = [
'month', 'weekno', 'day', 'monthday', 'yearday', 'hour', 'minute'
]; //others : 'setpos', 'second'
protected $ruleModifiers = ['wkst'];
protected $simpleMode = true;
protected $rules = ['freq' => 'yearly', 'interval' => 1];
protected $start = 0;
protected $freq = '';
protected $excluded; //EXDATE
protected $added; //RDATE
protected $cache; // getAllOccurrences()
/**
* Constructs a new Freqency-rule
*
* @param $rule string
* @param $start int Unix-timestamp (important : Need to be the start of Event)
* @param $excluded array of int (timestamps), see EXDATE documentation
* @param $added array of int (timestamps), see RDATE documentation
*/
public function __construct($rule, $start, $excluded = [], $added = []) {
$this->start = $start;
$this->excluded = [];
$rules = [];
foreach ($rule AS $k => $v) {
$this->rules[strtolower($k)] = $v;
}
if (isset($this->rules['until']) && is_string($this->rules['until'])) {
$this->rules['until'] = strtotime($this->rules['until']);
} else if ($this->rules['until'] instanceof \DateTime) {
$this->rules['until'] = $this->rules['until']->getTimestamp();
}
$this->freq = strtolower($this->rules['freq']);
foreach ($this->knownRules AS $rule) {
if (isset($this->rules['by' . $rule])) {
if ($this->isPrerule($rule, $this->freq)) {
$this->simpleMode = false;
}
}
}
if (!$this->simpleMode) {
if (!(isset($this->rules['byday']) || isset($this->rules['bymonthday']) || isset($this->rules['byyearday']))) {
$this->rules['bymonthday'] = date('d', $this->start);
}
}
//set until, and cache
if (isset($this->rules['count'])) {
$cache[$ts] = $ts = $this->start;
for ($n = 1; $n < $this->rules['count']; $n++) {
$ts = $this->findNext($ts);
$cache[$ts] = $ts;
}
$this->rules['until'] = $ts;
//EXDATE
if (!empty($excluded)) {
foreach ($excluded as $ts) {
unset($cache[$ts]);
}
}
//RDATE
if (!empty($added)) {
$cache = array_unique(array_merge(array_values($cache), $added));
asort($cache);
}
$this->cache = array_values($cache);
}
$this->excluded = $excluded;
$this->added = $added;
}
/**
* Returns all timestamps array(), build the cache if not made before
*
* @return array
*/
public function getAllOccurrences() {
if (empty($this->cache)) {
$cache = [];
//build cache
$next = $this->firstOccurrence();
while ($next) {
$cache[] = $next;
$next = $this->findNext($next);
}
if (!empty($this->added)) {
$cache = array_unique(array_merge($cache, $this->added));
asort($cache);
}
$this->cache = $cache;
}
return $this->cache;
}
/**
* Returns the previous (most recent) occurrence of the rule from the
* given offset
*
* @param int $offset
* @return int
*/
public function previousOccurrence($offset) {
if (!empty($this->cache)) {
$t2 = $this->start;
foreach ($this->cache as $ts) {
if ($ts >= $offset)
return $t2;
$t2 = $ts;
}
} else {
$ts = $this->start;
while (($t2 = $this->findNext($ts)) < $offset) {
if ($t2 == false) {
break;
}
$ts = $t2;
}
}
return $ts;
}
/**
* Returns the next occurrence of this rule after the given offset
*
* @param int $offset
* @return int
*/
public function nextOccurrence($offset) {
if ($offset < $this->start)
return $this->firstOccurrence();
return $this->findNext($offset);
}
/**
* Finds the first occurrence of the rule.
*
* @return int timestamp
*/
public function firstOccurrence() {
$t = $this->start;
if (in_array($t, $this->excluded))
$t = $this->findNext($t);
return $t;
}
/**
* Finds the absolute last occurrence of the rule from the given offset.
* Builds also the cache, if not set before...
*
* @return int timestamp
*/
public function lastOccurrence() {
//build cache if not done
$this->getAllOccurrences();
//return last timestamp in cache
return end($this->cache);
}
/**
* Calculates the next time after the given offset that the rule
* will apply.
*
* The approach to finding the next is as follows:
* First we establish a timeframe to find timestamps in. This is
* between $offset and the end of the period that $offset is in.
*
* We then loop though all the rules (that is a Prerule in the
* current freq.), and finds the smallest timestamp inside the
* timeframe.
*
* If we find something, we check if the date is a valid recurrence
* (with validDate). If it is, we return it. Otherwise we try to
* find a new date inside the same timeframe (but using the new-
* found date as offset)
*
* If no new timestamps were found in the period, we try in the
* next period
*
* @param int $offset
* @return int
*/
public function findNext($offset) {
if (!empty($this->cache)) {
foreach ($this->cache as $ts) {
if ($ts > $offset)
return $ts;
}
}
$debug = false;
//make sure the offset is valid
if ($offset === false || (isset($this->rules['until']) && $offset > $this->rules['until'])) {
if ($debug) echo 'STOP: ' . date('r', $offset) . "\n";
return false;
}
$found = true;
//set the timestamp of the offset (ignoring hours and minutes unless we want them to be
//part of the calculations.
if ($debug) echo 'O: ' . date('r', $offset) . "\n";
$hour = (in_array($this->freq, ['hourly', 'minutely']) && $offset > $this->start) ? date('H', $offset) : date(
'H', $this->start
);
$minute = (($this->freq === 'minutely' || isset($this->rules['byminute'])) && $offset > $this->start) ? date(
'i', $offset
) : date('i', $this->start);
$t = mktime($hour, $minute, date('s', $this->start), date('m', $offset), date('d', $offset), date('Y', $offset));
if ($debug) echo 'START: ' . date('r', $t) . "\n";
if ($this->simpleMode) {
if ($offset < $t) {
$ts = $t;
if ($ts && in_array($ts, $this->excluded))
$ts = $this->findNext($ts);
} else {
$ts = $this->findStartingPoint($t, $this->rules['interval'], false);
if (!$this->validDate($ts)) {
$ts = $this->findNext($ts);
}
}
return $ts;
}
$eop = $this->findEndOfPeriod($offset);
if ($debug) echo 'EOP: ' . date('r', $eop) . "\n";
foreach ($this->knownRules AS $rule) {
if ($found && isset($this->rules['by' . $rule])) {
if ($this->isPrerule($rule, $this->freq)) {
$subrules = explode(',', $this->rules['by' . $rule]);
$_t = null;
foreach ($subrules AS $subrule) {
$imm = call_user_func_array([$this, 'ruleBy' . $rule], [$subrule, $t]);
if ($imm === false) {
break;
}
if ($debug) echo strtoupper($rule) . ': ' . date(
'r', $imm
) . ' A: ' . ((int)($imm > $offset && $imm < $eop)) . "\n";
if ($imm > $offset && $imm <= $eop && ($_t == null || $imm < $_t)) {
$_t = $imm;
}
}
if ($_t !== null) {
$t = $_t;
} else {
$found = $this->validDate($t);
}
}
}
}
if ($offset < $this->start && $this->start < $t) {
$ts = $this->start;
} elseif ($found && ($t != $offset)) {
if ($this->validDate($t)) {
if ($debug) echo 'OK' . "\n";
$ts = $t;
} else {
if ($debug) echo 'Invalid' . "\n";
$ts = $this->findNext($t);
}
} else {
if ($debug) echo 'Not found' . "\n";
$ts = $this->findNext($this->findStartingPoint($offset, $this->rules['interval']));
}
if ($ts && in_array($ts, $this->excluded))
return $this->findNext($ts);
return $ts;
}
/**
* Finds the starting point for the next rule. It goes $interval
* 'freq' forward in time since the given offset
*
* @param int $offset
* @param int $interval
* @param boolean $truncate
* @return int
*/
private function findStartingPoint($offset, $interval, $truncate = true) {
$_freq = ($this->freq === 'daily') ? 'day__' : $this->freq;
$t = '+' . $interval . ' ' . substr($_freq, 0, -2) . 's';
if ($_freq === 'monthly' && $truncate) {
if ($interval > 1) {
$offset = strtotime('+' . ($interval - 1) . ' months ', $offset);
}
$t = '+' . (date('t', $offset) - date('d', $offset) + 1) . ' days';
}
$sp = strtotime($t, $offset);
if ($truncate) {
$sp = $this->truncateToPeriod($sp, $this->freq);
}
return $sp;
}
/**
* Finds the earliest timestamp posible outside this perioid
*
* @param int $offset
* @return int
*/
public function findEndOfPeriod($offset) {
return $this->findStartingPoint($offset, 1);
}
/**
* Resets the timestamp to the beginning of the
* period specified by freq
*
* Yes - the fall-through is on purpose!
*
* @param int $time
* @param int $freq
* @return int
*/
private function truncateToPeriod($time, $freq) {
$date = getdate($time);
switch ($freq) {
case 'yearly':
$date['mon'] = 1;
case 'monthly':
$date['mday'] = 1;
case 'daily':
$date['hours'] = 0;
case 'hourly':
$date['minutes'] = 0;
case 'minutely':
$date['seconds'] = 0;
break;
case 'weekly':
if (date('N', $time) == 1) {
$date['hours'] = 0;
$date['minutes'] = 0;
$date['seconds'] = 0;
} else {
$date = getdate(strtotime('last monday 0:00', $time));
}
break;
}
$d = mktime($date['hours'], $date['minutes'], $date['seconds'], $date['mon'], $date['mday'], $date['year']);
return $d;
}
/**
* Applies the BYDAY rule to the given timestamp
*
* @param string $rule
* @param int $t
* @return int
*/
private function ruleByday($rule, $t) {
$dir = ($rule{0} == '-') ? -1 : 1;
$dir_t = ($dir == 1) ? 'next' : 'last';
$d = $this->weekdays[substr($rule, -2)];
$s = $dir_t . ' ' . $d . ' ' . date('H:i:s', $t);
if ($rule == substr($rule, -2)) {
if (date('l', $t) == ucfirst($d)) {
$s = 'today ' . date('H:i:s', $t);
}
$_t = strtotime($s, $t);
if ($_t == $t && in_array($this->freq, ['weekly', 'monthly', 'yearly'])) {
// Yes. This is not a great idea.. but hey, it works.. for now
$s = 'next ' . $d . ' ' . date('H:i:s', $t);
$_t = strtotime($s, $_t);
}
return $_t;
} else {
$_f = $this->freq;
if (isset($this->rules['bymonth']) && $this->freq === 'yearly') {
$this->freq = 'monthly';
}
if ($dir == -1) {
$_t = $this->findEndOfPeriod($t);
} else {
$_t = $this->truncateToPeriod($t, $this->freq);
}
$this->freq = $_f;
$c = preg_replace('/[^0-9]/', '', $rule);
$c = ($c == '') ? 1 : $c;
$n = $_t;
while ($c > 0) {
if ($dir == 1 && $c == 1 && date('l', $t) == ucfirst($d)) {
$s = 'today ' . date('H:i:s', $t);
}
$n = strtotime($s, $n);
$c--;
}
return $n;
}
}
private function ruleBymonth($rule, $t) {
$_t = mktime(date('H', $t), date('i', $t), date('s', $t), $rule, date('d', $t), date('Y', $t));
if ($t == $_t && isset($this->rules['byday'])) {
// TODO: this should check if one of the by*day's exists, and have a multi-day value
return false;
} else {
return $_t;
}
}
private function ruleBymonthday($rule, $t) {
if ($rule < 0) {
$rule = date('t', $t) + $rule + 1;
}
return mktime(date('H', $t), date('i', $t), date('s', $t), date('m', $t), $rule, date('Y', $t));
}
private function ruleByyearday($rule, $t) {
if ($rule < 0) {
$_t = $this->findEndOfPeriod();
$d = '-';
} else {
$_t = $this->truncateToPeriod($t, $this->freq);
$d = '+';
}
$s = $d . abs($rule - 1) . ' days ' . date('H:i:s', $t);
return strtotime($s, $_t);
}
private function ruleByweekno($rule, $t) {
if ($rule < 0) {
$_t = $this->findEndOfPeriod();
$d = '-';
} else {
$_t = $this->truncateToPeriod($t, $this->freq);
$d = '+';
}
$sub = (date('W', $_t) == 1) ? 2 : 1;
$s = $d . abs($rule - $sub) . ' weeks ' . date('H:i:s', $t);
$_t = strtotime($s, $_t);
return $_t;
}
private function ruleByhour($rule, $t) {
$_t = mktime($rule, date('i', $t), date('s', $t), date('m', $t), date('d', $t), date('Y', $t));
return $_t;
}
private function ruleByminute($rule, $t) {
$_t = mktime(date('h', $t), $rule, date('s', $t), date('m', $t), date('d', $t), date('Y', $t));
return $_t;
}
private function validDate($t) {
if (isset($this->rules['until']) && $t > $this->rules['until']) {
return false;
}
if (in_array($t, $this->excluded)) {
return false;
}
if (isset($this->rules['bymonth'])) {
$months = explode(',', $this->rules['bymonth']);
if (!in_array(date('m', $t), $months)) {
return false;
}
}
if (isset($this->rules['byday'])) {
$days = explode(',', $this->rules['byday']);
foreach ($days As $i => $k) {
$days[$i] = $this->weekdays[preg_replace('/[^A-Z]/', '', $k)];
}
if (!in_array(strtolower(date('l', $t)), $days)) {
return false;
}
}
if (isset($this->rules['byweekno'])) {
$weeks = explode(',', $this->rules['byweekno']);
if (!in_array(date('W', $t), $weeks)) {
return false;
}
}
if (isset($this->rules['bymonthday'])) {
$weekdays = explode(',', $this->rules['bymonthday']);
foreach ($weekdays As $i => $k) {
if ($k < 0) {
$weekdays[$i] = date('t', $t) + $k + 1;
}
}
if (!in_array(date('d', $t), $weekdays)) {
return false;
}
}
if (isset($this->rules['byhour'])) {
$hours = explode(',', $this->rules['byhour']);
if (!in_array(date('H', $t), $hours)) {
return false;
}
}
return true;
}
private function isPrerule($rule, $freq) {
if ($rule === 'year')
return false;
if ($rule === 'month' && $freq === 'yearly')
return true;
if ($rule === 'monthday' && in_array($freq, ['yearly', 'monthly']) && !isset($this->rules['byday']))
return true;
// TODO: is it faster to do monthday first, and ignore day if monthday exists? - prolly by a factor of 4..
if ($rule === 'yearday' && $freq === 'yearly')
return true;
if ($rule === 'weekno' && $freq === 'yearly')
return true;
if ($rule === 'day' && in_array($freq, ['yearly', 'monthly', 'weekly']))
return true;
if ($rule === 'hour' && in_array($freq, ['yearly', 'monthly', 'weekly', 'daily']))
return true;
if ($rule === 'minute')
return true;
return false;
}
}

View File

@ -0,0 +1,471 @@
<?php
namespace om;
/**
* Copyright (c) 2004-2015 Roman Ožana (http://www.omdesign.cz)
*
* @author Roman Ožana <ozana@omdesign.cz>
*/
class IcalParser {
/** @var \DateTimeZone */
public $timezone;
/** @var array */
public $data = [];
/** @var array */
protected $counters = [];
/** @var array */
private $windowsTimezones;
protected $arrayKeyMappings = [
'ATTACH' => 'ATTACHMENTS',
'EXDATE' => 'EXDATES',
'RDATE' => 'RDATES',
];
public function __construct() {
$this->windowsTimezones = require __DIR__ . '/WindowsTimezones.php'; // load Windows timezones from separate file
}
/**
* @param string $file
* @param null $callback
* @return array|null
* @throws \RuntimeException
* @throws \InvalidArgumentException
* @throws \Exception
*/
public function parseFile($file, $callback = null) {
if (!$handle = fopen($file, 'r')) {
throw new \RuntimeException('Can\'t open file' . $file . ' for reading');
}
fclose($handle);
return $this->parseString(file_get_contents($file), $callback);
}
/**
* @param string $string
* @param null $callback
* @param boolean $add if true the parsed string is added to existing data
* @return array|null
* @throws \InvalidArgumentException
* @throws \Exception
*/
public function parseString($string, $callback = null, $add = false) {
if ($add === false) {
// delete old data
$this->data = [];
$this->counters = [];
}
if (!preg_match('/BEGIN:VCALENDAR/', $string)) {
throw new \InvalidArgumentException('Invalid ICAL data format');
}
$section = 'VCALENDAR';
// Replace \r\n with \n
$string = str_replace("\r\n", "\n", $string);
// Unfold multi-line strings
$string = str_replace("\n ", '', $string);
foreach (explode("\n", $string) as $row) {
switch ($row) {
case 'BEGIN:DAYLIGHT':
case 'BEGIN:VALARM':
case 'BEGIN:VTIMEZONE':
case 'BEGIN:VFREEBUSY':
case 'BEGIN:VJOURNAL':
case 'BEGIN:STANDARD':
case 'BEGIN:VTODO':
case 'BEGIN:VEVENT':
$section = substr($row, 6);
$this->counters[$section] = isset($this->counters[$section]) ? $this->counters[$section] + 1 : 0;
continue 2; // while
break;
case 'END:VEVENT':
$section = substr($row, 4);
$currCounter = $this->counters[$section];
$event = $this->data[$section][$currCounter];
if (!empty($event['RECURRENCE-ID'])) {
$this->data['_RECURRENCE_IDS'][$event['RECURRENCE-ID']] = $event;
}
continue 2; // while
break;
case 'END:DAYLIGHT':
case 'END:VALARM':
case 'END:VTIMEZONE':
case 'END:VFREEBUSY':
case 'END:VJOURNAL':
case 'END:STANDARD':
case 'END:VTODO':
continue 2; // while
break;
case 'END:VCALENDAR':
$veventSection = 'VEVENT';
if (!empty($this->data[$veventSection])) {
foreach ($this->data[$veventSection] as $currCounter => $event) {
if (!empty($event['RRULE']) || !empty($event['RDATE'])) {
$recurrences = $this->parseRecurrences($event);
if (!empty($recurrences)) {
$this->data[$veventSection][$currCounter]['RECURRENCES'] = $recurrences;
}
if (!empty($event['UID'])) {
$this->data["_RECURRENCE_COUNTERS_BY_UID"][$event['UID']] = $currCounter;
}
}
}
}
continue 2; // while
break;
}
list($key, $middle, $value) = $this->parseRow($row);
if ($callback) {
// call user function for processing line
call_user_func($callback, $row, $key, $middle, $value, $section, $this->counters[$section]);
} else {
if ($section === 'VCALENDAR') {
$this->data[$key] = $value;
} else {
if (isset($this->arrayKeyMappings[$key])) {
// use an array since there can be multiple entries for this key. This does not
// break the current implementation--it leaves the original key alone and adds
// a new one specifically for the array of values.
$arrayKey = $this->arrayKeyMappings[$key];
$this->data[$section][$this->counters[$section]][$arrayKey][] = $value;
}
$this->data[$section][$this->counters[$section]][$key] = $value;
}
}
}
return ($callback) ? null : $this->data;
}
/**
* @param $row
* @return array
*/
private function parseRow($row) {
preg_match('#^([\w-]+);?([\w-]+="[^"]*"|.*?):(.*)$#i', $row, $matches);
$key = false;
$middle = null;
$value = null;
if ($matches) {
$key = $matches[1];
$middle = $matches[2];
$value = $matches[3];
$timezone = null;
if ($key === 'X-WR-TIMEZONE' || $key === 'TZID') {
if (preg_match('#(\w+/\w+)$#i', $value, $matches)) {
$value = $matches[1];
}
$value = $this->toTimezone($value);
$this->timezone = new \DateTimeZone($value);
}
// have some middle part ?
if ($middle && preg_match_all('#(?<key>[^=;]+)=(?<value>[^;]+)#', $middle, $matches, PREG_SET_ORDER)) {
$middle = [];
foreach ($matches as $match) {
if ($match['key'] === 'TZID') {
$match['value'] = trim($match['value'], "'\"");
$match['value'] = $this->toTimezone($match['value']);
try {
$middle[$match['key']] = $timezone = new \DateTimeZone($match['value']);
} catch (\Exception $e) {
$middle[$match['key']] = $match['value'];
}
} else if ($match['key'] === 'ENCODING') {
if ($match['value'] === 'QUOTED-PRINTABLE') {
$value = quoted_printable_decode($value);
}
}
}
}
}
// process simple dates with timezone
if (in_array($key, ['DTSTAMP', 'LAST-MODIFIED', 'CREATED', 'DTSTART', 'DTEND'], true)) {
try {
$value = new \DateTime($value, ($timezone ?: $this->timezone));
} catch (\Exception $e) {
$value = null;
}
} else if (in_array($key, ['EXDATE', 'RDATE'])) {
$values = [];
foreach (explode(',', $value) as $singleValue) {
try {
$values[] = new \DateTime($singleValue, ($timezone ?: $this->timezone));
} catch (\Exception $e) {
// pass
}
}
if (count($values) === 1) {
$value = $values[0];
} else {
$value = $values;
}
}
if ($key === 'RRULE' && preg_match_all('#(?<key>[^=;]+)=(?<value>[^;]+)#', $value, $matches, PREG_SET_ORDER)) {
$middle = null;
$value = [];
foreach ($matches as $match) {
if (in_array($match['key'], ['UNTIL'])) {
try {
$value[$match['key']] = new \DateTime($match['value'], ($timezone ?: $this->timezone));
} catch (\Exception $e) {
$value[$match['key']] = $match['value'];
}
} else {
$value[$match['key']] = $match['value'];
}
}
}
//split by comma, escape \,
if ($key === 'CATEGORIES') {
$value = preg_split('/(?<![^\\\\]\\\\),/', $value);
}
//implement 4.3.11 Text ESCAPED-CHAR
$text_properties = [
'CALSCALE', 'METHOD', 'PRODID', 'VERSION', 'CATEGORIES', 'CLASS', 'COMMENT', 'DESCRIPTION'
, 'LOCATION', 'RESOURCES', 'STATUS', 'SUMMARY', 'TRANSP', 'TZID', 'TZNAME', 'CONTACT', 'RELATED-TO', 'UID'
, 'ACTION', 'REQUEST-STATUS'
];
if (in_array($key, $text_properties) || strpos($key, 'X-') === 0) {
if (is_array($value)) {
foreach ($value as &$var) {
$var = strtr($var, ['\\\\' => '\\', '\\N' => "\n", '\\n' => "\n", '\\;' => ';', '\\,' => ',']);
}
} else {
$value = strtr($value, ['\\\\' => '\\', '\\N' => "\n", '\\n' => "\n", '\\;' => ';', '\\,' => ',']);
}
}
return [$key, $middle, $value];
}
/**
* @param $event
* @return array
* @throws \Exception
*/
public function parseRecurrences($event) {
$recurring = new Recurrence($event['RRULE']);
$exclusions = [];
$additions = [];
if (!empty($event['EXDATES'])) {
foreach ($event['EXDATES'] as $exDate) {
if (is_array($exDate)) {
foreach ($exDate as $singleExDate) {
$exclusions[] = $singleExDate->getTimestamp();
}
} else {
$exclusions[] = $exDate->getTimestamp();
}
}
}
if (!empty($event['RDATES'])) {
foreach ($event['RDATES'] as $rDate) {
if (is_array($rDate)) {
foreach ($rDate as $singleRDate) {
$additions[] = $singleRDate->getTimestamp();
}
} else {
$additions[] = $rDate->getTimestamp();
}
}
}
$until = $recurring->getUntil();
if ($until === false) {
//forever... limit to 3 years
$end = clone($event['DTSTART']);
$end->add(new \DateInterval('P3Y')); // + 3 years
$recurring->setUntil($end);
$until = $recurring->getUntil();
}
date_default_timezone_set($event['DTSTART']->getTimezone()->getName());
$frequency = new Freq($recurring->rrule, $event['DTSTART']->getTimestamp(), $exclusions, $additions);
$recurrenceTimestamps = $frequency->getAllOccurrences();
$recurrences = [];
foreach ($recurrenceTimestamps as $recurrenceTimestamp) {
$tmp = new \DateTime('now', $event['DTSTART']->getTimezone());
$tmp->setTimestamp($recurrenceTimestamp);
$recurrenceIDDate = $tmp->format('Ymd');
$recurrenceIDDateTime = $tmp->format('Ymd\THis');
if (empty($this->data['_RECURRENCE_IDS'][$recurrenceIDDate]) &&
empty($this->data['_RECURRENCE_IDS'][$recurrenceIDDateTime])) {
$gmtCheck = new \DateTime("now", new \DateTimeZone('UTC'));
$gmtCheck->setTimestamp($recurrenceTimestamp);
$recurrenceIDDateTimeZ = $gmtCheck->format('Ymd\THis\Z');
if (empty($this->data['_RECURRENCE_IDS'][$recurrenceIDDateTimeZ])) {
$recurrences[] = $tmp;
}
}
}
return $recurrences;
}
/**
* @return array
*/
public function getEvents() {
$events = [];
if (isset($this->data['VEVENT'])) {
for ($i = 0; $i < count($this->data['VEVENT']); $i++) {
$event = $this->data['VEVENT'][$i];
if (empty($event['RECURRENCES'])) {
if (!empty($event['RECURRENCE-ID']) && !empty($event['UID']) && isset($event['SEQUENCE'])) {
$modifiedEventUID = $event['UID'];
$modifiedEventRecurID = $event['RECURRENCE-ID'];
$modifiedEventSeq = intval($event['SEQUENCE'], 10);
if (isset($this->data["_RECURRENCE_COUNTERS_BY_UID"][$modifiedEventUID])) {
$counter = $this->data["_RECURRENCE_COUNTERS_BY_UID"][$modifiedEventUID];
$originalEvent = $this->data["VEVENT"][$counter];
if (isset($originalEvent['SEQUENCE'])) {
$originalEventSeq = intval($originalEvent['SEQUENCE'], 10);
$originalEventFormattedStartDate = $originalEvent['DTSTART']->format('Ymd\THis');
if ($modifiedEventRecurID === $originalEventFormattedStartDate && $modifiedEventSeq > $originalEventSeq) {
// this modifies the original event
$modifiedEvent = array_replace_recursive($originalEvent, $event);
$this->data["VEVENT"][$counter] = $modifiedEvent;
foreach ($events as $z => $event) {
if ($events[$z]['UID'] === $originalEvent['UID'] &&
$events[$z]['SEQUENCE'] === $originalEvent['SEQUENCE']) {
// replace the original event with the modified event
$events[$z] = $modifiedEvent;
break;
}
}
$event = null; // don't add this to the $events[] array again
} else if (!empty($originalEvent['RECURRENCES'])) {
for ($j = 0; $j < count($originalEvent['RECURRENCES']); $j++) {
$recurDate = $originalEvent['RECURRENCES'][$j];
$formattedStartDate = $recurDate->format('Ymd\THis');
if ($formattedStartDate === $modifiedEventRecurID) {
unset($this->data["VEVENT"][$counter]['RECURRENCES'][$j]);
$this->data["VEVENT"][$counter]['RECURRENCES'] = array_values($this->data["VEVENT"][$counter]['RECURRENCES']);
break;
}
}
}
}
}
}
if (!empty($event)) {
$events[] = $event;
}
} else {
$recurrences = $event['RECURRENCES'];
$event['RECURRING'] = true;
$event['DTEND'] = !empty($event['DTEND']) ? $event['DTEND'] : $event['DTSTART'];
$eventInterval = $event['DTSTART']->diff($event['DTEND']);
$firstEvent = true;
foreach ($recurrences as $j => $recurDate) {
$newEvent = $event;
if (!$firstEvent) {
unset($newEvent['RECURRENCES']);
$newEvent['DTSTART'] = $recurDate;
$newEvent['DTEND'] = clone($recurDate);
$newEvent['DTEND']->add($eventInterval);
}
$newEvent['RECURRENCE_INSTANCE'] = $j;
$events[] = $newEvent;
$firstEvent = false;
}
}
}
}
return $events;
}
/**
* Process timezone and return correct one...
*
* @param string $zone
* @return mixed|null
*/
private function toTimezone($zone) {
return isset($this->windowsTimezones[$zone]) ? $this->windowsTimezones[$zone] : $zone;
}
/**
* @return array
*/
public function getAlarms() {
return isset($this->data['VALARM']) ? $this->data['VALARM'] : [];
}
/**
* @return array
*/
public function getTimezones() {
return isset($this->data['VTIMEZONE']) ? $this->data['VTIMEZONE'] : [];
}
/**
* Return sorted event list as array
*
* @return array
*/
public function getSortedEvents() {
if ($events = $this->getEvents()) {
usort(
$events, function ($a, $b) {
return $a['DTSTART'] > $b['DTSTART'];
}
);
return $events;
}
return [];
}
/**
* @return array
*/
public function getReverseSortedEvents() {
if ($events = $this->getEvents()) {
usort(
$events, function ($a, $b) {
return $a['DTSTART'] < $b['DTSTART'];
}
);
return $events;
}
return [];
}
}

View File

@ -0,0 +1,234 @@
<?php
namespace om;
use \DateTime;
/**
* Class taken from https://github.com/coopTilleuls/intouch-iCalendar.git (Recurrence.php)
*
* A wrapper for recurrence rules in iCalendar. Parses the given line and puts the
* recurrence rules in the correct field of this object.
*
* See http://tools.ietf.org/html/rfc2445 for more information. Page 39 and onward contains more
* information on the recurrence rules themselves. Page 116 and onward contains
* some great examples which were often used for testing.
*
* @author Steven Oxley
* @author Michael Kahn (C) 2013
* @license http://creativecommons.org/licenses/by-sa/2.5/dk/deed.en_GB CC-BY-SA-DK
*/
class Recurrence {
public $rrule;
protected $freq;
protected $until;
protected $count;
protected $interval;
protected $bysecond;
protected $byminute;
protected $byhour;
protected $byday;
protected $bymonthday;
protected $byyearday;
protected $byweekno;
protected $bymonth;
protected $bysetpos;
protected $wkst;
/**
* A list of the properties that can have comma-separated lists for values.
*
* @var array
*/
protected $listProperties = [
'bysecond', 'byminute', 'byhour', 'byday', 'bymonthday',
'byyearday', 'byweekno', 'bymonth', 'bysetpos'
];
/**
* Creates an recurrence object with a passed in line. Parses the line.
*
* @param array $rrule an om\icalparser row array which will be parsed to get the
* desired information.
*/
public function __construct($rrule) {
$this->parseRrule($rrule);
}
/**
* Parses an 'RRULE' array and sets the member variables of this object.
* Expects a string that looks like this: 'FREQ=WEEKLY;INTERVAL=2;BYDAY=SU,TU,WE'
*
* @param $rrule
*/
protected function parseRrule($rrule) {
$this->rrule = $rrule;
//loop through the properties in the line and set their associated
//member variables
foreach ($this->rrule as $propertyName => $propertyValue) {
//need the lower-case name for setting the member variable
$propertyName = strtolower($propertyName);
//split up the list of values into an array (if it's a list)
if (in_array($propertyName, $this->listProperties, true)) {
$propertyValue = explode(',', $propertyValue);
}
$this->$propertyName = $propertyValue;
}
}
/**
* Set the $until member
*
* @param mixed timestamp (int) / Valid DateTime format (string)
*/
public function setUntil($ts) {
if ($ts instanceof DateTime) {
$dt = $ts;
} else if (is_int($ts)) {
$dt = new DateTime('@' . $ts);
} else {
$dt = new DateTime($ts);
}
$this->until = $dt->format('Ymd\THisO');
$this->rrule['until'] = $this->until;
}
/**
* Retrieves the desired member variable and returns it (if it's set)
*
* @param string $member name of the member variable
* @return mixed the variable value (if set), false otherwise
*/
protected function getMember($member) {
if (isset($this->$member)) {
return $this->$member;
}
return false;
}
/**
* Returns the frequency - corresponds to FREQ in RFC 2445.
*
* @return mixed string if the member has been set, false otherwise
*/
public function getFreq() {
return $this->getMember('freq');
}
/**
* Returns when the event will go until - corresponds to UNTIL in RFC 2445.
*
* @return mixed string if the member has been set, false otherwise
*/
public function getUntil() {
return $this->getMember('until');
}
/**
* Returns the count of the times the event will occur (should only appear if 'until'
* does not appear) - corresponds to COUNT in RFC 2445.
*
* @return mixed string if the member has been set, false otherwise
*/
public function getCount() {
return $this->getMember('count');
}
/**
* Returns the interval - corresponds to INTERVAL in RFC 2445.
*
* @return mixed string if the member has been set, false otherwise
*/
public function getInterval() {
return $this->getMember('interval');
}
/**
* Returns the bysecond part of the event - corresponds to BYSECOND in RFC 2445.
*
* @return mixed string if the member has been set, false otherwise
*/
public function getBySecond() {
return $this->getMember('bysecond');
}
/**
* Returns the byminute information for the event - corresponds to BYMINUTE in RFC 2445.
*
* @return mixed string if the member has been set, false otherwise
*/
public function getByMinute() {
return $this->getMember('byminute');
}
/**
* Corresponds to BYHOUR in RFC 2445.
*
* @return mixed string if the member has been set, false otherwise
*/
public function getByHour() {
return $this->getMember('byhour');
}
/**
*Corresponds to BYDAY in RFC 2445.
*
* @return mixed string if the member has been set, false otherwise
*/
public function getByDay() {
return $this->getMember('byday');
}
/**
* Corresponds to BYMONTHDAY in RFC 2445.
*
* @return mixed string if the member has been set, false otherwise
*/
public function getByMonthDay() {
return $this->getMember('bymonthday');
}
/**
* Corresponds to BYYEARDAY in RFC 2445.
*
* @return mixed string if the member has been set, false otherwise
*/
public function getByYearDay() {
return $this->getMember('byyearday');
}
/**
* Corresponds to BYWEEKNO in RFC 2445.
*
* @return mixed string if the member has been set, false otherwise
*/
public function getByWeekNo() {
return $this->getMember('byweekno');
}
/**
* Corresponds to BYMONTH in RFC 2445.
*
* @return mixed string if the member has been set, false otherwise
*/
public function getByMonth() {
return $this->getMember('bymonth');
}
/**
* Corresponds to BYSETPOS in RFC 2445.
*
* @return mixed string if the member has been set, false otherwise
*/
public function getBySetPos() {
return $this->getMember('bysetpos');
}
/**
* Corresponds to WKST in RFC 2445.
*
* @return mixed string if the member has been set, false otherwise
*/
public function getWkst() {
return $this->getMember('wkst');
}
}

View File

@ -0,0 +1,210 @@
<?php
/**
* List of Windows Timezones
*/
return [
'Dateline Standard Time' => 'Etc/GMT+12',
'(UTC-12:00) International Date Line West' => 'Etc/GMT+12',
'UTC-11' => 'Etc/GMT+11',
'(UTC-11:00) Coordinated Universal Time -11' => 'Etc/GMT+11',
'Hawaiian Standard Time' => 'Pacific/Honolulu',
'(UTC-10:00) Hawaii' => 'Pacific/Honolulu',
'Alaskan Standard Time' => 'America/Anchorage',
'(UTC-09:00) Alaska' => 'America/Anchorage',
'Pacific Standard Time (Mexico)' => 'America/Santa_Isabel',
'(UTC-08:00) Baja California' => 'America/Santa_Isabel',
'Pacific Standard Time' => 'America/Los_Angeles',
'Pacific Time' => 'America/Los_Angeles',
'(UTC-08:00) Pacific Time (US and Canada)' => 'America/Los_Angeles',
'(UTC-08:00) Pacific Time (US & Canada)' => 'America/Los_Angeles',
'US Mountain Standard Time' => 'America/Phoenix',
'(UTC-07:00) Arizona' => 'America/Phoenix',
'Mountain Standard Time (Mexico)' => 'America/Chihuahua',
'(UTC-07:00) Chihuahua, La Paz, Mazatlan' => 'America/Chihuahua',
'Mountain Standard Time' => 'America/Denver',
'Mountain Time' => 'America/Denver',
'(UTC-07:00) Mountain Time (US and Canada)' => 'America/Denver',
'(UTC-07:00) Mountain Time (US & Canada)' => 'America/Denver',
'Central America Standard Time' => 'America/Guatemala',
'(UTC-06:00) Central America' => 'America/Guatemala',
'Central Standard Time' => 'America/Chicago',
'Central Time' => 'America/Chicago',
'(UTC-06:00) Central Time (US and Canada)' => 'America/Chicago',
'(UTC-06:00) Central Time (US & Canada)' => 'America/Chicago',
'Central Standard Time (Mexico)' => 'America/Mexico_City',
'(UTC-06:00) Guadalajara, Mexico City, Monterrey' => 'America/Mexico_City',
'Canada Central Standard Time' => 'America/Regina',
'(UTC-06:00) Saskatchewan' => 'America/Regina',
'SA Pacific Standard Time' => 'America/Bogota',
'(UTC-05:00) Bogota, Lima, Quito' => 'America/Bogota',
'Eastern Standard Time' => 'America/New_York',
'Eastern Time' => 'America/New_York',
'(UTC-05:00) Eastern Time (US and Canada)' => 'America/New_York',
'(UTC-05:00) Eastern Time (US & Canada)' => 'America/New_York',
'US Eastern Standard Time' => 'America/Indianapolis',
'(UTC-05:00) Indiana (East)' => 'America/Indianapolis',
'Venezuela Standard Time' => 'America/Caracas',
'(UTC-04:30) Caracas' => 'America/Caracas',
'Paraguay Standard Time' => 'America/Asuncion',
'(UTC-04:00) Asuncion' => 'America/Asuncion',
'Atlantic Standard Time' => 'America/Halifax',
'(UTC-04:00) Atlantic Time (Canada)' => 'America/Halifax',
'Central Brazilian Standard Time' => 'America/Cuiaba',
'(UTC-04:00) Cuiaba' => 'America/Cuiaba',
'SA Western Standard Time' => 'America/La_Paz',
'(UTC-04:00) Georgetown, La Paz, Manaus, San Juan' => 'America/La_Paz',
'Pacific SA Standard Time' => 'America/Santiago',
'(UTC-04:00) Santiago' => 'America/Santiago',
'Newfoundland Standard Time' => 'America/St_Johns',
'(UTC-03:30) Newfoundland' => 'America/St_Johns',
'E. South America Standard Time' => 'America/Sao_Paulo',
'(UTC-03:00) Brasilia' => 'America/Sao_Paulo',
'Argentina Standard Time' => 'America/Buenos_Aires',
'(UTC-03:00) Buenos Aires' => 'America/Buenos_Aires',
'SA Eastern Standard Time' => 'America/Cayenne',
'(UTC-03:00) Cayenne, Fortaleza' => 'America/Cayenne',
'Greenland Standard Time' => 'America/Godthab',
'(UTC-03:00) Greenland' => 'America/Godthab',
'Montevideo Standard Time' => 'America/Montevideo',
'(UTC-03:00) Montevideo' => 'America/Montevideo',
'Bahia Standard Time' => 'America/Bahia',
'UTC-02' => 'Etc/GMT+2',
'(UTC-02:00) Coordinated Universal Time -02' => 'Etc/GMT+2',
'Azores Standard Time' => 'Atlantic/Azores',
'(UTC-01:00) Azores' => 'Atlantic/Azores',
'Cape Verde Standard Time' => 'Atlantic/Cape_Verde',
'(UTC-01:00) Cabo Verde Is.' => 'Atlantic/Cape_Verde',
'Morocco Standard Time' => 'Africa/Casablanca',
'(UTC) Casablanca' => 'Africa/Casablanca',
'UTC' => 'Etc/GMT',
'Microsoft/Utc' => 'Etc/GMT',
'GMT Standard Time' => 'Europe/London',
'(UTC) Dublin, Edinburgh, Lisbon, London' => 'Europe/London',
'Greenwich Standard Time' => 'Atlantic/Reykjavik',
'(UTC) Monrovia, Reykjavik' => 'Atlantic/Reykjavik',
'W. Europe Standard Time' => 'Europe/Berlin',
'(UTC+01:00) Amsterdam, Berlin, Bern, Rome, Stockholm, Vienna' => 'Europe/Berlin',
'Central Europe Standard Time' => 'Europe/Budapest',
'(UTC+01:00) Belgrade, Bratislava, Budapest, Ljubljana, Prague' => 'Europe/Budapest',
'Romance Standard Time' => 'Europe/Paris',
'(UTC+01:00) Brussels, Copenhagen, Madrid, Paris' => 'Europe/Paris',
'Central European Standard Time' => 'Europe/Warsaw',
'(UTC+01:00) Sarajevo, Skopje, Warsaw, Zagreb' => 'Europe/Warsaw',
'W. Central Africa Standard Time' => 'Africa/Lagos',
'(UTC+01:00) West Central Africa' => 'Africa/Lagos',
'Namibia Standard Time' => 'Africa/Windhoek',
'(UTC+01:00) Windhoek' => 'Africa/Windhoek',
'GTB Standard Time' => 'Europe/Bucharest',
'(UTC+02:00) Athens, Bucharest' => 'Europe/Bucharest',
'Middle East Standard Time' => 'Asia/Beirut',
'(UTC+02:00) Beirut' => 'Asia/Beirut',
'Egypt Standard Time' => 'Africa/Cairo',
'(UTC+02:00) Cairo' => 'Africa/Cairo',
'Syria Standard Time' => 'Asia/Damascus',
'(UTC+02:00) Damascus' => 'Asia/Damascus',
'South Africa Standard Time' => 'Africa/Johannesburg',
'(UTC+02:00) Harare, Pretoria' => 'Africa/Johannesburg',
'FLE Standard Time' => 'Europe/Kiev',
'(UTC+02:00) Helsinki, Kyiv, Riga, Sofia, Tallinn, Vilnius' => 'Europe/Kiev',
'Turkey Standard Time' => 'Europe/Istanbul',
'(UTC+02:00) Istanbul' => 'Europe/Istanbul',
'Israel Standard Time' => 'Asia/Jerusalem',
'(UTC+02:00) Jerusalem' => 'Asia/Jerusalem',
'Libya Standard Time' => 'Africa/Tripoli',
'Jordan Standard Time' => 'Asia/Amman',
'(UTC+02:00) Amman' => 'Asia/Amman',
'Arabic Standard Time' => 'Asia/Baghdad',
'(UTC+03:00) Baghdad' => 'Asia/Baghdad',
'Kaliningrad Standard Time' => 'Europe/Kaliningrad',
'(UTC+03:00) Kaliningrad' => 'Europe/Kaliningrad',
'Arab Standard Time' => 'Asia/Riyadh',
'(UTC+03:00) Kuwait, Riyadh' => 'Asia/Riyadh',
'E. Africa Standard Time' => 'Africa/Nairobi',
'(UTC+03:00) Nairobi' => 'Africa/Nairobi',
'Iran Standard Time' => 'Asia/Tehran',
'(UTC+03:30) Tehran' => 'Asia/Tehran',
'Arabian Standard Time' => 'Asia/Dubai',
'(UTC+04:00) Abu Dhabi, Muscat' => 'Asia/Dubai',
'Azerbaijan Standard Time' => 'Asia/Baku',
'(UTC+04:00) Baku' => 'Asia/Baku',
'Russian Standard Time' => 'Europe/Moscow',
'(UTC+04:00) Moscow, St. Petersburg, Volgograd' => 'Europe/Moscow',
'Mauritius Standard Time' => 'Indian/Mauritius',
'(UTC+04:00) Port Louis' => 'Indian/Mauritius',
'Georgian Standard Time' => 'Asia/Tbilisi',
'(UTC+04:00) Tbilisi' => 'Asia/Tbilisi',
'Caucasus Standard Time' => 'Asia/Yerevan',
'(UTC+04:00) Yerevan' => 'Asia/Yerevan',
'Afghanistan Standard Time' => 'Asia/Kabul',
'(UTC+04:30) Kabul' => 'Asia/Kabul',
'West Asia Standard Time' => 'Asia/Tashkent',
'(UTC+05:00) Tashkent' => 'Asia/Tashkent',
'Pakistan Standard Time' => 'Asia/Karachi',
'(UTC+05:00) Islamabad, Karachi' => 'Asia/Karachi',
'India Standard Time' => 'Asia/Calcutta',
'(UTC+05:30) Chennai, Kolkata, Mumbai, New Delhi' => 'Asia/Calcutta',
'Sri Lanka Standard Time' => 'Asia/Colombo',
'(UTC+05:30) Sri Jayawardenepura' => 'Asia/Colombo',
'Nepal Standard Time' => 'Asia/Katmandu',
'(UTC+05:45) Kathmandu' => 'Asia/Katmandu',
'Central Asia Standard Time' => 'Asia/Almaty',
'(UTC+06:00) Astana' => 'Asia/Almaty',
'Bangladesh Standard Time' => 'Asia/Dhaka',
'(UTC+06:00) Dhaka' => 'Asia/Dhaka',
'Ekaterinburg Standard Time' => 'Asia/Yekaterinburg',
'(UTC+06:00) Ekaterinburg' => 'Asia/Yekaterinburg',
'Myanmar Standard Time' => 'Asia/Rangoon',
'(UTC+06:30) Yangon (Rangoon)' => 'Asia/Rangoon',
'SE Asia Standard Time' => 'Asia/Bangkok',
'(UTC+07:00) Bangkok, Hanoi, Jakarta' => 'Asia/Bangkok',
'N. Central Asia Standard Time' => 'Asia/Novosibirsk',
'(UTC+07:00) Novosibirsk' => 'Asia/Novosibirsk',
'China Standard Time' => 'Asia/Shanghai',
'(UTC+08:00) Beijing, Chongqing, Hong Kong, Urumqi' => 'Asia/Shanghai',
'North Asia Standard Time' => 'Asia/Krasnoyarsk',
'(UTC+08:00) Krasnoyarsk' => 'Asia/Krasnoyarsk',
'Singapore Standard Time' => 'Asia/Singapore',
'(UTC+08:00) Kuala Lumpur, Singapore' => 'Asia/Singapore',
'W. Australia Standard Time' => 'Australia/Perth',
'(UTC+08:00) Perth' => 'Australia/Perth',
'Taipei Standard Time' => 'Asia/Taipei',
'(UTC+08:00) Taipei' => 'Asia/Taipei',
'Ulaanbaatar Standard Time' => 'Asia/Ulaanbaatar',
'(UTC+08:00) Ulaanbaatar' => 'Asia/Ulaanbaatar',
'North Asia East Standard Time' => 'Asia/Irkutsk',
'(UTC+09:00) Irkutsk' => 'Asia/Irkutsk',
'Tokyo Standard Time' => 'Asia/Tokyo',
'(UTC+09:00) Osaka, Sapporo, Tokyo' => 'Asia/Tokyo',
'Korea Standard Time' => 'Asia/Seoul',
'(UTC+09:00) Seoul' => 'Asia/Seoul',
'Cen. Australia Standard Time' => 'Australia/Adelaide',
'(UTC+09:30) Adelaide' => 'Australia/Adelaide',
'AUS Central Standard Time' => 'Australia/Darwin',
'(UTC+09:30) Darwin' => 'Australia/Darwin',
'E. Australia Standard Time' => 'Australia/Brisbane',
'(UTC+10:00) Brisbane' => 'Australia/Brisbane',
'AUS Eastern Standard Time' => 'Australia/Sydney',
'(UTC+10:00) Canberra, Melbourne, Sydney' => 'Australia/Sydney',
'West Pacific Standard Time' => 'Pacific/Port_Moresby',
'(UTC+10:00) Guam, Port Moresby' => 'Pacific/Port_Moresby',
'Tasmania Standard Time' => 'Australia/Hobart',
'(UTC+10:00) Hobart' => 'Australia/Hobart',
'Yakutsk Standard Time' => 'Asia/Yakutsk',
'(UTC+10:00) Yakutsk' => 'Asia/Yakutsk',
'Central Pacific Standard Time' => 'Pacific/Guadalcanal',
'(UTC+11:00) Solomon Is., New Caledonia' => 'Pacific/Guadalcanal',
'Vladivostok Standard Time' => 'Asia/Vladivostok',
'(UTC+11:00) Vladivostok' => 'Asia/Vladivostok',
'New Zealand Standard Time' => 'Pacific/Auckland',
'(UTC+12:00) Auckland, Wellington' => 'Pacific/Auckland',
'UTC+12' => 'Etc/GMT-12',
'(UTC+12:00) Coordinated Universal Time +12' => 'Etc/GMT-12',
'Fiji Standard Time' => 'Pacific/Fiji',
'(UTC+12:00) Fiji' => 'Pacific/Fiji',
'Magadan Standard Time' => 'Asia/Magadan',
'(UTC+12:00) Magadan' => 'Asia/Magadan',
'Tonga Standard Time' => 'Pacific/Tongatapu',
'(UTC+13:00) Nuku\'alofa' => 'Pacific/Tongatapu',
'Samoa Standard Time' => 'Pacific/Apia',
'(UTC-11:00)Samoa' => 'Pacific/Apia',
];

View File

@ -0,0 +1,19 @@
<?php
/**
* @author Roman Ozana <ozana@omdesign.cz>
*/
use Tester\Assert;
use Tester\Environment;
require_once __DIR__ . '/../vendor/autoload.php';
Environment::setup();
date_default_timezone_set('Europe/Prague');
$cal = new \om\IcalParser();
$results = $cal->parseFile(__DIR__ . '/cal/blank_description.ics');
Assert::same('', $results['VEVENT'][0]['DESCRIPTION']);
Assert::same('America/Los_Angeles', $cal->timezone->getName());
Assert::same($results['DAYLIGHT'][0]['RRULE']['FREQ'], 'YEARLY');

View File

@ -0,0 +1,382 @@
BEGIN:VCALENDAR
VERSION:2.0
PRODID:-//Mozilla.org/NONSGML Mozilla Calendar V1.1//EN
BEGIN:VTIMEZONE
TZID:/mozilla.org/20070129_1/Europe/Paris
X-LIC-LOCATION:Europe/Paris
BEGIN:DAYLIGHT
TZOFFSETFROM:+0100
TZOFFSETTO:+0200
TZNAME:CEST
DTSTART:19700329T020000
RRULE:FREQ=YEARLY;INTERVAL=1;BYDAY=-1SU;BYMONTH=3
END:DAYLIGHT
BEGIN:STANDARD
TZOFFSETFROM:+0200
TZOFFSETTO:+0100
TZNAME:CET
DTSTART:19701025T030000
RRULE:FREQ=YEARLY;INTERVAL=1;BYDAY=-1SU;BYMONTH=10
END:STANDARD
END:VTIMEZONE
BEGIN:VEVENT
CREATED:20070606T141629Z
LAST-MODIFIED:20070606T154611Z
DTSTAMP:20070607T120859Z
UID:5d1ae55f-3910-4de9-8b65-d652768fb2f2
SUMMARY:Lundi de Pâques
DTSTART;VALUE=DATE;TZID=/mozilla.org/20070129_1/Europe/Paris:20070409
DTEND;VALUE=DATE;TZID=/mozilla.org/20070129_1/Europe/Paris:20070410
CATEGORIES:Jours fériés
END:VEVENT
BEGIN:VEVENT
CREATED:20070606T161310Z
LAST-MODIFIED:20070606T161327Z
DTSTAMP:20070607T120859Z
UID:9e19b119-f077-4ae9-934e-cb62322ca81f
SUMMARY:Ascension
DTSTART;VALUE=DATE;TZID=/mozilla.org/20070129_1/Europe/Paris:20080501
DTEND;VALUE=DATE;TZID=/mozilla.org/20070129_1/Europe/Paris:20080502
CATEGORIES:Jours fériés
END:VEVENT
BEGIN:VEVENT
CREATED:20070605T163903Z
LAST-MODIFIED:20070606T161656Z
DTSTAMP:20070607T120859Z
UID:c6a930d6-4ed5-45d8-bb3d-d3587a32b8aa
SUMMARY:Jour de l'an
CLASS:PUBLIC
RRULE:FREQ=YEARLY;INTERVAL=1
DTSTART;VALUE=DATE;TZID=/mozilla.org/20070129_1/Europe/Paris:20070101
DTEND;VALUE=DATE;TZID=/mozilla.org/20070129_1/Europe/Paris:20070102
CATEGORIES:Jours fériés
END:VEVENT
BEGIN:VEVENT
CREATED:20070606T141739Z
LAST-MODIFIED:20070606T161721Z
DTSTAMP:20070607T120859Z
UID:f439c81b-fd09-4b40-a629-3a9663dd29ff
SUMMARY:Fête du Travail
CLASS:PUBLIC
RRULE:FREQ=YEARLY;INTERVAL=1
DTSTART;VALUE=DATE;TZID=/mozilla.org/20070129_1/Europe/Paris:20070501
DTEND;VALUE=DATE;TZID=/mozilla.org/20070129_1/Europe/Paris:20070502
CATEGORIES:Jours fériés
END:VEVENT
BEGIN:VEVENT
CREATED:20070606T141853Z
LAST-MODIFIED:20070606T161731Z
DTSTAMP:20070607T120859Z
UID:b1c0e1ed-a09f-4fc2-aab1-170d3f661f13
SUMMARY:Armistice 1945
RRULE:FREQ=YEARLY;INTERVAL=1
DTSTART;VALUE=DATE;TZID=/mozilla.org/20070129_1/Europe/Paris:20070508
DTEND;VALUE=DATE;TZID=/mozilla.org/20070129_1/Europe/Paris:20070509
CATEGORIES:Jours fériés
END:VEVENT
BEGIN:VEVENT
CREATED:20070606T141932Z
LAST-MODIFIED:20070606T161741Z
DTSTAMP:20070607T120859Z
UID:5468e1a0-9dda-4fd2-88c0-dc3e727c1183
SUMMARY:Ascension
DTSTART;VALUE=DATE;TZID=/mozilla.org/20070129_1/Europe/Paris:20070517
DTEND;VALUE=DATE;TZID=/mozilla.org/20070129_1/Europe/Paris:20070518
CATEGORIES:Jours fériés
END:VEVENT
BEGIN:VEVENT
CREATED:20070606T154927Z
LAST-MODIFIED:20070606T161748Z
DTSTAMP:20070607T120859Z
UID:67a89bb6-9ad4-461b-951c-c4c8482d8618
SUMMARY:Lundi de Pentecôte
DTSTART;VALUE=DATE;TZID=/mozilla.org/20070129_1/Europe/Paris:20070528
DTEND;VALUE=DATE;TZID=/mozilla.org/20070129_1/Europe/Paris:20070529
CATEGORIES:Jours fériés
END:VEVENT
BEGIN:VEVENT
CREATED:20070606T142033Z
LAST-MODIFIED:20070606T161758Z
DTSTAMP:20070607T120859Z
UID:00eb3adc-c059-47c8-a1c0-4ca7048051b9
SUMMARY:Fête Nationale
RRULE:FREQ=YEARLY;INTERVAL=1
DTSTART;VALUE=DATE;TZID=/mozilla.org/20070129_1/Europe/Paris:20070714
DTEND;VALUE=DATE;TZID=/mozilla.org/20070129_1/Europe/Paris:20070715
CATEGORIES:Jours fériés
END:VEVENT
BEGIN:VEVENT
CREATED:20070606T142112Z
LAST-MODIFIED:20070606T162012Z
DTSTAMP:20070607T120859Z
UID:854e5499-9276-4a96-9be3-bcbaa7caafcf
SUMMARY:Assomption
RRULE:FREQ=YEARLY;INTERVAL=1
DTSTART;VALUE=DATE;TZID=/mozilla.org/20070129_1/Europe/Paris:20070815
DTEND;VALUE=DATE;TZID=/mozilla.org/20070129_1/Europe/Paris:20070816
CATEGORIES:Jours fériés
END:VEVENT
BEGIN:VEVENT
CREATED:20070606T142147Z
LAST-MODIFIED:20070606T162034Z
DTSTAMP:20070607T120859Z
UID:725c8c16-c37a-49f0-9d2e-dc976d6c3ea5
SUMMARY:Toussaint
RRULE:FREQ=YEARLY;INTERVAL=1
DTSTART;VALUE=DATE;TZID=/mozilla.org/20070129_1/Europe/Paris:20071101
DTEND;VALUE=DATE;TZID=/mozilla.org/20070129_1/Europe/Paris:20071102
CATEGORIES:Jours fériés
END:VEVENT
BEGIN:VEVENT
CREATED:20070606T142211Z
LAST-MODIFIED:20070606T162044Z
DTSTAMP:20070607T120859Z
UID:5218f724-6b66-434d-a8c5-138dfed64e07
SUMMARY:Armistice 1918
RRULE:FREQ=YEARLY;INTERVAL=1
DTSTART;VALUE=DATE;TZID=/mozilla.org/20070129_1/Europe/Paris:20071111
DTEND;VALUE=DATE;TZID=/mozilla.org/20070129_1/Europe/Paris:20071112
CATEGORIES:Jours fériés
END:VEVENT
BEGIN:VEVENT
CREATED:20070606T142243Z
LAST-MODIFIED:20070606T162054Z
DTSTAMP:20070607T120859Z
UID:18617cde-2d15-46c6-900f-b3341a7b7f98
SUMMARY:Noël
RRULE:FREQ=YEARLY;INTERVAL=1
DTSTART;VALUE=DATE;TZID=/mozilla.org/20070129_1/Europe/Paris:20071225
DTEND;VALUE=DATE;TZID=/mozilla.org/20070129_1/Europe/Paris:20071226
CATEGORIES:Jours fériés
END:VEVENT
BEGIN:VEVENT
CREATED:20070606T150648Z
LAST-MODIFIED:20070606T162128Z
DTSTAMP:20070607T120859Z
UID:19d50a52-f5a9-4d70-8fd7-a2caa97f6959
SUMMARY:Lundi de Pâques
DTSTART;VALUE=DATE;TZID=/mozilla.org/20070129_1/Europe/Paris:20080324
DTEND;VALUE=DATE;TZID=/mozilla.org/20070129_1/Europe/Paris:20080325
CATEGORIES:Jours fériés
END:VEVENT
BEGIN:VEVENT
CREATED:20070607T105427Z
LAST-MODIFIED:20070607T105450Z
DTSTAMP:20070607T120859Z
UID:18c90b99-edfa-4418-9bc7-992a07384967
SUMMARY:Lundi de Pâques
DTSTART;VALUE=DATE;TZID=/mozilla.org/20070129_1/Europe/Paris:20090413
DTEND;VALUE=DATE;TZID=/mozilla.org/20070129_1/Europe/Paris:20090414
CATEGORIES:Jours fériés
END:VEVENT
BEGIN:VEVENT
CREATED:20070607T105613Z
LAST-MODIFIED:20070607T105630Z
DTSTAMP:20070607T120859Z
UID:b989d129-8f2f-42be-a027-183f6d81eb40
SUMMARY:Ascension
DTSTART;VALUE=DATE;TZID=/mozilla.org/20070129_1/Europe/Paris:20090521
DTEND;VALUE=DATE;TZID=/mozilla.org/20070129_1/Europe/Paris:20090522
CATEGORIES:Jours fériés
END:VEVENT
BEGIN:VEVENT
CREATED:20070607T105907Z
LAST-MODIFIED:20070607T105928Z
DTSTAMP:20070607T120859Z
UID:7c6fe35c-44a5-450b-aea6-dd2baef78f06
SUMMARY:Lundi de Pentecôte
DTSTART;VALUE=DATE;TZID=/mozilla.org/20070129_1/Europe/Paris:20090601
DTEND;VALUE=DATE;TZID=/mozilla.org/20070129_1/Europe/Paris:20090602
CATEGORIES:Jours fériés
END:VEVENT
BEGIN:VEVENT
CREATED:20070607T110046Z
LAST-MODIFIED:20070607T110100Z
DTSTAMP:20070607T120859Z
UID:98c1c381-8632-45ce-9b11-10757face7c4
SUMMARY:Lundi de Pâques
DTSTART;VALUE=DATE;TZID=/mozilla.org/20070129_1/Europe/Paris:20100405
DTEND;VALUE=DATE;TZID=/mozilla.org/20070129_1/Europe/Paris:20100406
CATEGORIES:Jours fériés
END:VEVENT
BEGIN:VEVENT
CREATED:20070607T110121Z
LAST-MODIFIED:20070607T110135Z
DTSTAMP:20070607T120859Z
UID:aaeb1ba5-60f0-4e49-a25a-c0ff949acdd9
SUMMARY:Ascension
DTSTART;VALUE=DATE;TZID=/mozilla.org/20070129_1/Europe/Paris:20100513
DTEND;VALUE=DATE;TZID=/mozilla.org/20070129_1/Europe/Paris:20100514
CATEGORIES:Jours fériés
END:VEVENT
BEGIN:VEVENT
CREATED:20070607T110144Z
LAST-MODIFIED:20070607T110201Z
DTSTAMP:20070607T120859Z
UID:1f68f978-969e-4791-a7e3-cb3011134a34
SUMMARY:Lundi de Pentecôte
DTSTART;VALUE=DATE;TZID=/mozilla.org/20070129_1/Europe/Paris:20100524
DTEND;VALUE=DATE;TZID=/mozilla.org/20070129_1/Europe/Paris:20100525
CATEGORIES:Jours fériés
END:VEVENT
BEGIN:VEVENT
CREATED:20070607T112820Z
LAST-MODIFIED:20070607T112836Z
DTSTAMP:20070607T120859Z
UID:fa0d4b5b-8eeb-4b98-b35c-b6a547b96953
SUMMARY:Ascension
DTSTART;VALUE=DATE;TZID=/mozilla.org/20070129_1/Europe/Paris:20110602
DTEND;VALUE=DATE;TZID=/mozilla.org/20070129_1/Europe/Paris:20110603
CATEGORIES:Jours fériés
END:VEVENT
BEGIN:VEVENT
CREATED:20070607T112846Z
LAST-MODIFIED:20070607T112906Z
DTSTAMP:20070607T120859Z
UID:5be6194a-9fbd-45da-8e3c-568cac66b997
SUMMARY:Lundi de Pentecôte
DTSTART;VALUE=DATE;TZID=/mozilla.org/20070129_1/Europe/Paris:20110613
DTEND;VALUE=DATE;TZID=/mozilla.org/20070129_1/Europe/Paris:20110614
CATEGORIES:Jours fériés
END:VEVENT
BEGIN:VEVENT
CREATED:20070607T112958Z
LAST-MODIFIED:20070607T113016Z
DTSTAMP:20070607T120859Z
UID:4162d242-5468-4007-8814-10286b9589a0
SUMMARY:Lundi de Pâques
DTSTART;VALUE=DATE;TZID=/mozilla.org/20070129_1/Europe/Paris:20120409
DTEND;VALUE=DATE;TZID=/mozilla.org/20070129_1/Europe/Paris:20120410
CATEGORIES:Jours fériés
END:VEVENT
BEGIN:VEVENT
CREATED:20070607T113034Z
LAST-MODIFIED:20070607T113048Z
DTSTAMP:20070607T120859Z
UID:6d368a35-6b6d-4ec1-9f48-97c53b25502e
SUMMARY:Ascension
DTSTART;VALUE=DATE;TZID=/mozilla.org/20070129_1/Europe/Paris:20120517
DTEND;VALUE=DATE;TZID=/mozilla.org/20070129_1/Europe/Paris:20120518
CATEGORIES:Jours fériés
END:VEVENT
BEGIN:VEVENT
CREATED:20070607T113055Z
LAST-MODIFIED:20070607T113114Z
DTSTAMP:20070607T120859Z
UID:e8913a3d-3e84-447d-afb4-f0b082948449
SUMMARY:Lundi de Pentecôte
DTSTART;VALUE=DATE;TZID=/mozilla.org/20070129_1/Europe/Paris:20120528
DTEND;VALUE=DATE;TZID=/mozilla.org/20070129_1/Europe/Paris:20120529
CATEGORIES:Jours fériés
END:VEVENT
BEGIN:VEVENT
CREATED:20070607T113205Z
LAST-MODIFIED:20070607T113229Z
DTSTAMP:20070607T120859Z
UID:ebc79872-a185-4641-bc22-1092d5139efb
SUMMARY:Lundi de Pâques
DTSTART;VALUE=DATE;TZID=/mozilla.org/20070129_1/Europe/Paris:20130401
DTEND;VALUE=DATE;TZID=/mozilla.org/20070129_1/Europe/Paris:20130402
CATEGORIES:Jours fériés
END:VEVENT
BEGIN:VEVENT
CREATED:20070607T113245Z
LAST-MODIFIED:20070607T113257Z
DTSTAMP:20070607T120859Z
UID:9714bd39-429b-433c-ab5c-5fd6a67e658e
SUMMARY:Ascension
DTSTART;VALUE=DATE;TZID=/mozilla.org/20070129_1/Europe/Paris:20130509
DTEND;VALUE=DATE;TZID=/mozilla.org/20070129_1/Europe/Paris:20130510
CATEGORIES:Jours fériés
END:VEVENT
BEGIN:VEVENT
CREATED:20070607T113305Z
LAST-MODIFIED:20070607T113325Z
DTSTAMP:20070607T120859Z
UID:79f5f02f-e92d-417f-9637-9e2a88840583
SUMMARY:Lundi de Pentecôte
DTSTART;VALUE=DATE;TZID=/mozilla.org/20070129_1/Europe/Paris:20130520
DTEND;VALUE=DATE;TZID=/mozilla.org/20070129_1/Europe/Paris:20130521
CATEGORIES:Jours fériés
END:VEVENT
BEGIN:VEVENT
CREATED:20070607T113408Z
LAST-MODIFIED:20070607T113426Z
DTSTAMP:20070607T120859Z
UID:172dcce6-6f95-4c1f-ada9-e8bf2a7e8245
SUMMARY:Lundi de Pâques
DTSTART;VALUE=DATE;TZID=/mozilla.org/20070129_1/Europe/Paris:20140421
DTEND;VALUE=DATE;TZID=/mozilla.org/20070129_1/Europe/Paris:20140422
CATEGORIES:Jours fériés
END:VEVENT
BEGIN:VEVENT
CREATED:20070607T113439Z
LAST-MODIFIED:20070607T113452Z
DTSTAMP:20070607T120859Z
UID:6625ed89-bf9f-478a-9796-c3dc203ab5e6
SUMMARY:Ascension
DTSTART;VALUE=DATE;TZID=/mozilla.org/20070129_1/Europe/Paris:20140529
DTEND;VALUE=DATE;TZID=/mozilla.org/20070129_1/Europe/Paris:20140530
CATEGORIES:Jours fériés
END:VEVENT
BEGIN:VEVENT
CREATED:20070607T113504Z
LAST-MODIFIED:20070607T113523Z
DTSTAMP:20070607T120859Z
UID:7abad826-ab68-447f-81b2-1e04a4c2ef88
SUMMARY:Lundi de Pentecôte
DTSTART;VALUE=DATE;TZID=/mozilla.org/20070129_1/Europe/Paris:20140609
DTEND;VALUE=DATE;TZID=/mozilla.org/20070129_1/Europe/Paris:20140610
CATEGORIES:Jours fériés
END:VEVENT
BEGIN:VEVENT
CREATED:20070607T113606Z
LAST-MODIFIED:20070607T113622Z
DTSTAMP:20070607T120859Z
UID:cf42813f-4a74-422b-aa19-90dcefccc92d
SUMMARY:Lundi de Pâques
DTSTART;VALUE=DATE;TZID=/mozilla.org/20070129_1/Europe/Paris:20150406
DTEND;VALUE=DATE;TZID=/mozilla.org/20070129_1/Europe/Paris:20150407
CATEGORIES:Jours fériés
END:VEVENT
BEGIN:VEVENT
CREATED:20070607T113643Z
LAST-MODIFIED:20070607T113657Z
DTSTAMP:20070607T120859Z
UID:e7d30f2b-d546-4b7e-8780-0754a46e6970
SUMMARY:Ascension
DTSTART;VALUE=DATE;TZID=/mozilla.org/20070129_1/Europe/Paris:20150514
DTEND;VALUE=DATE;TZID=/mozilla.org/20070129_1/Europe/Paris:20150515
CATEGORIES:Jours fériés
END:VEVENT
BEGIN:VEVENT
CREATED:20070607T113706Z
LAST-MODIFIED:20070607T113726Z
DTSTAMP:20070607T120859Z
UID:a8ccc771-4e8b-4594-ae30-33e9ce384ac9
SUMMARY:Lundi de Pentecôte
DTSTART;VALUE=DATE;TZID=/mozilla.org/20070129_1/Europe/Paris:20150525
DTEND;VALUE=DATE;TZID=/mozilla.org/20070129_1/Europe/Paris:20150526
CATEGORIES:Jours fériés
END:VEVENT
BEGIN:VEVENT
CREATED:20070606T162350Z
LAST-MODIFIED:20070607T115133Z
DTSTAMP:20070607T120859Z
UID:419f1bff-a820-4d07-bf4e-1a6ec139e3df
SUMMARY:Lundi de Pentecôte
DTSTART;VALUE=DATE;TZID=/mozilla.org/20070129_1/Europe/Paris:20080512
DTEND;VALUE=DATE;TZID=/mozilla.org/20070129_1/Europe/Paris:20080513
CATEGORIES:Jours fériés
END:VEVENT
BEGIN:VEVENT
CREATED:20070607T112742Z
LAST-MODIFIED:20070607T115439Z
DTSTAMP:20070607T120859Z
UID:570d9fe7-cdc9-4fdf-9794-909edf520383
SUMMARY:Lundi de Pâques
DTSTART;VALUE=DATE;TZID=/mozilla.org/20070129_1/Europe/Paris:20110425
DTEND;VALUE=DATE;TZID=/mozilla.org/20070129_1/Europe/Paris:20110426
CATEGORIES:Jours fériés
END:VEVENT
END:VCALENDAR

View File

@ -0,0 +1,616 @@
BEGIN:VCALENDAR
PRODID:-//Google Inc//Google Calendar 70.9054//EN
VERSION:2.0
CALSCALE:GREGORIAN
METHOD:PUBLISH
X-WR-TIMEZONE:UTC
X-WR-CALDESC:České svátky
BEGIN:VEVENT
DTSTART;VALUE=DATE:20131224
DTEND;VALUE=DATE:20131225
DTSTAMP:20140202T201100Z
UID:h@9bae7e86083abdfdff45712c19ef81bc41f44111@google.com
ATTENDEE;CUTYPE=INDIVIDUAL;ROLE=REQ-PARTICIPANT;PARTSTAT=ACCEPTED;X-NUM-GUE
STS=0:mailto:cdpisorqclhmg8r8dtm6ip31f506esjfelo2sthecdgmopbechgn4bj7dtnmer
355phmur8%40virtual
CLASS:PUBLIC
CREATED:20140202T183416Z
LAST-MODIFIED:20140202T183416Z
SEQUENCE:1
STATUS:CONFIRMED
SUMMARY:Štedrý den
TRANSP:OPAQUE
END:VEVENT
BEGIN:VEVENT
DTSTART;VALUE=DATE:20141224
DTEND;VALUE=DATE:20141225
DTSTAMP:20140202T201100Z
UID:h@26c4829203feb7deebebdf226285322a079b9b7c@google.com
ATTENDEE;CUTYPE=INDIVIDUAL;ROLE=REQ-PARTICIPANT;PARTSTAT=ACCEPTED;X-NUM-GUE
STS=0:mailto:cdpisorqclhmg8r8dtm6ip31f506esjfelo2sthecdgmopbechgn4bj7dtnmer
355phmur8%40virtual
CLASS:PUBLIC
CREATED:20140202T183416Z
LAST-MODIFIED:20140202T183416Z
SEQUENCE:1
STATUS:CONFIRMED
SUMMARY:Štedrý den
TRANSP:OPAQUE
END:VEVENT
BEGIN:VEVENT
DTSTART;VALUE=DATE:20151224
DTEND;VALUE=DATE:20151225
DTSTAMP:20140202T201100Z
UID:h@1c3d67eb7865010f0ee809055f7c465124091d1b@google.com
ATTENDEE;CUTYPE=INDIVIDUAL;ROLE=REQ-PARTICIPANT;PARTSTAT=ACCEPTED;X-NUM-GUE
STS=0:mailto:cdpisorqclhmg8r8dtm6ip31f506esjfelo2sthecdgmopbechgn4bj7dtnmer
355phmur8%40virtual
CLASS:PUBLIC
CREATED:20140202T183416Z
LAST-MODIFIED:20140202T183416Z
SEQUENCE:1
STATUS:CONFIRMED
SUMMARY:Štedrý den
TRANSP:OPAQUE
END:VEVENT
BEGIN:VEVENT
DTSTART;VALUE=DATE:20150406
DTEND;VALUE=DATE:20150407
DTSTAMP:20140202T201100Z
UID:h@e5a21162ed9d250ee5f689058366a09f10cf4ccb@google.com
ATTENDEE;CUTYPE=INDIVIDUAL;ROLE=REQ-PARTICIPANT;PARTSTAT=ACCEPTED;X-NUM-GUE
STS=0:mailto:cdpisorqclhmg8r8dtm6ip31f506esjfelo2sthecdgmopbechgn4bj7dtnmer
355phmur8%40virtual
CLASS:PUBLIC
CREATED:20140202T183416Z
LAST-MODIFIED:20140202T183416Z
SEQUENCE:1
STATUS:CONFIRMED
SUMMARY:Velikonoční pondělí
TRANSP:OPAQUE
END:VEVENT
BEGIN:VEVENT
DTSTART;VALUE=DATE:20140421
DTEND;VALUE=DATE:20140422
DTSTAMP:20140202T201100Z
UID:h@9595a34a188b5376d452c829499a8f8354ec6049@google.com
ATTENDEE;CUTYPE=INDIVIDUAL;ROLE=REQ-PARTICIPANT;PARTSTAT=ACCEPTED;X-NUM-GUE
STS=0:mailto:cdpisorqclhmg8r8dtm6ip31f506esjfelo2sthecdgmopbechgn4bj7dtnmer
355phmur8%40virtual
CLASS:PUBLIC
CREATED:20140202T183416Z
LAST-MODIFIED:20140202T183416Z
SEQUENCE:1
STATUS:CONFIRMED
SUMMARY:Velikonoční pondělí
TRANSP:OPAQUE
END:VEVENT
BEGIN:VEVENT
DTSTART;VALUE=DATE:20150501
DTEND;VALUE=DATE:20150502
DTSTAMP:20140202T201100Z
UID:h@7470a1d77684e63d5aa048babb939885ad1066c5@google.com
ATTENDEE;CUTYPE=INDIVIDUAL;ROLE=REQ-PARTICIPANT;PARTSTAT=ACCEPTED;X-NUM-GUE
STS=0:mailto:cdpisorqclhmg8r8dtm6ip31f506esjfelo2sthecdgmopbechgn4bj7dtnmer
355phmur8%40virtual
CLASS:PUBLIC
CREATED:20140202T183416Z
LAST-MODIFIED:20140202T183416Z
SEQUENCE:1
STATUS:CONFIRMED
SUMMARY:Svátek práce
TRANSP:OPAQUE
END:VEVENT
BEGIN:VEVENT
DTSTART;VALUE=DATE:20140501
DTEND;VALUE=DATE:20140502
DTSTAMP:20140202T201100Z
UID:h@59ea753d474913d8c7ab474eaba701f8ec5c2ba1@google.com
ATTENDEE;CUTYPE=INDIVIDUAL;ROLE=REQ-PARTICIPANT;PARTSTAT=ACCEPTED;X-NUM-GUE
STS=0:mailto:cdpisorqclhmg8r8dtm6ip31f506esjfelo2sthecdgmopbechgn4bj7dtnmer
355phmur8%40virtual
CLASS:PUBLIC
CREATED:20140202T183416Z
LAST-MODIFIED:20140202T183416Z
SEQUENCE:1
STATUS:CONFIRMED
SUMMARY:Svátek práce
TRANSP:OPAQUE
END:VEVENT
BEGIN:VEVENT
DTSTART;VALUE=DATE:20130501
DTEND;VALUE=DATE:20130502
DTSTAMP:20140202T201100Z
UID:h@19480e43102b11f061a7fc231692a6504e6f55de@google.com
ATTENDEE;CUTYPE=INDIVIDUAL;ROLE=REQ-PARTICIPANT;PARTSTAT=ACCEPTED;X-NUM-GUE
STS=0:mailto:cdpisorqclhmg8r8dtm6ip31f506esjfelo2sthecdgmopbechgn4bj7dtnmer
355phmur8%40virtual
CLASS:PUBLIC
CREATED:20140202T183416Z
LAST-MODIFIED:20140202T183416Z
SEQUENCE:1
STATUS:CONFIRMED
SUMMARY:Svátek práce
TRANSP:OPAQUE
END:VEVENT
BEGIN:VEVENT
DTSTART;VALUE=DATE:20140101
DTEND;VALUE=DATE:20140102
DTSTAMP:20140202T201100Z
UID:h@cdcc3450b77b919b7e5c1d0186439b81fe315723@google.com
ATTENDEE;CUTYPE=INDIVIDUAL;ROLE=REQ-PARTICIPANT;PARTSTAT=ACCEPTED;X-NUM-GUE
STS=0:mailto:cdpisorqclhmg8r8dtm6ip31f506esjfelo2sthecdgmopbechgn4bj7dtnmer
355phmur8%40virtual
CLASS:PUBLIC
CREATED:20140202T183416Z
LAST-MODIFIED:20140202T183416Z
SEQUENCE:1
STATUS:CONFIRMED
SUMMARY:Nový rok
TRANSP:OPAQUE
END:VEVENT
BEGIN:VEVENT
DTSTART;VALUE=DATE:20130101
DTEND;VALUE=DATE:20130102
DTSTAMP:20140202T201100Z
UID:h@93d93af5add7e8e8542f9d2be9bf9b189adc7088@google.com
ATTENDEE;CUTYPE=INDIVIDUAL;ROLE=REQ-PARTICIPANT;PARTSTAT=ACCEPTED;X-NUM-GUE
STS=0:mailto:cdpisorqclhmg8r8dtm6ip31f506esjfelo2sthecdgmopbechgn4bj7dtnmer
355phmur8%40virtual
CLASS:PUBLIC
CREATED:20140202T183416Z
LAST-MODIFIED:20140202T183416Z
SEQUENCE:1
STATUS:CONFIRMED
SUMMARY:Nový rok
TRANSP:OPAQUE
END:VEVENT
BEGIN:VEVENT
DTSTART;VALUE=DATE:20150101
DTEND;VALUE=DATE:20150102
DTSTAMP:20140202T201100Z
UID:h@3be21c366071b22c3322e48e898803d89a2873c8@google.com
ATTENDEE;CUTYPE=INDIVIDUAL;ROLE=REQ-PARTICIPANT;PARTSTAT=ACCEPTED;X-NUM-GUE
STS=0:mailto:cdpisorqclhmg8r8dtm6ip31f506esjfelo2sthecdgmopbechgn4bj7dtnmer
355phmur8%40virtual
CLASS:PUBLIC
CREATED:20140202T183416Z
LAST-MODIFIED:20140202T183416Z
SEQUENCE:1
STATUS:CONFIRMED
SUMMARY:Nový rok
TRANSP:OPAQUE
END:VEVENT
BEGIN:VEVENT
DTSTART;VALUE=DATE:20140928
DTEND;VALUE=DATE:20140929
DTSTAMP:20140202T201100Z
UID:h@910a92f331886c719cdab7cae0f8d56387788789@google.com
ATTENDEE;CUTYPE=INDIVIDUAL;ROLE=REQ-PARTICIPANT;PARTSTAT=ACCEPTED;X-NUM-GUE
STS=0:mailto:cdpisorqclhmg8r8dtm6ip31f506esjfelo2sthecdgmopbechgn4bj7dtnmer
355phmur8%40virtual
CLASS:PUBLIC
CREATED:20140202T183416Z
LAST-MODIFIED:20140202T183416Z
SEQUENCE:1
STATUS:CONFIRMED
SUMMARY:Den české státnosti
TRANSP:OPAQUE
END:VEVENT
BEGIN:VEVENT
DTSTART;VALUE=DATE:20130928
DTEND;VALUE=DATE:20130929
DTSTAMP:20140202T201100Z
UID:h@4bdee7defc8620b327b23400a9da3be5d0721a10@google.com
ATTENDEE;CUTYPE=INDIVIDUAL;ROLE=REQ-PARTICIPANT;PARTSTAT=ACCEPTED;X-NUM-GUE
STS=0:mailto:cdpisorqclhmg8r8dtm6ip31f506esjfelo2sthecdgmopbechgn4bj7dtnmer
355phmur8%40virtual
CLASS:PUBLIC
CREATED:20140202T183416Z
LAST-MODIFIED:20140202T183416Z
SEQUENCE:1
STATUS:CONFIRMED
SUMMARY:Den české státnosti
TRANSP:OPAQUE
END:VEVENT
BEGIN:VEVENT
DTSTART;VALUE=DATE:20150928
DTEND;VALUE=DATE:20150929
DTSTAMP:20140202T201100Z
UID:h@0534aebb7a00356b125529a447b38be655046ca9@google.com
ATTENDEE;CUTYPE=INDIVIDUAL;ROLE=REQ-PARTICIPANT;PARTSTAT=ACCEPTED;X-NUM-GUE
STS=0:mailto:cdpisorqclhmg8r8dtm6ip31f506esjfelo2sthecdgmopbechgn4bj7dtnmer
355phmur8%40virtual
CLASS:PUBLIC
CREATED:20140202T183416Z
LAST-MODIFIED:20140202T183416Z
SEQUENCE:1
STATUS:CONFIRMED
SUMMARY:Den české státnosti
TRANSP:OPAQUE
END:VEVENT
BEGIN:VEVENT
DTSTART;VALUE=DATE:20150508
DTEND;VALUE=DATE:20150509
DTSTAMP:20140202T201100Z
UID:h@f234114d721bac5776f1683f23a58ed2ffd53c84@google.com
ATTENDEE;CUTYPE=INDIVIDUAL;ROLE=REQ-PARTICIPANT;PARTSTAT=ACCEPTED;X-NUM-GUE
STS=0:mailto:cdpisorqclhmg8r8dtm6ip31f506esjfelo2sthecdgmopbechgn4bj7dtnmer
355phmur8%40virtual
CLASS:PUBLIC
CREATED:20140202T183416Z
LAST-MODIFIED:20140202T183416Z
SEQUENCE:1
STATUS:CONFIRMED
SUMMARY:Den vítězství
TRANSP:OPAQUE
END:VEVENT
BEGIN:VEVENT
DTSTART;VALUE=DATE:20130508
DTEND;VALUE=DATE:20130509
DTSTAMP:20140202T201100Z
UID:h@5b971aece3bf450de53261bafe25898080af2454@google.com
ATTENDEE;CUTYPE=INDIVIDUAL;ROLE=REQ-PARTICIPANT;PARTSTAT=ACCEPTED;X-NUM-GUE
STS=0:mailto:cdpisorqclhmg8r8dtm6ip31f506esjfelo2sthecdgmopbechgn4bj7dtnmer
355phmur8%40virtual
CLASS:PUBLIC
CREATED:20140202T183416Z
LAST-MODIFIED:20140202T183416Z
SEQUENCE:1
STATUS:CONFIRMED
SUMMARY:Den vítězství
TRANSP:OPAQUE
END:VEVENT
BEGIN:VEVENT
DTSTART;VALUE=DATE:20140508
DTEND;VALUE=DATE:20140509
DTSTAMP:20140202T201100Z
UID:h@574f6e8b741d1eb0e80ed4caea1441858393ff58@google.com
ATTENDEE;CUTYPE=INDIVIDUAL;ROLE=REQ-PARTICIPANT;PARTSTAT=ACCEPTED;X-NUM-GUE
STS=0:mailto:cdpisorqclhmg8r8dtm6ip31f506esjfelo2sthecdgmopbechgn4bj7dtnmer
355phmur8%40virtual
CLASS:PUBLIC
CREATED:20140202T183416Z
LAST-MODIFIED:20140202T183416Z
SEQUENCE:1
STATUS:CONFIRMED
SUMMARY:Den vítězství
TRANSP:OPAQUE
END:VEVENT
BEGIN:VEVENT
DTSTART;VALUE=DATE:20131028
DTEND;VALUE=DATE:20131029
DTSTAMP:20140202T201100Z
UID:h@be894303693f374fad9017da7ac6391c23eca0f6@google.com
ATTENDEE;CUTYPE=INDIVIDUAL;ROLE=REQ-PARTICIPANT;PARTSTAT=ACCEPTED;X-NUM-GUE
STS=0:mailto:cdpisorqclhmg8r8dtm6ip31f506esjfelo2sthecdgmopbechgn4bj7dtnmer
355phmur8%40virtual
CLASS:PUBLIC
CREATED:20140202T183416Z
LAST-MODIFIED:20140202T183416Z
SEQUENCE:1
STATUS:CONFIRMED
SUMMARY:Den vzniku samostatného československého státu
TRANSP:OPAQUE
END:VEVENT
BEGIN:VEVENT
DTSTART;VALUE=DATE:20151028
DTEND;VALUE=DATE:20151029
DTSTAMP:20140202T201100Z
UID:h@7e708d1f45342cd36f819e1f0d3d9f9b7eacc02f@google.com
ATTENDEE;CUTYPE=INDIVIDUAL;ROLE=REQ-PARTICIPANT;PARTSTAT=ACCEPTED;X-NUM-GUE
STS=0:mailto:cdpisorqclhmg8r8dtm6ip31f506esjfelo2sthecdgmopbechgn4bj7dtnmer
355phmur8%40virtual
CLASS:PUBLIC
CREATED:20140202T183416Z
LAST-MODIFIED:20140202T183416Z
SEQUENCE:1
STATUS:CONFIRMED
SUMMARY:Den vzniku samostatného československého státu
TRANSP:OPAQUE
END:VEVENT
BEGIN:VEVENT
DTSTART;VALUE=DATE:20141028
DTEND;VALUE=DATE:20141029
DTSTAMP:20140202T201100Z
UID:h@4dcdf85aaa09aea21fd49914085b47cdb44ccf0f@google.com
ATTENDEE;CUTYPE=INDIVIDUAL;ROLE=REQ-PARTICIPANT;PARTSTAT=ACCEPTED;X-NUM-GUE
STS=0:mailto:cdpisorqclhmg8r8dtm6ip31f506esjfelo2sthecdgmopbechgn4bj7dtnmer
355phmur8%40virtual
CLASS:PUBLIC
CREATED:20140202T183416Z
LAST-MODIFIED:20140202T183416Z
SEQUENCE:1
STATUS:CONFIRMED
SUMMARY:Den vzniku samostatného československého státu
TRANSP:OPAQUE
END:VEVENT
BEGIN:VEVENT
DTSTART;VALUE=DATE:20150706
DTEND;VALUE=DATE:20150707
DTSTAMP:20140202T201100Z
UID:h@d2253851fcafd5063bdbece5367507e338b5eea0@google.com
ATTENDEE;CUTYPE=INDIVIDUAL;ROLE=REQ-PARTICIPANT;PARTSTAT=ACCEPTED;X-NUM-GUE
STS=0:mailto:cdpisorqclhmg8r8dtm6ip31f506esjfelo2sthecdgmopbechgn4bj7dtnmer
355phmur8%40virtual
CLASS:PUBLIC
CREATED:20140202T183416Z
LAST-MODIFIED:20140202T183416Z
SEQUENCE:1
STATUS:CONFIRMED
SUMMARY:Den upálení mistra Jana Husa
TRANSP:OPAQUE
END:VEVENT
BEGIN:VEVENT
DTSTART;VALUE=DATE:20140706
DTEND;VALUE=DATE:20140707
DTSTAMP:20140202T201100Z
UID:h@2f980e6bc7f0445430367c33d3e4a27441196199@google.com
ATTENDEE;CUTYPE=INDIVIDUAL;ROLE=REQ-PARTICIPANT;PARTSTAT=ACCEPTED;X-NUM-GUE
STS=0:mailto:cdpisorqclhmg8r8dtm6ip31f506esjfelo2sthecdgmopbechgn4bj7dtnmer
355phmur8%40virtual
CLASS:PUBLIC
CREATED:20140202T183416Z
LAST-MODIFIED:20140202T183416Z
SEQUENCE:1
STATUS:CONFIRMED
SUMMARY:Den upálení mistra Jana Husa
TRANSP:OPAQUE
END:VEVENT
BEGIN:VEVENT
DTSTART;VALUE=DATE:20130706
DTEND;VALUE=DATE:20130707
DTSTAMP:20140202T201100Z
UID:h@09c62186abafba1bac59818bde105765a7a02121@google.com
ATTENDEE;CUTYPE=INDIVIDUAL;ROLE=REQ-PARTICIPANT;PARTSTAT=ACCEPTED;X-NUM-GUE
STS=0:mailto:cdpisorqclhmg8r8dtm6ip31f506esjfelo2sthecdgmopbechgn4bj7dtnmer
355phmur8%40virtual
CLASS:PUBLIC
CREATED:20140202T183416Z
LAST-MODIFIED:20140202T183416Z
SEQUENCE:1
STATUS:CONFIRMED
SUMMARY:Den upálení mistra Jana Husa
TRANSP:OPAQUE
END:VEVENT
BEGIN:VEVENT
DTSTART;VALUE=DATE:20150705
DTEND;VALUE=DATE:20150706
DTSTAMP:20140202T201100Z
UID:h@df873adcd2b61ea7c1b13761d7561b9fe6faae5c@google.com
ATTENDEE;CUTYPE=INDIVIDUAL;ROLE=REQ-PARTICIPANT;PARTSTAT=ACCEPTED;X-NUM-GUE
STS=0:mailto:cdpisorqclhmg8r8dtm6ip31f506esjfelo2sthecdgmopbechgn4bj7dtnmer
355phmur8%40virtual
CLASS:PUBLIC
CREATED:20140202T183416Z
LAST-MODIFIED:20140202T183416Z
SEQUENCE:1
STATUS:CONFIRMED
SUMMARY:Den slovanských věrozvěstů Cyrila a Metoděje
TRANSP:OPAQUE
END:VEVENT
BEGIN:VEVENT
DTSTART;VALUE=DATE:20140705
DTEND;VALUE=DATE:20140706
DTSTAMP:20140202T201100Z
UID:h@cc790a245031c0186f1d6d9ab8560db87c86269d@google.com
ATTENDEE;CUTYPE=INDIVIDUAL;ROLE=REQ-PARTICIPANT;PARTSTAT=ACCEPTED;X-NUM-GUE
STS=0:mailto:cdpisorqclhmg8r8dtm6ip31f506esjfelo2sthecdgmopbechgn4bj7dtnmer
355phmur8%40virtual
CLASS:PUBLIC
CREATED:20140202T183416Z
LAST-MODIFIED:20140202T183416Z
SEQUENCE:1
STATUS:CONFIRMED
SUMMARY:Den slovanských věrozvěstů Cyrila a Metoděje
TRANSP:OPAQUE
END:VEVENT
BEGIN:VEVENT
DTSTART;VALUE=DATE:20130705
DTEND;VALUE=DATE:20130706
DTSTAMP:20140202T201100Z
UID:h@4b4d8fc982e6734d799afdd5de90041a009e56b5@google.com
ATTENDEE;CUTYPE=INDIVIDUAL;ROLE=REQ-PARTICIPANT;PARTSTAT=ACCEPTED;X-NUM-GUE
STS=0:mailto:cdpisorqclhmg8r8dtm6ip31f506esjfelo2sthecdgmopbechgn4bj7dtnmer
355phmur8%40virtual
CLASS:PUBLIC
CREATED:20140202T183416Z
LAST-MODIFIED:20140202T183416Z
SEQUENCE:1
STATUS:CONFIRMED
SUMMARY:Den slovanských věrozvěstů Cyrila a Metoděje
TRANSP:OPAQUE
END:VEVENT
BEGIN:VEVENT
DTSTART;VALUE=DATE:20150101
DTEND;VALUE=DATE:20150102
DTSTAMP:20140202T201100Z
UID:h@e35dfa2052d4cf25d186e005626c66b794792d35@google.com
ATTENDEE;CUTYPE=INDIVIDUAL;ROLE=REQ-PARTICIPANT;PARTSTAT=ACCEPTED;X-NUM-GUE
STS=0:mailto:cdpisorqclhmg8r8dtm6ip31f506esjfelo2sthecdgmopbechgn4bj7dtnmer
355phmur8%40virtual
CLASS:PUBLIC
CREATED:20140202T183416Z
LAST-MODIFIED:20140202T183416Z
SEQUENCE:1
STATUS:CONFIRMED
SUMMARY:Den obnovy samostatného českého státu
TRANSP:OPAQUE
END:VEVENT
BEGIN:VEVENT
DTSTART;VALUE=DATE:20130101
DTEND;VALUE=DATE:20130102
DTSTAMP:20140202T201100Z
UID:h@e13a9a864c4beec0b4f1055fb4e1bb14076b5a9b@google.com
ATTENDEE;CUTYPE=INDIVIDUAL;ROLE=REQ-PARTICIPANT;PARTSTAT=ACCEPTED;X-NUM-GUE
STS=0:mailto:cdpisorqclhmg8r8dtm6ip31f506esjfelo2sthecdgmopbechgn4bj7dtnmer
355phmur8%40virtual
CLASS:PUBLIC
CREATED:20140202T183416Z
LAST-MODIFIED:20140202T183416Z
SEQUENCE:1
STATUS:CONFIRMED
SUMMARY:Den obnovy samostatného českého státu
TRANSP:OPAQUE
END:VEVENT
BEGIN:VEVENT
DTSTART;VALUE=DATE:20140101
DTEND;VALUE=DATE:20140102
DTSTAMP:20140202T201100Z
UID:h@a87543a1136d4a980a8037471eb49ea00f087c81@google.com
ATTENDEE;CUTYPE=INDIVIDUAL;ROLE=REQ-PARTICIPANT;PARTSTAT=ACCEPTED;X-NUM-GUE
STS=0:mailto:cdpisorqclhmg8r8dtm6ip31f506esjfelo2sthecdgmopbechgn4bj7dtnmer
355phmur8%40virtual
CLASS:PUBLIC
CREATED:20140202T183416Z
LAST-MODIFIED:20140202T183416Z
SEQUENCE:1
STATUS:CONFIRMED
SUMMARY:Den obnovy samostatného českého státu
TRANSP:OPAQUE
END:VEVENT
BEGIN:VEVENT
DTSTART;VALUE=DATE:20141117
DTEND;VALUE=DATE:20141118
DTSTAMP:20140202T201100Z
UID:h@94e14807e30f52a82572a2cd28a51c89a033d09f@google.com
ATTENDEE;CUTYPE=INDIVIDUAL;ROLE=REQ-PARTICIPANT;PARTSTAT=ACCEPTED;X-NUM-GUE
STS=0:mailto:cdpisorqclhmg8r8dtm6ip31f506esjfelo2sthecdgmopbechgn4bj7dtnmer
355phmur8%40virtual
CLASS:PUBLIC
CREATED:20140202T183416Z
LAST-MODIFIED:20140202T183416Z
SEQUENCE:1
STATUS:CONFIRMED
SUMMARY:Den boje za svobodu a demokracii
TRANSP:OPAQUE
END:VEVENT
BEGIN:VEVENT
DTSTART;VALUE=DATE:20131117
DTEND;VALUE=DATE:20131118
DTSTAMP:20140202T201100Z
UID:h@873a2a1499e25477876926c6729dc214b2f1f0f9@google.com
ATTENDEE;CUTYPE=INDIVIDUAL;ROLE=REQ-PARTICIPANT;PARTSTAT=ACCEPTED;X-NUM-GUE
STS=0:mailto:cdpisorqclhmg8r8dtm6ip31f506esjfelo2sthecdgmopbechgn4bj7dtnmer
355phmur8%40virtual
CLASS:PUBLIC
CREATED:20140202T183416Z
LAST-MODIFIED:20140202T183416Z
SEQUENCE:1
STATUS:CONFIRMED
SUMMARY:Den boje za svobodu a demokracii
TRANSP:OPAQUE
END:VEVENT
BEGIN:VEVENT
DTSTART;VALUE=DATE:20151117
DTEND;VALUE=DATE:20151118
DTSTAMP:20140202T201100Z
UID:h@599f0d6373565c265b3491b084a2c6198b0b00b9@google.com
ATTENDEE;CUTYPE=INDIVIDUAL;ROLE=REQ-PARTICIPANT;PARTSTAT=ACCEPTED;X-NUM-GUE
STS=0:mailto:cdpisorqclhmg8r8dtm6ip31f506esjfelo2sthecdgmopbechgn4bj7dtnmer
355phmur8%40virtual
CLASS:PUBLIC
CREATED:20140202T183416Z
LAST-MODIFIED:20140202T183416Z
SEQUENCE:1
STATUS:CONFIRMED
SUMMARY:Den boje za svobodu a demokracii
TRANSP:OPAQUE
END:VEVENT
BEGIN:VEVENT
DTSTART;VALUE=DATE:20151226
DTEND;VALUE=DATE:20151227
DTSTAMP:20140202T201100Z
UID:h@e65fdbb6f9703e75e775c9f407f55663c80d4764@google.com
ATTENDEE;CUTYPE=INDIVIDUAL;ROLE=REQ-PARTICIPANT;PARTSTAT=ACCEPTED;X-NUM-GUE
STS=0:mailto:cdpisorqclhmg8r8dtm6ip31f506esjfelo2sthecdgmopbechgn4bj7dtnmer
355phmur8%40virtual
CLASS:PUBLIC
CREATED:20140202T183416Z
LAST-MODIFIED:20140202T183416Z
SEQUENCE:1
STATUS:CONFIRMED
SUMMARY:2. svátek vánoční
TRANSP:OPAQUE
END:VEVENT
BEGIN:VEVENT
DTSTART;VALUE=DATE:20141226
DTEND;VALUE=DATE:20141227
DTSTAMP:20140202T201100Z
UID:h@807088064c072183b2fa351251155bff44f09787@google.com
ATTENDEE;CUTYPE=INDIVIDUAL;ROLE=REQ-PARTICIPANT;PARTSTAT=ACCEPTED;X-NUM-GUE
STS=0:mailto:cdpisorqclhmg8r8dtm6ip31f506esjfelo2sthecdgmopbechgn4bj7dtnmer
355phmur8%40virtual
CLASS:PUBLIC
CREATED:20140202T183416Z
LAST-MODIFIED:20140202T183416Z
SEQUENCE:1
STATUS:CONFIRMED
SUMMARY:2. svátek vánoční
TRANSP:OPAQUE
END:VEVENT
BEGIN:VEVENT
DTSTART;VALUE=DATE:20131226
DTEND;VALUE=DATE:20131227
DTSTAMP:20140202T201100Z
UID:h@6165f686632ab29cdd7bdb46a4c3578a48045428@google.com
ATTENDEE;CUTYPE=INDIVIDUAL;ROLE=REQ-PARTICIPANT;PARTSTAT=ACCEPTED;X-NUM-GUE
STS=0:mailto:cdpisorqclhmg8r8dtm6ip31f506esjfelo2sthecdgmopbechgn4bj7dtnmer
355phmur8%40virtual
CLASS:PUBLIC
CREATED:20140202T183416Z
LAST-MODIFIED:20140202T183416Z
SEQUENCE:1
STATUS:CONFIRMED
SUMMARY:2. svátek vánoční
TRANSP:OPAQUE
END:VEVENT
BEGIN:VEVENT
DTSTART;VALUE=DATE:20141225
DTEND;VALUE=DATE:20141226
DTSTAMP:20140202T201100Z
UID:h@e2f049ac27b03ada54a27294becbcd1cc2680d9a@google.com
ATTENDEE;CUTYPE=INDIVIDUAL;ROLE=REQ-PARTICIPANT;PARTSTAT=ACCEPTED;X-NUM-GUE
STS=0:mailto:cdpisorqclhmg8r8dtm6ip31f506esjfelo2sthecdgmopbechgn4bj7dtnmer
355phmur8%40virtual
CLASS:PUBLIC
CREATED:20140202T183416Z
LAST-MODIFIED:20140202T183416Z
SEQUENCE:1
STATUS:CONFIRMED
SUMMARY:1. svátek vánoční
TRANSP:OPAQUE
END:VEVENT
BEGIN:VEVENT
DTSTART;VALUE=DATE:20131225
DTEND;VALUE=DATE:20131226
DTSTAMP:20140202T201100Z
UID:h@7f26c52a3d0e69b81f2fc35490224899490c0014@google.com
ATTENDEE;CUTYPE=INDIVIDUAL;ROLE=REQ-PARTICIPANT;PARTSTAT=ACCEPTED;X-NUM-GUE
STS=0:mailto:cdpisorqclhmg8r8dtm6ip31f506esjfelo2sthecdgmopbechgn4bj7dtnmer
355phmur8%40virtual
CLASS:PUBLIC
CREATED:20140202T183416Z
LAST-MODIFIED:20140202T183416Z
SEQUENCE:1
STATUS:CONFIRMED
SUMMARY:1. svátek vánoční
TRANSP:OPAQUE
END:VEVENT
BEGIN:VEVENT
DTSTART;VALUE=DATE:20151225
DTEND;VALUE=DATE:20151226
DTSTAMP:20140202T201100Z
UID:h@3ddadf7953340f067a4e3b07a4621f9343ff1518@google.com
ATTENDEE;CUTYPE=INDIVIDUAL;ROLE=REQ-PARTICIPANT;PARTSTAT=ACCEPTED;X-NUM-GUE
STS=0:mailto:cdpisorqclhmg8r8dtm6ip31f506esjfelo2sthecdgmopbechgn4bj7dtnmer
355phmur8%40virtual
CLASS:PUBLIC
CREATED:20140202T183416Z
LAST-MODIFIED:20140202T183416Z
SEQUENCE:1
STATUS:CONFIRMED
SUMMARY:1. svátek vánoční
TRANSP:OPAQUE
END:VEVENT
END:VCALENDAR

View File

@ -0,0 +1,51 @@
BEGIN:VCALENDAR
PRODID:-//Google Inc//Google Calendar 70.9054//EN
VERSION:2.0
CALSCALE:GREGORIAN
X-WR-CALNAME:calmozilla1@gmail.com
X-WR-TIMEZONE:America/Los_Angeles
BEGIN:VTIMEZONE
TZID:America/Los_Angeles
X-LIC-LOCATION:America/Los_Angeles
BEGIN:DAYLIGHT
TZOFFSETFROM:-0800
TZOFFSETTO:-0700
TZNAME:PDT
DTSTART:19700308T020000
RRULE:FREQ=YEARLY;BYMONTH=3;BYDAY=2SU
END:DAYLIGHT
BEGIN:STANDARD
TZOFFSETFROM:-0700
TZOFFSETTO:-0800
TZNAME:PST
DTSTART:19701101T020000
RRULE:FREQ=YEARLY;BYMONTH=11;BYDAY=1SU
END:STANDARD
END:VTIMEZONE
BEGIN:VEVENT
DTSTART;TZID=America/Los_Angeles:20120630T060000
DTEND;TZID=America/Los_Angeles:20120630T070000
DTSTAMP:20120724T212411Z
UID:dn4vrfmfn5p05roahsopg57h48@google.com
CREATED:20120724T212411Z
DESCRIPTION:
LAST-MODIFIED:20120724T212411Z
LOCATION:
SEQUENCE:0
STATUS:CONFIRMED
SUMMARY:Really long event name thing
TRANSP:OPAQUE
BEGIN:VALARM
ACTION:EMAIL
DESCRIPTION:This is an event reminder
SUMMARY:Alarm notification
ATTENDEE:mailto:calmozilla1@gmail.com
TRIGGER:-P0DT0H30M0S
END:VALARM
BEGIN:VALARM
ACTION:DISPLAY
DESCRIPTION:This is an event reminder
TRIGGER:-P0DT0H30M0S
END:VALARM
END:VEVENT
END:VCALENDAR

View File

@ -0,0 +1,4 @@
BEGIN:VCALENDAR
END:VCALENDAR

View File

@ -0,0 +1,4 @@
BEGIN:VCALENDAR
COMMENT:This blank line is invalid
END:VCALENDAR

View File

@ -0,0 +1,52 @@
BEGIN:VCALENDAR
PRODID:-//Google Inc//Google Calendar 70.9054//EN
VERSION:2.0
CALSCALE:GREGORIAN
X-WR-CALNAME:calmozilla1@gmail.com
X-WR-TIMEZONE:America/Los_Angeles
BEGIN:VTIMEZONE
TZID:America/Los_Angeles
X-LIC-LOCATION:America/Los_Angeles
BEGIN:DAYLIGHT
TZOFFSETFROM:-0800
TZOFFSETTO:-0700
TZNAME:PDT
DTSTART:19700308T020000
RRULE:FREQ=YEARLY;BYMONTH=3;BYDAY=2SU
END:DAYLIGHT
BEGIN:STANDARD
TZOFFSETFROM:-0700
TZOFFSETTO:-0800
TZNAME:PST
DTSTART:19701101T020000
RRULE:FREQ=YEARLY;BYMONTH=11;BYDAY=1SU
END:STANDARD
END:VTIMEZONE
BEGIN:VEVENT
DTSTART;TZID=America/Los_Angeles:20120801T050000
DTEND;TZID=America/Los_Angeles:20120801T060000
RRULE:FREQ=DAILY
DTSTAMP:20120803T221236Z
UID:tgh9qho17b07pk2n2ji3gluans@google.com
CREATED:20120803T221236Z
DESCRIPTION:
LAST-MODIFIED:20120803T221236Z
LOCATION:
SEQUENCE:0
STATUS:CONFIRMED
SUMMARY:Every day recurring
TRANSP:OPAQUE
BEGIN:VALARM
ACTION:EMAIL
DESCRIPTION:This is an event reminder
SUMMARY:Alarm notification
ATTENDEE:mailto:calmozilla1@gmail.com
TRIGGER:-P0DT0H30M0S
END:VALARM
BEGIN:VALARM
ACTION:DISPLAY
DESCRIPTION:This is an event reminder
TRIGGER:-P0DT0H30M0S
END:VALARM
END:VEVENT
END:VCALENDAR

View File

@ -0,0 +1,41 @@
BEGIN:VCALENDAR
PRODID:-//Google Inc//Google Calendar 70.9054//EN
VERSION:2.0
CALSCALE:GREGORIAN
X-WR-CALNAME:calmozilla1@gmail.com
X-WR-TIMEZONE:America/Los_Angeles
BEGIN:VTIMEZONE
TZID:America/Los_Angeles
X-LIC-LOCATION:America/Los_Angeles
BEGIN:DAYLIGHT
TZOFFSETFROM:-0800
TZOFFSETTO:-0700
TZNAME:PDT
DTSTART:19700308T020000
RRULE:FREQ=YEARLY;BYMONTH=3;BYDAY=2SU
END:DAYLIGHT
BEGIN:STANDARD
TZOFFSETFROM:-0700
TZOFFSETTO:-0800
TZNAME:PST
DTSTART:19701101T020000
RRULE:FREQ=YEARLY;BYMONTH=11;BYDAY=1SU
END:STANDARD
END:VTIMEZONE
BEGIN:VEVENT
DTSTART;VALUE=DATE:20170821
DTEND;VALUE=DATE:20170822
RRULE:FREQ=WEEKLY;UNTIL=20170911;BYDAY=MO
DTSTAMP:20170818T191547Z
UID:37mfdqtlcrrvbil9b3n7vicb1t@google.com
CLASS:PUBLIC
CREATED:20170818T175332Z
DESCRIPTION:
LAST-MODIFIED:20170818T175332Z
LOCATION:
SEQUENCE:0
STATUS:CONFIRMED
SUMMARY:Late Start\, SMS
TRANSP:TRANSPARENT
END:VEVENT
END:VCALENDAR

View File

@ -0,0 +1,52 @@
BEGIN:VCALENDAR
PRODID:-//Google Inc//Google Calendar 70.9054//EN
VERSION:2.0
CALSCALE:GREGORIAN
X-WR-CALNAME:calmozilla1@gmail.com
X-WR-TIMEZONE:America/Los_Angeles
BEGIN:VTIMEZONE
TZID:America/Los_Angeles
X-LIC-LOCATION:America/Los_Angeles
BEGIN:DAYLIGHT
TZOFFSETFROM:-0800
TZOFFSETTO:-0700
TZNAME:PDT
DTSTART:19700308T020000
RRULE:FREQ=YEARLY;BYMONTH=3;BYDAY=2SU
END:DAYLIGHT
BEGIN:STANDARD
TZOFFSETFROM:-0700
TZOFFSETTO:-0800
TZNAME:PST
DTSTART:19701101T020000
RRULE:FREQ=YEARLY;BYMONTH=11;BYDAY=1SU
END:STANDARD
END:VTIMEZONE
BEGIN:VEVENT
DTSTART;VALUE=DATE:20120803
DTEND;VALUE=DATE:20120804
RRULE:FREQ=WEEKLY;BYDAY=MO,TU,WE,TH,FR
DTSTAMP:20120803T221306Z
UID:4pfh824gvims850j0gar361t04@google.com
CREATED:20120803T221306Z
DESCRIPTION:
LAST-MODIFIED:20120803T221306Z
LOCATION:
SEQUENCE:0
STATUS:CONFIRMED
SUMMARY:Day Long Event
TRANSP:TRANSPARENT
BEGIN:VALARM
ACTION:EMAIL
DESCRIPTION:This is an event reminder
SUMMARY:Alarm notification
ATTENDEE:mailto:calmozilla1@gmail.com
TRIGGER;VALUE=DATE-TIME:20120802T233000Z
END:VALARM
BEGIN:VALARM
ACTION:DISPLAY
DESCRIPTION:This is an event reminder
TRIGGER;VALUE=DATE-TIME:20120802T233000Z
END:VALARM
END:VEVENT
END:VCALENDAR

View File

@ -0,0 +1,50 @@
BEGIN:VCALENDAR
PRODID:-//Google Inc//Google Calendar 70.9054//EN
VERSION:2.0
CALSCALE:GREGORIAN
X-WR-CALNAME:calmozilla1@gmail.com
X-WR-TIMEZONE:America/Los_Angeles
BEGIN:VTIMEZONE
TZID:America/Los_Angeles
X-LIC-LOCATION:America/Los_Angeles
BEGIN:DAYLIGHT
TZOFFSETFROM:-0800
TZOFFSETTO:-0700
TZNAME:PDT
DTSTART:19700308T020000
RRULE:FREQ=YEARLY;BYMONTH=3;BYDAY=2SU
END:DAYLIGHT
BEGIN:STANDARD
TZOFFSETFROM:-0700
TZOFFSETTO:-0800
TZNAME:PST
DTSTART:19701101T020000
RRULE:FREQ=YEARLY;BYMONTH=11;BYDAY=1SU
END:STANDARD
END:VTIMEZONE
BEGIN:VEVENT
DTSTART;VALUE=DATE:20120904
DTEND;VALUE=DATE:20120905
DTSTAMP:20120905T084734Z
UID:redgrb1l0aju5edm6h0s102eu4@google.com
CREATED:20120905T084734Z
DESCRIPTION:
LAST-MODIFIED:20120905T084734Z
LOCATION:
SEQUENCE:0
STATUS:CONFIRMED
SUMMARY:Event
TRANSP:TRANSPARENT
BEGIN:VALARM
ACTION:EMAIL
DESCRIPTION:This is an event reminder
SUMMARY:Alarm notification
ATTENDEE:mailto:calmozilla1@gmail.com
TRIGGER;VALUE=DATE-TIME:20120903T233000Z
END:VALARM
BEGIN:VALARM
ACTION:DISPLAY
DESCRIPTION:This is an event reminder
END:VALARM
END:VEVENT
END:VCALENDAR

View File

@ -0,0 +1,90 @@
BEGIN:VCALENDAR
PRODID:-//Google Inc//Google Calendar 70.9054//EN
VERSION:2.0
CALSCALE:GREGORIAN
X-WR-CALNAME:Contacts' birthdays and events
X-WR-TIMEZONE:America/Los_Angeles
X-WR-CALDESC:Your contacts' birthdays and anniversaries
BEGIN:VEVENT
DTSTART;VALUE=DATE:20141210
DTEND;VALUE=DATE:20141211
RRULE:FREQ=DAILY;INTERVAL=1;COUNT=1
RDATE:20131210Z
RDATE:20121210Z
DTSTAMP:20121207T183041Z
UID:2014_BIRTHDAY_79d389868f96182e@google.com
ATTENDEE;CUTYPE=INDIVIDUAL;ROLE=REQ-PARTICIPANT;PARTSTAT=ACCEPTED;CN=Contac
ts;X-NUM-GUESTS=0:mailto:4dhmurjkc5hn8sq0ctp6utbg5pr2sor1dhimsp31e8n6errfct
m6abj3dtmg@virtual
CLASS:PUBLIC
CREATED:20121207T183041Z
LAST-MODIFIED:20121207T183041Z
SEQUENCE:1
STATUS:CONFIRMED
SUMMARY:PErson #2's birthday
TRANSP:OPAQUE
END:VEVENT
BEGIN:VEVENT
DTSTART;VALUE=DATE:20121210
DTEND;VALUE=DATE:20121211
DTSTAMP:20121207T183041Z
UID:BIRTHDAY_79d389868f96182e@google.com
ATTENDEE;CUTYPE=INDIVIDUAL;ROLE=REQ-PARTICIPANT;PARTSTAT=ACCEPTED;CN=Contac
ts;X-NUM-GUESTS=0:mailto:4dhmurjkc5hn8sq0ctp6utbg5pr2sor1dhimsp31e8n6errfct
m6abj3dtmg@virtual
X-GOOGLE-CALENDAR-CONTENT-ICON:https://calendar.google.com/googlecalendar/i
mages/cake.gif
X-GOOGLE-CALENDAR-CONTENT-DISPLAY:chip
RECURRENCE-ID;VALUE=DATE:20121210
CLASS:PUBLIC
CREATED:20121207T183041Z
DESCRIPTION:Today is PErson #2's birthday!
LAST-MODIFIED:20121207T183041Z
SEQUENCE:1
STATUS:CONFIRMED
SUMMARY:PErson #2's birthday
TRANSP:OPAQUE
END:VEVENT
BEGIN:VEVENT
DTSTART;VALUE=DATE:20131210
DTEND;VALUE=DATE:20131211
DTSTAMP:20121207T183041Z
UID:BIRTHDAY_79d389868f96182e@google.com
ATTENDEE;CUTYPE=INDIVIDUAL;ROLE=REQ-PARTICIPANT;PARTSTAT=ACCEPTED;CN=Contac
ts;X-NUM-GUESTS=0:mailto:4dhmurjkc5hn8sq0ctp6utbg5pr2sor1dhimsp31e8n6errfct
m6abj3dtmg@virtual
X-GOOGLE-CALENDAR-CONTENT-ICON:https://calendar.google.com/googlecalendar/i
mages/cake.gif
X-GOOGLE-CALENDAR-CONTENT-DISPLAY:chip
RECURRENCE-ID;VALUE=DATE:20131210
CLASS:PUBLIC
CREATED:20121207T183041Z
DESCRIPTION:Today is PErson #2's birthday!
LAST-MODIFIED:20121207T183041Z
SEQUENCE:1
STATUS:CONFIRMED
SUMMARY:PErson #2's birthday
TRANSP:OPAQUE
END:VEVENT
BEGIN:VEVENT
DTSTART;VALUE=DATE:20141210
DTEND;VALUE=DATE:20141211
DTSTAMP:20121207T183041Z
UID:BIRTHDAY_79d389868f96182e@google.com
ATTENDEE;CUTYPE=INDIVIDUAL;ROLE=REQ-PARTICIPANT;PARTSTAT=ACCEPTED;CN=Contac
ts;X-NUM-GUESTS=0:mailto:4dhmurjkc5hn8sq0ctp6utbg5pr2sor1dhimsp31e8n6errfct
m6abj3dtmg@virtual
X-GOOGLE-CALENDAR-CONTENT-ICON:https://calendar.google.com/googlecalendar/i
mages/cake.gif
X-GOOGLE-CALENDAR-CONTENT-DISPLAY:chip
RECURRENCE-ID;VALUE=DATE:20141210
CLASS:PUBLIC
CREATED:20121207T183041Z
DESCRIPTION:Today is PErson #2's birthday!
LAST-MODIFIED:20121207T183041Z
SEQUENCE:1
STATUS:CONFIRMED
SUMMARY:PErson #2's birthday
TRANSP:OPAQUE
END:VEVENT
END:VCALENDAR

View File

@ -0,0 +1,39 @@
BEGIN:VCALENDAR
PRODID:-//Google Inc//Google Calendar 70.9054//EN
VERSION:2.0
CALSCALE:GREGORIAN
X-WR-CALNAME:calmozilla1@gmail.com
X-WR-TIMEZONE:America/Los_Angeles
BEGIN:VTIMEZONE
TZID:America/Los_Angeles
X-LIC-LOCATION:America/Los_Angeles
BEGIN:DAYLIGHT
TZOFFSETFROM:-0800
TZOFFSETTO:-0700
TZNAME:PDT
DTSTART:19700308T020000
RRULE:FREQ=YEARLY;BYMONTH=3;BYDAY=2SU
END:DAYLIGHT
BEGIN:STANDARD
TZOFFSETFROM:-0700
TZOFFSETTO:-0800
TZNAME:PST
DTSTART:19701101T020000
RRULE:FREQ=YEARLY;BYMONTH=11;BYDAY=1SU
END:STANDARD
END:VTIMEZONE
BEGIN:VEVENT
DTSTART;TZID=America/Los_Angeles:20120630T060000
DTEND;TZID=America/Los_Angeles:20120630T070000
DTSTAMP:20120724T212411Z
UID:dn4vrfmfn5p05roahsopg57h48@google.com
CREATED:20120724T212411Z
DESCRIPTION:
LAST-MODIFIED:20120724T212411Z
LOCATION:
SEQUENCE:0
STATUS:CONFIRMED
SUMMARY:Really long event name thing
TRANSP:OPAQUE
END:VEVENT
END:VCALENDAR

View File

@ -0,0 +1,52 @@
BEGIN:VCALENDAR
PRODID:-//Google Inc//Google Calendar 70.9054//EN
VERSION:2.0
CALSCALE:GREGORIAN
X-WR-CALNAME:calmozilla1@gmail.com
X-WR-TIMEZONE:America/Los_Angeles
BEGIN:VTIMEZONE
TZID:America/Los_Angeles
X-LIC-LOCATION:America/Los_Angeles
BEGIN:DAYLIGHT
TZOFFSETFROM:-0800
TZOFFSETTO:-0700
TZNAME:PDT
DTSTART:19700308T020000
RRULE:FREQ=YEARLY;BYMONTH=3;BYDAY=2SU
END:DAYLIGHT
BEGIN:STANDARD
TZOFFSETFROM:-0700
TZOFFSETTO:-0800
TZNAME:PST
DTSTART:19701101T020000
RRULE:FREQ=YEARLY;BYMONTH=11;BYDAY=1SU
END:STANDARD
END:VTIMEZONE
BEGIN:VEVENT
DTSTART;TZID=America/Los_Angeles:20120630T060000
DTEND;TZID=America/Los_Angeles:20120630T070000
DTSTAMP:20120724T212411Z
UID:dn4vrfmfn5p05roahsopg57h48@google.com
CREATED:20120724T212411Z
DESCRIPTION:Here is a description that spans multiple lines!\n\nThis should be on
a new line as well because the description contains newline characters.
LAST-MODIFIED:20120724T212411Z
LOCATION:
SEQUENCE:0
STATUS:CONFIRMED
SUMMARY:Really long event name thing
TRANSP:OPAQUE
BEGIN:VALARM
ACTION:EMAIL
DESCRIPTION:This is an event reminder
SUMMARY:Alarm notification
ATTENDEE:mailto:calmozilla1@gmail.com
TRIGGER:-P0DT0H30M0S
END:VALARM
BEGIN:VALARM
ACTION:DISPLAY
DESCRIPTION:This is an event reminder
TRIGGER:-P0DT0H30M0S
END:VALARM
END:VEVENT
END:VCALENDAR

View File

@ -0,0 +1,45 @@
BEGIN:VCALENDAR
VERSION:2.0
PRODID:Zimbra-Calendar-Provider
BEGIN:VTIMEZONE
TZID:America/Los_Angeles
BEGIN:STANDARD
DTSTART:19710101T020000
TZOFFSETTO:-0800
TZOFFSETFROM:-0700
RRULE:FREQ=YEARLY;WKST=MO;INTERVAL=1;BYMONTH=11;BYDAY=1SU
TZNAME:PST
END:STANDARD
BEGIN:DAYLIGHT
DTSTART:19710101T020000
TZOFFSETTO:-0700
TZOFFSETFROM:-0800
RRULE:FREQ=YEARLY;WKST=MO;INTERVAL=1;BYMONTH=3;BYDAY=2SU
TZNAME:PDT
END:DAYLIGHT
END:VTIMEZONE
BEGIN:VEVENT
UID:1334F9B7-6136-444E-A58D-472564C6AA73
SUMMARY:sahaja <> frashed
DESCRIPTION:weekly 1on1
ATTACH:http://globe-views.com/dcim/dreams/dog/dog-01.jpg
ATTACH:http://www.hdanimals.com/static/cache/e9/59/e959f33a6b440f36cad24beca8bf6d1c.jpg
ATTENDEE;CN=James Lal;CUTYPE=INDIVIDUAL;ROLE=REQ-PARTICIPANT;PARTSTAT=NEEDS
-ACTION;RSVP=TRUE:mailto:jlal@mozilla.com
ORGANIZER;CN=Faramarz Rashed:mailto:frashed@mozilla.com
DTSTART;TZID=America/Los_Angeles:20120326T110000
DTEND;TZID=America/Los_Angeles:20120326T113000
STATUS:CONFIRMED
CLASS:PUBLIC
TRANSP:OPAQUE
LAST-MODIFIED:20120326T161522Z
DTSTAMP:20120730T165637Z
SEQUENCE:9
BEGIN:VALARM
ACTION:DISPLAY
TRIGGER;RELATED=START:-PT5M
DESCRIPTION:Reminder
END:VALARM
END:VEVENT
END:VCALENDAR

View File

@ -0,0 +1,45 @@
BEGIN:VCALENDAR
VERSION:2.0
PRODID:Zimbra-Calendar-Provider
BEGIN:VTIMEZONE
TZID:America/Los_Angeles
BEGIN:STANDARD
DTSTART:19710101T020000
TZOFFSETTO:-0800
TZOFFSETFROM:-0700
RRULE:FREQ=YEARLY;WKST=MO;INTERVAL=1;BYMONTH=11;BYDAY=1SU
TZNAME:PST
END:STANDARD
BEGIN:DAYLIGHT
DTSTART:19710101T020000
TZOFFSETTO:-0700
TZOFFSETFROM:-0800
RRULE:FREQ=YEARLY;WKST=MO;INTERVAL=1;BYMONTH=3;BYDAY=2SU
TZNAME:PDT
END:DAYLIGHT
END:VTIMEZONE
BEGIN:VEVENT
UID:1334F9B7-6136-444E-A58D-472564C6AA73
RRULE:FREQ=WEEKLY;UNTIL=20120730T065959Z
RRULE:FREQ=MONTHLY;BYDAY=SU;UNTIL=20120730T065959Z
SUMMARY:sahaja <> frashed
DESCRIPTION:weekly 1on1
ATTENDEE;CN=James Lal;CUTYPE=INDIVIDUAL;ROLE=REQ-PARTICIPANT;PARTSTAT=NEEDS
-ACTION;RSVP=TRUE:mailto:jlal@mozilla.com
ORGANIZER;CN=Faramarz Rashed:mailto:frashed@mozilla.com
DTSTART;TZID=America/Los_Angeles:20120326T110000
DTEND;TZID=America/Los_Angeles:20120326T113000
STATUS:CONFIRMED
CLASS:PUBLIC
TRANSP:OPAQUE
LAST-MODIFIED:20120326T161522Z
DTSTAMP:20120730T165637Z
SEQUENCE:9
BEGIN:VALARM
ACTION:DISPLAY
TRIGGER;RELATED=START:-PT5M
DESCRIPTION:Reminder
END:VALARM
END:VEVENT
END:VCALENDAR

View File

@ -0,0 +1,45 @@
BEGIN:VCALENDAR
VERSION:2.0
PRODID:Zimbra-Calendar-Provider
BEGIN:VTIMEZONE
TZID:America/Los_Angeles
BEGIN:STANDARD
DTSTART:19710101T020000
TZOFFSETTO:-0800
TZOFFSETFROM:-0700
RRULE:FREQ=YEARLY;BYDAY=1SU;BYMONTH=11
TZNAME:PST
END:STANDARD
BEGIN:DAYLIGHT
DTSTART:19710101T020000
TZOFFSETTO:-0700
TZOFFSETFROM:-0800
RRULE:FREQ=YEARLY;BYDAY=2SU;BYMONTH=3
TZNAME:PDT
END:DAYLIGHT
END:VTIMEZONE
BEGIN:VEVENT
UID:44c10eaa-db0b-4223-8653-cf2b63f26326
RRULE:FREQ=DAILY;BYDAY=MO,TU,WE,TH,FR
SUMMARY:Calendar
DESCRIPTION:desc
ATTENDEE;CN=XXX;ROLE=REQ-PARTICIPANT;PARTSTAT=ACCEPTED;RSVP=TRU
E:mailto:foo@bar.com
ATTENDEE;CN=XXXX;ROLE=REQ-PARTICIPANT;PARTSTAT=ACCEPTED;RSVP=TR
UE:mailto:x@bar.com
ORGANIZER;CN=foobar:mailto:x@bar.com
DTSTART;TZID=America/Los_Angeles:20120911T103000
DTEND;TZID=America/Los_Angeles:20120911T110000
STATUS:CONFIRMED
CLASS:PUBLIC
TRANSP:OPAQUE
LAST-MODIFIED:20120911T184851Z
DTSTAMP:20120911T184851Z
SEQUENCE:1
BEGIN:VALARM
ACTION:DISPLAY
TRIGGER;RELATED=START:-PT5M
DESCRIPTION:Reminder
END:VALARM
END:VEVENT
END:VCALENDAR

View File

@ -0,0 +1,3 @@
# iCal source
- https://github.com/mozilla-comm/ical.js/tree/master/samples

View File

@ -0,0 +1,92 @@
BEGIN:VCALENDAR
VERSION:2.0
PRODID:Zimbra-Calendar-Provider
BEGIN:VTIMEZONE
TZID:America/Los_Angeles
BEGIN:STANDARD
DTSTART:19710101T020000
TZOFFSETTO:-0800
TZOFFSETFROM:-0700
RRULE:FREQ=YEARLY;WKST=MO;INTERVAL=1;BYMONTH=11;BYDAY=1SU
TZNAME:PST
END:STANDARD
BEGIN:DAYLIGHT
DTSTART:19710101T020000
TZOFFSETTO:-0700
TZOFFSETFROM:-0800
RRULE:FREQ=YEARLY;WKST=MO;INTERVAL=1;BYMONTH=3;BYDAY=2SU
TZNAME:PDT
END:DAYLIGHT
END:VTIMEZONE
BEGIN:VEVENT
UID:623c13c0-6c2b-45d6-a12b-c33ad61c4868
DESCRIPTION:IAM FOO
RRULE:FREQ=MONTHLY;INTERVAL=1;BYDAY=1TU
SUMMARY:Crazy Event Thingy!
ATTENDEE;CUTYPE=INDIVIDUAL;ROLE=REQ-PARTICIPANT;PARTSTAT=ACCEPTED;CN=Sahaja
Lal;X-NUM-GUESTS=0:mailto:calmozilla1@gmail.com
ATTENDEE;CUTYPE=INDIVIDUAL;ROLE=REQ-PARTICIPANT;PARTSTAT=NEEDS-ACTION;CN=ja
mes@lightsofapollo.com;X-NUM-GUESTS=0:mailto:james@lightsofapollo.com
ATTENDEE;CUTYPE=INDIVIDUAL;ROLE=REQ-PARTICIPANT;PARTSTAT=NEEDS-ACTION;CN=ia
m.revelation@gmail.com;X-NUM-GUESTS=0:mailto:iam.revelation@gmail.com
LOCATION:PLACE
ORGANIZER;CN=James Lal:mailto:jlal@mozilla.com
DTSTART;TZID=America/Los_Angeles:20121002T100000
DTEND;TZID=America/Los_Angeles:20121002T103000
STATUS:CONFIRMED
CLASS:PUBLIC
TRANSP:OPAQUE
LAST-MODIFIED:20120912T171506Z
DTSTAMP:20120912T171506Z
SEQUENCE:0
RDATE;TZID=America/Los_Angeles:20121105T100000
RDATE;TZID=America/Los_Angeles:20121110T100000,20121130T100000
EXDATE;TZID=America/Los_Angeles:20130402T100000
EXDATE;TZID=America/Los_Angeles:20121204T100000
EXDATE;TZID=America/Los_Angeles:20130205T100000
BEGIN:VALARM
ACTION:DISPLAY
TRIGGER;RELATED=START:-PT5M
DESCRIPTION:Reminder
END:VALARM
END:VEVENT
BEGIN:VEVENT
UID:623c13c0-6c2b-45d6-a12b-c33ad61c4868
SUMMARY:Crazy Event Thingy!
DESCRIPTION:I HAZ CHANGED!
ORGANIZER;CN=James Lal:mailto:jlal@mozilla.com
DTSTART;TZID=America/Los_Angeles:20121002T150000
DTEND;TZID=America/Los_Angeles:20121002T153000
STATUS:CONFIRMED
CLASS:PUBLIC
TRANSP:OPAQUE
RECURRENCE-ID;TZID=America/Los_Angeles:20121002T100000
LAST-MODIFIED:20120912T171540Z
DTSTAMP:20120912T171540Z
SEQUENCE:1
BEGIN:VALARM
ACTION:DISPLAY
TRIGGER;RELATED=START:-PT5M
DESCRIPTION:Reminder
END:VALARM
END:VEVENT
BEGIN:VEVENT
UID:623c13c0-6c2b-45d6-a12b-c33ad61c4868
SUMMARY:Crazy Event Thingy!
ORGANIZER;CN=James Lal:mailto:jlal@mozilla.com
DTSTART;TZID=America/Los_Angeles:20121106T200000
DTEND;TZID=America/Los_Angeles:20121106T203000
STATUS:CONFIRMED
CLASS:PUBLIC
TRANSP:OPAQUE
RECURRENCE-ID:20121105T180000Z
LAST-MODIFIED:20120912T171820Z
DTSTAMP:20120912T171820Z
SEQUENCE:1
BEGIN:VALARM
ACTION:DISPLAY
TRIGGER;RELATED=START:-PT5M
DESCRIPTION:Reminder
END:VALARM
END:VEVENT
END:VCALENDAR

View File

@ -0,0 +1,50 @@
BEGIN:VCALENDAR
VERSION:2.0
PRODID:Zimbra-Calendar-Provider
BEGIN:VTIMEZONE
TZID:America/Los_Angeles
BEGIN:STANDARD
DTSTART:19710101T020000
TZOFFSETTO:-0800
TZOFFSETFROM:-0700
RRULE:FREQ=YEARLY;WKST=MO;INTERVAL=1;BYMONTH=11;BYDAY=1SU
TZNAME:PST
END:STANDARD
BEGIN:DAYLIGHT
DTSTART:19710101T020000
TZOFFSETTO:-0700
TZOFFSETFROM:-0800
RRULE:FREQ=YEARLY;WKST=MO;INTERVAL=1;BYMONTH=3;BYDAY=2SU
TZNAME:PDT
END:DAYLIGHT
END:VTIMEZONE
BEGIN:VEVENT
UID:623c13c0-6c2b-45d6-a12b-c33ad61c4868
DESCRIPTION:IAM FOO
RRULE:FREQ=MONTHLY;INTERVAL=1;BYDAY=1TU;UNTIL=20121231T100000
SUMMARY:Crazy Event Thingy!
ATTENDEE;CUTYPE=INDIVIDUAL;ROLE=REQ-PARTICIPANT;PARTSTAT=ACCEPTED;CN=Sahaja
Lal;X-NUM-GUESTS=0:mailto:calmozilla1@gmail.com
ATTENDEE;CUTYPE=INDIVIDUAL;ROLE=REQ-PARTICIPANT;PARTSTAT=NEEDS-ACTION;CN=ja
mes@lightsofapollo.com;X-NUM-GUESTS=0:mailto:james@lightsofapollo.com
ATTENDEE;CUTYPE=INDIVIDUAL;ROLE=REQ-PARTICIPANT;PARTSTAT=NEEDS-ACTION;CN=ia
m.revelation@gmail.com;X-NUM-GUESTS=0:mailto:iam.revelation@gmail.com
LOCATION:PLACE
ORGANIZER;CN=James Lal:mailto:jlal@mozilla.com
DTSTART;TZID=America/Los_Angeles:20121002T100000
DTEND;TZID=America/Los_Angeles:20121002T103000
STATUS:CONFIRMED
CLASS:PUBLIC
TRANSP:OPAQUE
LAST-MODIFIED:20120912T171506Z
DTSTAMP:20120912T171506Z
SEQUENCE:0
RDATE;TZID=America/Los_Angeles:20121110T100000
RDATE;TZID=America/Los_Angeles:20121105T100000
BEGIN:VALARM
ACTION:DISPLAY
TRIGGER;RELATED=START:-PT5M
DESCRIPTION:Reminder
END:VALARM
END:VEVENT
END:VCALENDAR

View File

@ -0,0 +1,63 @@
BEGIN:VCALENDAR
PRODID:-//Google Inc//Google Calendar 70.9054//EN
VERSION:2.0
CALSCALE:GREGORIAN
METHOD:PUBLISH
X-WR-CALNAME:School Board
X-WR-TIMEZONE:America/Chicago
X-WR-CALDESC:
BEGIN:VTIMEZONE
TZID:America/Chicago
X-LIC-LOCATION:America/Chicago
BEGIN:DAYLIGHT
TZOFFSETFROM:-0600
TZOFFSETTO:-0500
TZNAME:CDT
DTSTART:19700308T020000
RRULE:FREQ=YEARLY;BYMONTH=3;BYDAY=2SU
END:DAYLIGHT
BEGIN:STANDARD
TZOFFSETFROM:-0500
TZOFFSETTO:-0600
TZNAME:CST
DTSTART:19701101T020000
RRULE:FREQ=YEARLY;BYMONTH=11;BYDAY=1SU
END:STANDARD
END:VTIMEZONE
BEGIN:VEVENT
DTSTART;TZID=America/Chicago:20160808T180000
DTEND;TZID=America/Chicago:20160808T203000
DTSTAMP:20160718T160226Z
UID:kpgr4590djmi89l3sv51gmalrc@google.com
ATTENDEE;CUTYPE=INDIVIDUAL;ROLE=REQ-PARTICIPANT;PARTSTAT=ACCEPTED;CN=School
Board;X-NUM-GUESTS=0:mailto:aliceisd.net_7hatmpq9uek3a1h6if0r0sn5bc@group.
calendar.google.com
RECURRENCE-ID;TZID=America/Chicago:20160808T183000
CREATED:20150715T183809Z
DESCRIPTION:
LAST-MODIFIED:20160718T155538Z
LOCATION:
SEQUENCE:1
STATUS:CONFIRMED
SUMMARY:Regular Board Meeting Modified
TRANSP:OPAQUE
END:VEVENT
BEGIN:VEVENT
DTSTART;TZID=America/Chicago:20150810T183000
DTEND;TZID=America/Chicago:20150810T210000
RRULE:FREQ=MONTHLY;UNTIL=20180709T233000Z;BYDAY=2MO
DTSTAMP:20160718T160226Z
UID:kpgr4590djmi89l3sv51gmalrc@google.com
ATTENDEE;CUTYPE=INDIVIDUAL;ROLE=REQ-PARTICIPANT;PARTSTAT=ACCEPTED;CN=School
Board;X-NUM-GUESTS=0:mailto:aliceisd.net_7hatmpq9uek3a1h6if0r0sn5bc@group.
calendar.google.com
CREATED:20150715T183809Z
DESCRIPTION:
LAST-MODIFIED:20160718T155538Z
LOCATION:
SEQUENCE:0
STATUS:CONFIRMED
SUMMARY:Regular Board Meeting
TRANSP:OPAQUE
END:VEVENT
END:VCALENDAR

View File

@ -0,0 +1,578 @@
BEGIN:VCALENDAR
PRODID:-//Google Inc//Google Calendar 70.9054//EN
VERSION:2.0
CALSCALE:GREGORIAN
METHOD:PUBLISH
X-WR-CALNAME:SB-1213
X-WR-TIMEZONE:America/Denver
X-WR-CALDESC:
BEGIN:VTIMEZONE
TZID:America/New_York
X-LIC-LOCATION:America/New_York
BEGIN:DAYLIGHT
TZOFFSETFROM:-0500
TZOFFSETTO:-0400
TZNAME:EDT
DTSTART:19700308T020000
RRULE:FREQ=YEARLY;BYMONTH=3;BYDAY=2SU
END:DAYLIGHT
BEGIN:STANDARD
TZOFFSETFROM:-0400
TZOFFSETTO:-0500
TZNAME:EST
DTSTART:19701101T020000
RRULE:FREQ=YEARLY;BYMONTH=11;BYDAY=1SU
END:STANDARD
END:VTIMEZONE
BEGIN:VEVENT
DTSTART;VALUE=DATE:20170602
DTEND;VALUE=DATE:20170603
DTSTAMP:20160829T191852Z
UID:h9i3hjtisl53goaljdcdb681fc@google.com
RECURRENCE-ID;VALUE=DATE:20170601
CREATED:20160829T134437Z
DESCRIPTION:
LAST-MODIFIED:20160829T134450Z
LOCATION:
SEQUENCE:4
STATUS:CONFIRMED
SUMMARY:B
TRANSP:TRANSPARENT
END:VEVENT
BEGIN:VEVENT
DTSTART;VALUE=DATE:20170531
DTEND;VALUE=DATE:20170601
DTSTAMP:20160829T191852Z
UID:h9i3hjtisl53goaljdcdb681fc@google.com
RECURRENCE-ID;VALUE=DATE:20170530
CREATED:20160829T134437Z
DESCRIPTION:
LAST-MODIFIED:20160829T134450Z
LOCATION:
SEQUENCE:4
STATUS:CONFIRMED
SUMMARY:B
TRANSP:TRANSPARENT
END:VEVENT
BEGIN:VEVENT
DTSTART;VALUE=DATE:20170524
DTEND;VALUE=DATE:20170525
DTSTAMP:20160829T191852Z
UID:h9i3hjtisl53goaljdcdb681fc@google.com
RECURRENCE-ID;VALUE=DATE:20170524
CREATED:20160829T134437Z
DESCRIPTION:
LAST-MODIFIED:20160829T134450Z
LOCATION:
SEQUENCE:5
STATUS:CONFIRMED
SUMMARY:B
TRANSP:TRANSPARENT
END:VEVENT
BEGIN:VEVENT
DTSTART;VALUE=DATE:20170216
DTEND;VALUE=DATE:20170217
DTSTAMP:20160829T191852Z
UID:h9i3hjtisl53goaljdcdb681fc@google.com
RECURRENCE-ID;VALUE=DATE:20170215
CREATED:20160829T134437Z
DESCRIPTION:
LAST-MODIFIED:20160829T134450Z
LOCATION:
SEQUENCE:2
STATUS:CONFIRMED
SUMMARY:B
TRANSP:TRANSPARENT
END:VEVENT
BEGIN:VEVENT
DTSTART;VALUE=DATE:20170214
DTEND;VALUE=DATE:20170215
DTSTAMP:20160829T191852Z
UID:h9i3hjtisl53goaljdcdb681fc@google.com
RECURRENCE-ID;VALUE=DATE:20170213
CREATED:20160829T134437Z
DESCRIPTION:
LAST-MODIFIED:20160829T134450Z
LOCATION:
SEQUENCE:2
STATUS:CONFIRMED
SUMMARY:B
TRANSP:TRANSPARENT
END:VEVENT
BEGIN:VEVENT
DTSTART;VALUE=DATE:20170210
DTEND;VALUE=DATE:20170211
DTSTAMP:20160829T191852Z
UID:h9i3hjtisl53goaljdcdb681fc@google.com
RECURRENCE-ID;VALUE=DATE:20170209
CREATED:20160829T134437Z
DESCRIPTION:
LAST-MODIFIED:20160829T134450Z
LOCATION:
SEQUENCE:2
STATUS:CONFIRMED
SUMMARY:B
TRANSP:TRANSPARENT
END:VEVENT
BEGIN:VEVENT
DTSTART;VALUE=DATE:20170208
DTEND;VALUE=DATE:20170209
DTSTAMP:20160829T191852Z
UID:h9i3hjtisl53goaljdcdb681fc@google.com
RECURRENCE-ID;VALUE=DATE:20170207
CREATED:20160829T134437Z
DESCRIPTION:
LAST-MODIFIED:20160829T134450Z
LOCATION:
SEQUENCE:2
STATUS:CONFIRMED
SUMMARY:B
TRANSP:TRANSPARENT
END:VEVENT
BEGIN:VEVENT
DTSTART;VALUE=DATE:20170206
DTEND;VALUE=DATE:20170207
DTSTAMP:20160829T191852Z
UID:h9i3hjtisl53goaljdcdb681fc@google.com
RECURRENCE-ID;VALUE=DATE:20170205
CREATED:20160829T134437Z
DESCRIPTION:
LAST-MODIFIED:20160829T134450Z
LOCATION:
SEQUENCE:2
STATUS:CONFIRMED
SUMMARY:B
TRANSP:TRANSPARENT
END:VEVENT
BEGIN:VEVENT
DTSTART;VALUE=DATE:20170202
DTEND;VALUE=DATE:20170203
DTSTAMP:20160829T191852Z
UID:h9i3hjtisl53goaljdcdb681fc@google.com
RECURRENCE-ID;VALUE=DATE:20170201
CREATED:20160829T134437Z
DESCRIPTION:
LAST-MODIFIED:20160829T134450Z
LOCATION:
SEQUENCE:2
STATUS:CONFIRMED
SUMMARY:B
TRANSP:TRANSPARENT
END:VEVENT
BEGIN:VEVENT
DTSTART;VALUE=DATE:20170131
DTEND;VALUE=DATE:20170201
DTSTAMP:20160829T191852Z
UID:h9i3hjtisl53goaljdcdb681fc@google.com
RECURRENCE-ID;VALUE=DATE:20170130
CREATED:20160829T134437Z
DESCRIPTION:
LAST-MODIFIED:20160829T134450Z
LOCATION:
SEQUENCE:2
STATUS:CONFIRMED
SUMMARY:B
TRANSP:TRANSPARENT
END:VEVENT
BEGIN:VEVENT
DTSTART;VALUE=DATE:20170127
DTEND;VALUE=DATE:20170128
DTSTAMP:20160829T191852Z
UID:h9i3hjtisl53goaljdcdb681fc@google.com
RECURRENCE-ID;VALUE=DATE:20170126
CREATED:20160829T134437Z
DESCRIPTION:
LAST-MODIFIED:20160829T134450Z
LOCATION:
SEQUENCE:2
STATUS:CONFIRMED
SUMMARY:B
TRANSP:TRANSPARENT
END:VEVENT
BEGIN:VEVENT
DTSTART;VALUE=DATE:20170125
DTEND;VALUE=DATE:20170126
DTSTAMP:20160829T191852Z
UID:h9i3hjtisl53goaljdcdb681fc@google.com
RECURRENCE-ID;VALUE=DATE:20170124
CREATED:20160829T134437Z
DESCRIPTION:
LAST-MODIFIED:20160829T134450Z
LOCATION:
SEQUENCE:2
STATUS:CONFIRMED
SUMMARY:B
TRANSP:TRANSPARENT
END:VEVENT
BEGIN:VEVENT
DTSTART;VALUE=DATE:20170123
DTEND;VALUE=DATE:20170124
DTSTAMP:20160829T191852Z
UID:h9i3hjtisl53goaljdcdb681fc@google.com
RECURRENCE-ID;VALUE=DATE:20170122
CREATED:20160829T134437Z
DESCRIPTION:
LAST-MODIFIED:20160829T134450Z
LOCATION:
SEQUENCE:2
STATUS:CONFIRMED
SUMMARY:B
TRANSP:TRANSPARENT
END:VEVENT
BEGIN:VEVENT
DTSTART;VALUE=DATE:20170119
DTEND;VALUE=DATE:20170120
DTSTAMP:20160829T191852Z
UID:h9i3hjtisl53goaljdcdb681fc@google.com
RECURRENCE-ID;VALUE=DATE:20170118
CREATED:20160829T134437Z
DESCRIPTION:
LAST-MODIFIED:20160829T134450Z
LOCATION:
SEQUENCE:2
STATUS:CONFIRMED
SUMMARY:B
TRANSP:TRANSPARENT
END:VEVENT
BEGIN:VEVENT
DTSTART;VALUE=DATE:20170113
DTEND;VALUE=DATE:20170114
DTSTAMP:20160829T191852Z
UID:h9i3hjtisl53goaljdcdb681fc@google.com
RECURRENCE-ID;VALUE=DATE:20170112
CREATED:20160829T134437Z
DESCRIPTION:
LAST-MODIFIED:20160829T134450Z
LOCATION:
SEQUENCE:2
STATUS:CONFIRMED
SUMMARY:B
TRANSP:TRANSPARENT
END:VEVENT
BEGIN:VEVENT
DTSTART;VALUE=DATE:20170111
DTEND;VALUE=DATE:20170112
DTSTAMP:20160829T191852Z
UID:h9i3hjtisl53goaljdcdb681fc@google.com
RECURRENCE-ID;VALUE=DATE:20170110
CREATED:20160829T134437Z
DESCRIPTION:
LAST-MODIFIED:20160829T134450Z
LOCATION:
SEQUENCE:2
STATUS:CONFIRMED
SUMMARY:B
TRANSP:TRANSPARENT
END:VEVENT
BEGIN:VEVENT
DTSTART;VALUE=DATE:20170109
DTEND;VALUE=DATE:20170110
DTSTAMP:20160829T191852Z
UID:h9i3hjtisl53goaljdcdb681fc@google.com
RECURRENCE-ID;VALUE=DATE:20170108
CREATED:20160829T134437Z
DESCRIPTION:
LAST-MODIFIED:20160829T134450Z
LOCATION:
SEQUENCE:2
STATUS:CONFIRMED
SUMMARY:B
TRANSP:TRANSPARENT
END:VEVENT
BEGIN:VEVENT
DTSTART;VALUE=DATE:20170105
DTEND;VALUE=DATE:20170106
DTSTAMP:20160829T191852Z
UID:h9i3hjtisl53goaljdcdb681fc@google.com
RECURRENCE-ID;VALUE=DATE:20170104
CREATED:20160829T134437Z
DESCRIPTION:
LAST-MODIFIED:20160829T134450Z
LOCATION:
SEQUENCE:2
STATUS:CONFIRMED
SUMMARY:B
TRANSP:TRANSPARENT
END:VEVENT
BEGIN:VEVENT
DTSTART;VALUE=DATE:20170103
DTEND;VALUE=DATE:20170104
DTSTAMP:20160829T191852Z
UID:h9i3hjtisl53goaljdcdb681fc@google.com
RECURRENCE-ID;VALUE=DATE:20170102
CREATED:20160829T134437Z
DESCRIPTION:
LAST-MODIFIED:20160829T134450Z
LOCATION:
SEQUENCE:2
STATUS:CONFIRMED
SUMMARY:B
TRANSP:TRANSPARENT
END:VEVENT
BEGIN:VEVENT
DTSTART;VALUE=DATE:20161122
DTEND;VALUE=DATE:20161123
DTSTAMP:20160829T191852Z
UID:h9i3hjtisl53goaljdcdb681fc@google.com
RECURRENCE-ID;VALUE=DATE:20161121
CREATED:20160829T134437Z
DESCRIPTION:
LAST-MODIFIED:20160829T134450Z
LOCATION:
SEQUENCE:2
STATUS:CONFIRMED
SUMMARY:B
TRANSP:TRANSPARENT
END:VEVENT
BEGIN:VEVENT
DTSTART;VALUE=DATE:20161118
DTEND;VALUE=DATE:20161119
DTSTAMP:20160829T191852Z
UID:h9i3hjtisl53goaljdcdb681fc@google.com
RECURRENCE-ID;VALUE=DATE:20161117
CREATED:20160829T134437Z
DESCRIPTION:
LAST-MODIFIED:20160829T134450Z
LOCATION:
SEQUENCE:2
STATUS:CONFIRMED
SUMMARY:B
TRANSP:TRANSPARENT
END:VEVENT
BEGIN:VEVENT
DTSTART;VALUE=DATE:20161116
DTEND;VALUE=DATE:20161117
DTSTAMP:20160829T191852Z
UID:h9i3hjtisl53goaljdcdb681fc@google.com
RECURRENCE-ID;VALUE=DATE:20161115
CREATED:20160829T134437Z
DESCRIPTION:
LAST-MODIFIED:20160829T134450Z
LOCATION:
SEQUENCE:2
STATUS:CONFIRMED
SUMMARY:B
TRANSP:TRANSPARENT
END:VEVENT
BEGIN:VEVENT
DTSTART;VALUE=DATE:20161114
DTEND;VALUE=DATE:20161115
DTSTAMP:20160829T191852Z
UID:h9i3hjtisl53goaljdcdb681fc@google.com
RECURRENCE-ID;VALUE=DATE:20161113
CREATED:20160829T134437Z
DESCRIPTION:
LAST-MODIFIED:20160829T134450Z
LOCATION:
SEQUENCE:2
STATUS:CONFIRMED
SUMMARY:B
TRANSP:TRANSPARENT
END:VEVENT
BEGIN:VEVENT
DTSTART;VALUE=DATE:20161110
DTEND;VALUE=DATE:20161111
DTSTAMP:20160829T191852Z
UID:h9i3hjtisl53goaljdcdb681fc@google.com
RECURRENCE-ID;VALUE=DATE:20161109
CREATED:20160829T134437Z
DESCRIPTION:
LAST-MODIFIED:20160829T134450Z
LOCATION:
SEQUENCE:2
STATUS:CONFIRMED
SUMMARY:B
TRANSP:TRANSPARENT
END:VEVENT
BEGIN:VEVENT
DTSTART;VALUE=DATE:20160923
DTEND;VALUE=DATE:20160924
DTSTAMP:20160829T191852Z
UID:h9i3hjtisl53goaljdcdb681fc@google.com
RECURRENCE-ID;VALUE=DATE:20160922
CREATED:20160829T134437Z
DESCRIPTION:
LAST-MODIFIED:20160829T134450Z
LOCATION:
SEQUENCE:2
STATUS:CONFIRMED
SUMMARY:B
TRANSP:TRANSPARENT
END:VEVENT
BEGIN:VEVENT
DTSTART;VALUE=DATE:20160921
DTEND;VALUE=DATE:20160922
DTSTAMP:20160829T191852Z
UID:h9i3hjtisl53goaljdcdb681fc@google.com
RECURRENCE-ID;VALUE=DATE:20160920
CREATED:20160829T134437Z
DESCRIPTION:
LAST-MODIFIED:20160829T134450Z
LOCATION:
SEQUENCE:2
STATUS:CONFIRMED
SUMMARY:B
TRANSP:TRANSPARENT
END:VEVENT
BEGIN:VEVENT
DTSTART;VALUE=DATE:20160919
DTEND;VALUE=DATE:20160920
DTSTAMP:20160829T191852Z
UID:h9i3hjtisl53goaljdcdb681fc@google.com
RECURRENCE-ID;VALUE=DATE:20160916
CREATED:20160829T134437Z
DESCRIPTION:
LAST-MODIFIED:20160829T134450Z
LOCATION:
SEQUENCE:2
STATUS:CONFIRMED
SUMMARY:B
TRANSP:TRANSPARENT
END:VEVENT
BEGIN:VEVENT
DTSTART;VALUE=DATE:20160915
DTEND;VALUE=DATE:20160916
DTSTAMP:20160829T191852Z
UID:h9i3hjtisl53goaljdcdb681fc@google.com
RECURRENCE-ID;VALUE=DATE:20160914
CREATED:20160829T134437Z
DESCRIPTION:
LAST-MODIFIED:20160829T134450Z
LOCATION:
SEQUENCE:2
STATUS:CONFIRMED
SUMMARY:B
TRANSP:TRANSPARENT
END:VEVENT
BEGIN:VEVENT
DTSTART;VALUE=DATE:20160913
DTEND;VALUE=DATE:20160914
DTSTAMP:20160829T191852Z
UID:h9i3hjtisl53goaljdcdb681fc@google.com
RECURRENCE-ID;VALUE=DATE:20160912
CREATED:20160829T134437Z
DESCRIPTION:
LAST-MODIFIED:20160829T134450Z
LOCATION:
SEQUENCE:2
STATUS:CONFIRMED
SUMMARY:B
TRANSP:TRANSPARENT
END:VEVENT
BEGIN:VEVENT
DTSTART;VALUE=DATE:20160909
DTEND;VALUE=DATE:20160910
DTSTAMP:20160829T191852Z
UID:h9i3hjtisl53goaljdcdb681fc@google.com
RECURRENCE-ID;VALUE=DATE:20160908
CREATED:20160829T134437Z
DESCRIPTION:
LAST-MODIFIED:20160829T134450Z
LOCATION:
SEQUENCE:2
STATUS:CONFIRMED
SUMMARY:B
TRANSP:TRANSPARENT
END:VEVENT
BEGIN:VEVENT
DTSTART;VALUE=DATE:20160907
DTEND;VALUE=DATE:20160908
DTSTAMP:20160829T191852Z
UID:h9i3hjtisl53goaljdcdb681fc@google.com
RECURRENCE-ID;VALUE=DATE:20160906
CREATED:20160829T134437Z
DESCRIPTION:
LAST-MODIFIED:20160829T134450Z
LOCATION:
SEQUENCE:2
STATUS:CONFIRMED
SUMMARY:B
TRANSP:TRANSPARENT
END:VEVENT
BEGIN:VEVENT
DTSTART;VALUE=DATE:20160817
DTEND;VALUE=DATE:20160818
EXDATE;VALUE=DATE:20160821
EXDATE;VALUE=DATE:20160827
EXDATE;VALUE=DATE:20160904
EXDATE;VALUE=DATE:20160910
EXDATE;VALUE=DATE:20160918
EXDATE;VALUE=DATE:20160924
EXDATE;VALUE=DATE:20160926
EXDATE;VALUE=DATE:20161002
EXDATE;VALUE=DATE:20161008
EXDATE;VALUE=DATE:20161016
EXDATE;VALUE=DATE:20161022
EXDATE;VALUE=DATE:20161030
EXDATE;VALUE=DATE:20161105
EXDATE;VALUE=DATE:20161107
EXDATE;VALUE=DATE:20161111
EXDATE;VALUE=DATE:20161119
EXDATE;VALUE=DATE:20161123
EXDATE;VALUE=DATE:20161125
EXDATE;VALUE=DATE:20161127
EXDATE;VALUE=DATE:20161203
EXDATE;VALUE=DATE:20161211
EXDATE;VALUE=DATE:20161217
EXDATE;VALUE=DATE:20161219
EXDATE;VALUE=DATE:20161221
EXDATE;VALUE=DATE:20161223
EXDATE;VALUE=DATE:20161225
EXDATE;VALUE=DATE:20161227
EXDATE;VALUE=DATE:20161229
EXDATE;VALUE=DATE:20161231
EXDATE;VALUE=DATE:20170106
EXDATE;VALUE=DATE:20170114
EXDATE;VALUE=DATE:20170116
EXDATE;VALUE=DATE:20170120
EXDATE;VALUE=DATE:20170128
EXDATE;VALUE=DATE:20170203
EXDATE;VALUE=DATE:20170211
EXDATE;VALUE=DATE:20170217
EXDATE;VALUE=DATE:20170219
EXDATE;VALUE=DATE:20170225
EXDATE;VALUE=DATE:20170305
EXDATE;VALUE=DATE:20170311
EXDATE;VALUE=DATE:20170319
EXDATE;VALUE=DATE:20170325
EXDATE;VALUE=DATE:20170327
EXDATE;VALUE=DATE:20170402
EXDATE;VALUE=DATE:20170408
EXDATE;VALUE=DATE:20170410
EXDATE;VALUE=DATE:20170412
EXDATE;VALUE=DATE:20170414
EXDATE;VALUE=DATE:20170416
EXDATE;VALUE=DATE:20170422
EXDATE;VALUE=DATE:20170430
EXDATE;VALUE=DATE:20170506
EXDATE;VALUE=DATE:20170514
EXDATE;VALUE=DATE:20170520
EXDATE;VALUE=DATE:20170528
RRULE:FREQ=DAILY;UNTIL=20170601;INTERVAL=2
DTSTAMP:20160829T191852Z
UID:h9i3hjtisl53goaljdcdb681fc@google.com
CREATED:20160829T134437Z
DESCRIPTION:
LAST-MODIFIED:20160829T134450Z
LOCATION:
SEQUENCE:1
STATUS:CONFIRMED
SUMMARY:B
TRANSP:TRANSPARENT
END:VEVENT
BEGIN:VEVENT
DTSTART;VALUE=DATE:20170601
DTEND;VALUE=DATE:20170602
DTSTAMP:20160829T191852Z
UID:h9i3hjtisl53goaljdcdb681fc@google.com
RECURRENCE-ID;VALUE=DATE:20170526
CREATED:20160829T134437Z
DESCRIPTION:
LAST-MODIFIED:20160829T134450Z
LOCATION:
SEQUENCE:6
STATUS:CONFIRMED
SUMMARY:A
TRANSP:TRANSPARENT
END:VEVENT
END:VCALENDAR

View File

@ -0,0 +1,57 @@
BEGIN:VCALENDAR
PRODID:-//Google Inc//Google Calendar 70.9054//EN
VERSION:2.0
CALSCALE:GREGORIAN
METHOD:PUBLISH
X-WR-CALNAME:G. C. Hawley Middle School
X-WR-TIMEZONE:America/New_York
X-WR-CALDESC:This is the website calendar for GC Hawley MS.
BEGIN:VTIMEZONE
TZID:America/New_York
X-LIC-LOCATION:America/New_York
BEGIN:DAYLIGHT
TZOFFSETFROM:-0500
TZOFFSETTO:-0400
TZNAME:EDT
DTSTART:19700308T020000
RRULE:FREQ=YEARLY;BYMONTH=3;BYDAY=2SU
END:DAYLIGHT
BEGIN:STANDARD
TZOFFSETFROM:-0400
TZOFFSETTO:-0500
TZNAME:EST
DTSTART:19701101T020000
RRULE:FREQ=YEARLY;BYMONTH=11;BYDAY=1SU
END:STANDARD
END:VTIMEZONE
BEGIN:VEVENT
DTSTART;TZID=America/New_York:20160915T123000
DTEND;TZID=America/New_York:20160915T160000
RRULE:FREQ=MONTHLY;UNTIL=20161020T035959Z;BYDAY=3TH
DTSTAMP:20160913T221241Z
UID:d28i2lkvhp2qb2v7n6oe9poikc@google.com
CREATED:20160705T193430Z
DESCRIPTION:Professional Development for Staff
LAST-MODIFIED:20160825T003008Z
LOCATION:
SEQUENCE:1
STATUS:CONFIRMED
SUMMARY:Early Release for Students
TRANSP:OPAQUE
END:VEVENT
BEGIN:VEVENT
DTSTART;TZID=America/New_York:20160929T123000
DTEND;TZID=America/New_York:20160929T160000
DTSTAMP:20160913T221241Z
UID:d28i2lkvhp2qb2v7n6oe9poikc@google.com
RECURRENCE-ID;TZID=America/New_York:20160915T123000
CREATED:20160705T193430Z
DESCRIPTION:Professional Development for Staff
LAST-MODIFIED:20160825T003008Z
LOCATION:
SEQUENCE:2
STATUS:CONFIRMED
SUMMARY:Early Release for Students
TRANSP:OPAQUE
END:VEVENT
END:VCALENDAR

View File

@ -0,0 +1,27 @@
BEGIN:VCALENDAR
VERSION:2.0
PRODID:Zimbra-Calendar-Provider
BEGIN:VTIMEZONE
TZID:Etc/GMT
BEGIN:STANDARD
DTSTART:19710101T000000
TZOFFSETTO:-0000
TZOFFSETFROM:-0000
TZNAME:GMT
END:STANDARD
END:VTIMEZONE
BEGIN:VEVENT
UID:d118e997-3683-4552-8fe8-57c641f1f179
SUMMARY:And another
ORGANIZER;CN=Sahaja Lal:mailto:calmozilla1@yahoo.com
DTSTART;TZID=Etc/GMT:20120821T210000
DTEND;TZID=Etc/GMT:20120821T213000
STATUS:CONFIRMED
CLASS:PUBLIC
X-MICROSOFT-CDO-INTENDEDSTATUS:BUSY
TRANSP:OPAQUE
X-MICROSOFT-DISALLOW-COUNTER:TRUE
DTSTAMP:20120817T032509Z
SEQUENCE:0
END:VEVENT
END:VCALENDAR

View File

@ -0,0 +1,237 @@
BEGIN:VCALENDAR
METHOD:PUBLISH
PRODID:Microsoft Exchange Server 2010
VERSION:2.0
X-WR-CALNAME:High School Counselors Office
BEGIN:VTIMEZONE
TZID:(UTC-06:00) Central Time (US & Canada)
BEGIN:STANDARD
DTSTART:16010101T020000
TZOFFSETFROM:-0500
TZOFFSETTO:-0600
RRULE:FREQ=YEARLY;INTERVAL=1;BYDAY=1SU;BYMONTH=11
END:STANDARD
BEGIN:DAYLIGHT
DTSTART:16010101T020000
TZOFFSETFROM:-0600
TZOFFSETTO:-0500
RRULE:FREQ=YEARLY;INTERVAL=1;BYDAY=2SU;BYMONTH=3
END:DAYLIGHT
END:VTIMEZONE
BEGIN:VTIMEZONE
TZID:Eastern Time
BEGIN:STANDARD
DTSTART:16010101T020000
TZOFFSETFROM:-0400
TZOFFSETTO:-0500
RRULE:FREQ=YEARLY;INTERVAL=1;BYDAY=1SU;BYMONTH=11
END:STANDARD
BEGIN:DAYLIGHT
DTSTART:16010101T020000
TZOFFSETFROM:-0500
TZOFFSETTO:-0400
RRULE:FREQ=YEARLY;INTERVAL=1;BYDAY=2SU;BYMONTH=3
END:DAYLIGHT
END:VTIMEZONE
BEGIN:VTIMEZONE
TZID:Greenwich Standard Time
BEGIN:STANDARD
DTSTART:16010101T000000
TZOFFSETFROM:+0000
TZOFFSETTO:+0000
END:STANDARD
BEGIN:DAYLIGHT
DTSTART:16010101T000000
TZOFFSETFROM:+0000
TZOFFSETTO:+0000
END:DAYLIGHT
END:VTIMEZONE
BEGIN:VEVENT
DESCRIPTION:All seniors MUST make an appointment in the counseling office\,
to visit with a counselor and go over their application for graduation.\n
UID:040000008200E00074C5B7101A82E008000000004A8A50D0FC09D201000000000000000
010000000D27D08FB73761145BC661D80CE521463
SUMMARY:Senior Appointment Sign-up
DTSTART;VALUE=DATE:20160914
DTEND;VALUE=DATE:20160915
CLASS:PUBLIC
PRIORITY:5
DTSTAMP:20160916T193959Z
TRANSP:OPAQUE
STATUS:CONFIRMED
SEQUENCE:0
LOCATION:
X-MICROSOFT-CDO-APPT-SEQUENCE:0
X-MICROSOFT-CDO-BUSYSTATUS:FREE
X-MICROSOFT-CDO-INTENDEDSTATUS:BUSY
X-MICROSOFT-CDO-ALLDAYEVENT:TRUE
X-MICROSOFT-CDO-IMPORTANCE:1
X-MICROSOFT-CDO-INSTTYPE:0
X-MICROSOFT-DISALLOW-COUNTER:FALSE
END:VEVENT
BEGIN:VEVENT
DESCRIPTION:Registration for the PSAT test begins in the counseling office.
The test is open to any junior or sophomore. The test is $15 and must be
paid at the time of registration. Test date is Wednesday\, October 19th.\n
UID:040000008200E00074C5B7101A82E008000000004B8D8376DB0AD201000000000000000
010000000CF196AE75B9C684C9E51C33A403CA455
SUMMARY:PSAT Registration
DTSTART;VALUE=DATE:20160915
DTEND;VALUE=DATE:20160916
CLASS:PUBLIC
PRIORITY:5
DTSTAMP:20160916T193959Z
TRANSP:OPAQUE
STATUS:CONFIRMED
SEQUENCE:0
LOCATION:
X-MICROSOFT-CDO-APPT-SEQUENCE:0
X-MICROSOFT-CDO-BUSYSTATUS:FREE
X-MICROSOFT-CDO-INTENDEDSTATUS:BUSY
X-MICROSOFT-CDO-ALLDAYEVENT:TRUE
X-MICROSOFT-CDO-IMPORTANCE:1
X-MICROSOFT-CDO-INSTTYPE:0
X-MICROSOFT-DISALLOW-COUNTER:FALSE
END:VEVENT
BEGIN:VEVENT
DESCRIPTION:Financial Aid night for all seniors and their parents at 7:00pm
in the high school auditorium.\n
UID:040000008200E00074C5B7101A82E00800000000A3D802C7DB0AD201000000000000000
0100000004690B516982D4841A6A5808F1BF285D2
SUMMARY:Financial Aid NIght
DTSTART;TZID="(UTC-06:00) Central Time (US & Canada)":20160919T190000
DTEND;TZID="(UTC-06:00) Central Time (US & Canada)":20160919T200000
CLASS:PUBLIC
PRIORITY:5
DTSTAMP:20160916T193959Z
TRANSP:OPAQUE
STATUS:CONFIRMED
SEQUENCE:0
LOCATION:
X-MICROSOFT-CDO-APPT-SEQUENCE:0
X-MICROSOFT-CDO-BUSYSTATUS:BUSY
X-MICROSOFT-CDO-INTENDEDSTATUS:BUSY
X-MICROSOFT-CDO-ALLDAYEVENT:FALSE
X-MICROSOFT-CDO-IMPORTANCE:1
X-MICROSOFT-CDO-INSTTYPE:0
X-MICROSOFT-DISALLOW-COUNTER:FALSE
END:VEVENT
BEGIN:VEVENT
DESCRIPTION:This is the last day to register for the PSAT test in October!
Please see the counseling office if you would like to register.\n
UID:040000008200E00074C5B7101A82E00800000000DE3BE28BDB0AD201000000000000000
0100000008C413809A1751A4E82CEB8F1BB526C61
SUMMARY:PSAT Test registration ends
DTSTART;VALUE=DATE:20160923
DTEND;VALUE=DATE:20160924
CLASS:PUBLIC
PRIORITY:5
DTSTAMP:20160916T193959Z
TRANSP:OPAQUE
STATUS:CONFIRMED
SEQUENCE:0
LOCATION:
X-MICROSOFT-CDO-APPT-SEQUENCE:0
X-MICROSOFT-CDO-BUSYSTATUS:FREE
X-MICROSOFT-CDO-INTENDEDSTATUS:BUSY
X-MICROSOFT-CDO-ALLDAYEVENT:TRUE
X-MICROSOFT-CDO-IMPORTANCE:1
X-MICROSOFT-CDO-INSTTYPE:0
X-MICROSOFT-DISALLOW-COUNTER:FALSE
END:VEVENT
BEGIN:VEVENT
DESCRIPTION:College Application Day for all interested seniors! The Bank of
North Dakota is waiving the application fee for any student to apply to a
North Dakota college or university. Counselors and college staff will be
assisting students with their applications periods 1-3 in the high school
library!\n
UID:040000008200E00074C5B7101A82E0080000000019668644DC0AD201000000000000000
010000000DB1D0B39660D4045A6AC5C232EB0D76B
SUMMARY:College Application Day
DTSTART;TZID="(UTC-06:00) Central Time (US & Canada)":20161005T080000
DTEND;TZID="(UTC-06:00) Central Time (US & Canada)":20161005T081500
CLASS:PUBLIC
PRIORITY:5
DTSTAMP:20160916T193959Z
TRANSP:OPAQUE
STATUS:CONFIRMED
SEQUENCE:0
LOCATION:
X-MICROSOFT-CDO-APPT-SEQUENCE:0
X-MICROSOFT-CDO-BUSYSTATUS:BUSY
X-MICROSOFT-CDO-INTENDEDSTATUS:BUSY
X-MICROSOFT-CDO-ALLDAYEVENT:FALSE
X-MICROSOFT-CDO-IMPORTANCE:1
X-MICROSOFT-CDO-INSTTYPE:0
X-MICROSOFT-DISALLOW-COUNTER:FALSE
END:VEVENT
BEGIN:VEVENT
DESCRIPTION:PSAT Test in the high school auditorium for all students that r
egistered. Please report to the auditorium at 8:30am with a sharpened #2 p
encil and calculator.\n
UID:040000008200E00074C5B7101A82E00800000000E68A2E67DC0AD201000000000000000
01000000080E5BC118E41944ABC1C94B815AB2235
SUMMARY:PSAT Test
DTSTART;VALUE=DATE:20161019
DTEND;VALUE=DATE:20161020
CLASS:PUBLIC
PRIORITY:5
DTSTAMP:20160916T193959Z
TRANSP:OPAQUE
STATUS:CONFIRMED
SEQUENCE:0
LOCATION:
X-MICROSOFT-CDO-APPT-SEQUENCE:0
X-MICROSOFT-CDO-BUSYSTATUS:FREE
X-MICROSOFT-CDO-INTENDEDSTATUS:BUSY
X-MICROSOFT-CDO-ALLDAYEVENT:TRUE
X-MICROSOFT-CDO-IMPORTANCE:1
X-MICROSOFT-CDO-INSTTYPE:0
X-MICROSOFT-DISALLOW-COUNTER:FALSE
END:VEVENT
BEGIN:VEVENT
DESCRIPTION:North Dakota State Assessment for all juniors (periods 2-4).\n
UID:040000008200E00074C5B7101A82E008000000002EB6D123DD0AD201000000000000000
01000000061F7AF4CD0D2C84B9C6A916D2C633339
SUMMARY:NDSA Science Assessment
DTSTART;TZID="(UTC-06:00) Central Time (US & Canada)":20161025T091500
DTEND;TZID="(UTC-06:00) Central Time (US & Canada)":20161025T114500
CLASS:PUBLIC
PRIORITY:5
DTSTAMP:20160916T193959Z
TRANSP:OPAQUE
STATUS:CONFIRMED
SEQUENCE:0
LOCATION:
X-MICROSOFT-CDO-APPT-SEQUENCE:0
X-MICROSOFT-CDO-BUSYSTATUS:BUSY
X-MICROSOFT-CDO-INTENDEDSTATUS:BUSY
X-MICROSOFT-CDO-ALLDAYEVENT:FALSE
X-MICROSOFT-CDO-IMPORTANCE:1
X-MICROSOFT-CDO-INSTTYPE:0
X-MICROSOFT-DISALLOW-COUNTER:FALSE
END:VEVENT
BEGIN:VEVENT
DESCRIPTION:\n
UID:040000008200E00074C5B7101A82E0080000000052D533E856D6D301000000000000000
010000000568B47E6EF679B4B812809E063BB64E1
SUMMARY:Test Event
DTSTART;TZID=Eastern Time:20180419T103000
DTEND;TZID=Eastern Time:20180419T113000
CLASS:PUBLIC
PRIORITY:5
DTSTAMP:20180417T144309Z
TRANSP:OPAQUE
STATUS:CONFIRMED
SEQUENCE:0
LOCATION:Boardroom
X-MICROSOFT-CDO-APPT-SEQUENCE:0
X-MICROSOFT-CDO-BUSYSTATUS:BUSY
X-MICROSOFT-CDO-INTENDEDSTATUS:BUSY
X-MICROSOFT-CDO-ALLDAYEVENT:FALSE
X-MICROSOFT-CDO-IMPORTANCE:1
X-MICROSOFT-CDO-INSTTYPE:0
X-MICROSOFT-DONOTFORWARDMEETING:FALSE
X-MICROSOFT-DISALLOW-COUNTER:FALSE
END:VEVENT
END:VCALENDAR

View File

@ -0,0 +1,37 @@
BEGIN:VCALENDAR
PRODID:-//Google Inc//Google Calendar 70.9054//EN
VERSION:2.0
CALSCALE:GREGORIAN
X-WR-CALNAME:calmozilla1@gmail.com
X-WR-TIMEZONE:America/Los_Angeles
BEGIN:VTIMEZONE
TZID:America/Los_Angeles
X-LIC-LOCATION:America/Los_Angeles
END:VTIMEZONE
BEGIN:VEVENT
DTSTART;VALUE=DATE:2014929
DTEND;VALUE=DATE:20140930
UID:dn4vrfmfn5p05roahsopg57h48@google.com
CREATED:20120724T212411Z
DESCRIPTION:
LAST-MODIFIED:20120724T212411Z
LOCATION:
SEQUENCE:0
STATUS:CONFIRMED
SUMMARY:Really long event name thing
TRANSP:OPAQUE
END:VEVENT
BEGIN:VEVENT
DTSTART;VALUE=DATE:20140929
DTEND;VALUE=DATE:2014930
UID:dn4vrfmfn5p05roahsopg57h48@google.com
CREATED:20120724T212411Z
DESCRIPTION:
LAST-MODIFIED:20120724T212411Z
LOCATION:
SEQUENCE:0
STATUS:CONFIRMED
SUMMARY:Really long event name thing
TRANSP:OPAQUE
END:VEVENT
END:VCALENDAR

View File

@ -0,0 +1,18 @@
<?php
/**
* @author Aaron Parecki <aaron@parecki.com>
*/
use Tester\Assert;
use Tester\Environment;
require_once __DIR__ . '/../vendor/autoload.php';
Environment::setup();
date_default_timezone_set('Europe/Prague');
// sort by date
$cal = new \om\IcalParser();
$results = $cal->parseFile(__DIR__ . '/cal/multiline_description.ics');
$events = $cal->getSortedEvents();
Assert::same('30.6.2012 06:00:00', $events[0]['DTSTART']->format('j.n.Y H:i:s'));
Assert::same("Here is a description that spans multiple lines!\n\nThis should be on a new line as well because the description contains newline characters.", $events[0]['DESCRIPTION']);

View File

@ -0,0 +1,20 @@
<?php
/**
* @author PC Drew <pc@soprisapps.com>
*/
use Tester\Assert;
require_once __DIR__ . '/../vendor/autoload.php';
\Tester\Environment::setup();
date_default_timezone_set('Europe/Prague');
$cal = new \om\IcalParser();
$results = $cal->parseFile(__DIR__ . '/cal/multiple_attachments.ics');
// Backwards compatibility, there is only ever one key displayed
Assert::type('string', $results['VEVENT'][0]['ATTACH']);
// The new key 'ATTACHMENTS' is an array with 1 or more attachments
Assert::type('array', $results['VEVENT'][0]['ATTACHMENTS']);
Assert::count(2, $results['VEVENT'][0]['ATTACHMENTS']);

View File

@ -0,0 +1,170 @@
<?php
/**
* @author PC Drew <pc@schoolblocks.com>
*/
use Tester\Assert;
use Tester\Environment;
require_once __DIR__ . '/../vendor/autoload.php';
Environment::setup();
$cal = new \om\IcalParser();
$results = $cal->parseFile(__DIR__ . '/cal/recur_instances_finite.ics');
$events = $cal->getSortedEvents();
// DTSTART;TZID=America/Los_Angeles:20121002T100000
// DTEND;TZID=America/Los_Angeles:20121002T103000
// RRULE:FREQ=MONTHLY;INTERVAL=1;BYDAY=1TU;UNTIL=20121231T100000
// RDATE;TZID=America/Los_Angeles:20121110T100000
// RDATE;TZID=America/Los_Angeles:20121105T100000
Assert::equal(5, sizeof($events));
Assert::equal('2.10.2012 10:00:00', $events[0]['DTSTART']->format('j.n.Y H:i:s'));
Assert::equal('5.11.2012 10:00:00', $events[1]['DTSTART']->format('j.n.Y H:i:s'));
Assert::equal('6.11.2012 10:00:00', $events[2]['DTSTART']->format('j.n.Y H:i:s'));
Assert::equal('10.11.2012 10:00:00', $events[3]['DTSTART']->format('j.n.Y H:i:s'));
Assert::equal('4.12.2012 10:00:00', $events[4]['DTSTART']->format('j.n.Y H:i:s'));
$results = $cal->parseFile(__DIR__ . '/cal/recur_instances.ics');
$events = $cal->getSortedEvents();
$recurrences = [];
foreach($events as $i => $event) {
$recurrences[] = $event['DTSTART'];
}
// DTSTART;TZID=America/Los_Angeles:20121002T100000
// DTEND;TZID=America/Los_Angeles:20121002T103000
// RRULE:FREQ=MONTHLY;INTERVAL=1;BYDAY=1TU
// RDATE;TZID=America/Los_Angeles:20121105T100000
// RDATE;TZID=America/Los_Angeles:20121110T100000,20121130T100000
// EXDATE;TZID=America/Los_Angeles:20130402T100000
// EXDATE;TZID=America/Los_Angeles:20121204T100000
// EXDATE;TZID=America/Los_Angeles:20130205T100000
// total = 36 events - 3 exclusions + 3 additions
// because there is no "UNTIL", we only calculate the next 3 years of repeating events
Assert::equal(35, sizeof($recurrences));
Assert::equal('02.10.2012 15:00:00', $recurrences[0]->format('d.m.Y H:i:s'));
Assert::equal('06.11.2012 20:00:00', $recurrences[1]->format('d.m.Y H:i:s'));
Assert::equal('10.11.2012 10:00:00', $recurrences[2]->format('d.m.Y H:i:s'));
Assert::equal('30.11.2012 10:00:00', $recurrences[3]->format('d.m.Y H:i:s'));
Assert::equal('01.01.2013 10:00:00', $recurrences[4]->format('d.m.Y H:i:s'));
Assert::equal('05.03.2013 10:00:00', $recurrences[5]->format('d.m.Y H:i:s'));
Assert::equal('07.05.2013 10:00:00', $recurrences[6]->format('d.m.Y H:i:s'));
Assert::equal('04.06.2013 10:00:00', $recurrences[7]->format('d.m.Y H:i:s'));
Assert::equal('02.07.2013 10:00:00', $recurrences[8]->format('d.m.Y H:i:s'));
Assert::equal('06.08.2013 10:00:00', $recurrences[9]->format('d.m.Y H:i:s'));
Assert::equal('03.09.2013 10:00:00', $recurrences[10]->format('d.m.Y H:i:s'));
Assert::equal('01.10.2013 10:00:00', $recurrences[11]->format('d.m.Y H:i:s'));
Assert::equal('05.11.2013 10:00:00', $recurrences[12]->format('d.m.Y H:i:s'));
Assert::equal('03.12.2013 10:00:00', $recurrences[13]->format('d.m.Y H:i:s'));
Assert::equal('07.01.2014 10:00:00', $recurrences[14]->format('d.m.Y H:i:s'));
Assert::equal('04.02.2014 10:00:00', $recurrences[15]->format('d.m.Y H:i:s'));
Assert::equal('04.03.2014 10:00:00', $recurrences[16]->format('d.m.Y H:i:s'));
Assert::equal('01.04.2014 10:00:00', $recurrences[17]->format('d.m.Y H:i:s'));
Assert::equal('06.05.2014 10:00:00', $recurrences[18]->format('d.m.Y H:i:s'));
Assert::equal('03.06.2014 10:00:00', $recurrences[19]->format('d.m.Y H:i:s'));
Assert::equal('01.07.2014 10:00:00', $recurrences[20]->format('d.m.Y H:i:s'));
Assert::equal('05.08.2014 10:00:00', $recurrences[21]->format('d.m.Y H:i:s'));
Assert::equal('02.09.2014 10:00:00', $recurrences[22]->format('d.m.Y H:i:s'));
Assert::equal('07.10.2014 10:00:00', $recurrences[23]->format('d.m.Y H:i:s'));
Assert::equal('04.11.2014 10:00:00', $recurrences[24]->format('d.m.Y H:i:s'));
Assert::equal('02.12.2014 10:00:00', $recurrences[25]->format('d.m.Y H:i:s'));
Assert::equal('06.01.2015 10:00:00', $recurrences[26]->format('d.m.Y H:i:s'));
Assert::equal('03.02.2015 10:00:00', $recurrences[27]->format('d.m.Y H:i:s'));
Assert::equal('03.03.2015 10:00:00', $recurrences[28]->format('d.m.Y H:i:s'));
Assert::equal('07.04.2015 10:00:00', $recurrences[29]->format('d.m.Y H:i:s'));
Assert::equal('05.05.2015 10:00:00', $recurrences[30]->format('d.m.Y H:i:s'));
Assert::equal('02.06.2015 10:00:00', $recurrences[31]->format('d.m.Y H:i:s'));
Assert::equal('07.07.2015 10:00:00', $recurrences[32]->format('d.m.Y H:i:s'));
Assert::equal('04.08.2015 10:00:00', $recurrences[33]->format('d.m.Y H:i:s'));
Assert::equal('01.09.2015 10:00:00', $recurrences[34]->format('d.m.Y H:i:s'));
foreach ($events[0]['EXDATES'] as $exDate) {
Assert::notContains($exDate, $recurrences);
}
$results = $cal->parseFile(__DIR__ . '/cal/recur_instances_with_modifications.ics');
$events = $cal->getSortedEvents(true);
Assert::false(empty($events[0]['RECURRENCES']));
// the 12th entry is the modified event, related to the remaining recurring events
Assert::true(empty($events[12]['RECURRENCES']));
$recurrences = $events[0]['RECURRENCES'];
$modifiedEvent = $events[12];
// There should be 35 total recurrences because the modified event should've removed 1 recurrence
Assert::equal(35, sizeof($recurrences));
// There should be 36 total events because of the modified event + 35 recurrences
Assert::equal(36, sizeof($events));
Assert::notContains($modifiedEvent['DTSTART'], $recurrences);
$results = $cal->parseFile(__DIR__ . '/cal/recur_instances_with_modifications_and_interval.ics');
// Build the cache of RECURRENCE-IDs and EXDATES first, so that we can properly determine the interval
$eventCache = array();
foreach($results['VEVENT'] as $event) {
$eventSequence = empty($event['SEQUENCE']) ? "0" : $event['SEQUENCE'];
$eventRecurrenceID = empty($event['RECURRENCE-ID']) ? "0" : $event['RECURRENCE-ID'];
$eventCache[$event['UID']][$eventRecurrenceID][$eventSequence] = $event;
}
$trueEvents = array();
foreach($results['VEVENT'] as $event) {
if(empty($event['RECURRENCES'])) {
$trueEvents[] = $event;
} else {
$eventUID = $event['UID'];
foreach($event['RECURRENCES'] as $recurrence) {
$eventRecurrenceID = $recurrence->format("Ymd");
if(empty($eventCache[$eventUID][$eventRecurrenceID])) {
$trueEvents[$eventRecurrenceID] = array('DTSTART' => $recurrence);
} else {
krsort($eventCache[$eventUID][$eventRecurrenceID]);
$keys = array_keys($eventCache[$eventUID][$eventRecurrenceID]);
$trueEvents[$eventRecurrenceID] = $eventCache[$eventUID][$eventRecurrenceID][$keys[0]];
}
}
}
}
usort($trueEvents, function ($a, $b) {
return $a['DTSTART'] > $b['DTSTART'];
});
$events = $cal->getSortedEvents(true);
Assert::false(empty($events[0]['RECURRENCES']));
Assert::equal(count($trueEvents), count($events));
foreach($trueEvents as $index => $trueEvent) {
Assert::equal($trueEvent['DTSTART']->format("Ymd"), $events[$index]['DTSTART']->format("Ymd"));
}
// There is still an issue that needs to be resolved when modifications are made to the initial event that is the
// base of the recurrences. The below ICS file has a great edge case example: one event, no recurrences in the
// recurring ruleset, and a modification to the initial event.
$results = $cal->parseFile(__DIR__ . '/cal/recur_instances_with_modifications_to_first_day.ics');
$events = $cal->getSortedEvents();
Assert::true(empty($events[0]['RECURRENCES'])); // edited event
Assert::true(empty($events[1]['RECURRENCES'])); // recurring event base with no recurrences
Assert::equal(1, count($events));
$results = $cal->parseFile(__DIR__ . '/cal/daily_recur.ics');
$events = $cal->getSortedEvents();
$period = new DatePeriod(new DateTime('20120801T050000'), new DateInterval('P1D'), 365 * 3);
foreach($period as $i => $day) {
Assert::equal($day->format('j.n.Y H:i:s'), $events[$i]['DTSTART']->format('j.n.Y H:i:s'));
}
$results = $cal->parseFile(__DIR__ . '/cal/daily_recur2.ics');
$events = $cal->getSortedEvents();
Assert::equal(4, sizeof($events));
Assert::equal('21.8.2017 00:00:00', $events[0]['DTSTART']->format('j.n.Y H:i:s'));
Assert::equal('28.8.2017 00:00:00', $events[1]['DTSTART']->format('j.n.Y H:i:s'));
Assert::equal('4.9.2017 00:00:00', $events[2]['DTSTART']->format('j.n.Y H:i:s'));
Assert::equal('11.9.2017 00:00:00', $events[3]['DTSTART']->format('j.n.Y H:i:s'));

View File

@ -0,0 +1,29 @@
<?php
/**
* @author Roman Ozana <ozana@omdesign.cz>
*/
use Tester\Assert;
use Tester\Environment;
require_once __DIR__ . '/../vendor/autoload.php';
Environment::setup();
date_default_timezone_set('Europe/Prague');
// sort by date
$cal = new \om\IcalParser();
$results = $cal->parseFile(__DIR__ . '/cal/basic.ics');
$events = $cal->getSortedEvents();
Assert::same('1.1.2013 00:00:00', $events[0]['DTSTART']->format('j.n.Y H:i:s'));
// reverse sort (parseFile)
$cal = new \om\IcalParser();
$results = $cal->parseFile(__DIR__ . '/cal/basic.ics');
$events = $cal->getReverseSortedEvents();
Assert::same('26.12.2015 00:00:00', $events[0]['DTSTART']->format('j.n.Y H:i:s'));
// reverse sort (parseString)
$cal = new \om\IcalParser();
$results = $cal->parseString(file_get_contents(__DIR__ . '/cal/basic.ics'));
$events = $cal->getReverseSortedEvents();
Assert::same('26.12.2015 00:00:00', $events[0]['DTSTART']->format('j.n.Y H:i:s'));

View File

@ -0,0 +1,28 @@
<?php
/**
* @author Marc Vachette <marc.vachette@gmail.com>
*/
use Tester\Assert;
use Tester\Environment;
require_once __DIR__ . '/../vendor/autoload.php';
Environment::setup();
date_default_timezone_set('Europe/Paris');
//some clean timezone
$cal = new \om\IcalParser();
$results = $cal->parseFile(__DIR__ . '/cal/blank_description.ics');
Assert::same('America/Los_Angeles', $cal->timezone->getName());
$results = $cal->parseFile(__DIR__ . '/cal/utc_negative_zero.ics');
Assert::same('Etc/GMT', $cal->timezone->getName());
//time zone with custom prefixes (Mozilla files tken from here: https://www.mozilla.org/en-US/projects/calendar/holidays/)
$cal = new \om\IcalParser();
$results = $cal->parseFile(__DIR__ . '/cal/FrenchHolidays.ics');
Assert::same('Europe/Paris', $cal->timezone->getName());
$cal = new \om\IcalParser();
$results = $cal->parseFile(__DIR__ . '/cal/weird_windows_timezones.ics');
$events = $cal->getSortedEvents();

View File

@ -0,0 +1,19 @@
<?php
/**
* @author Roman Ozana <ozana@omdesign.cz>
*/
use Tester\Assert;
use Tester\Environment;
require_once __DIR__ . '/../vendor/autoload.php';
Environment::setup();
$cal = new \om\IcalParser();
$results = $cal->parseFile(__DIR__ . '/cal/wrong_dates.ics');
$events = $cal->getSortedEvents();
Assert::same('29.9.2014 00:00:00', $events[1]['DTSTART']->format('j.n.Y H:i:s'));
Assert::same(null, $events[1]['DTEND']);
Assert::same(null, $events[0]['DTSTART']);
Assert::same('30.9.2014 00:00:00', $events[0]['DTEND']->format('j.n.Y H:i:s'));

View File

@ -0,0 +1,19 @@
<?php
/**
* This file generates a map from windows timezones to tz database timezones
*
* @author Clement Wong <cw@clement.hk>
* @license http://www.opensource.org/licenses/mit-license.php MIT License
*/
$windows_timezones = array();
$windowstimezonexml = new DOMDocument();
$windowstimezonexml->load('http://unicode.org/cldr/data/common/supplemental/windowsZones.xml');
$zones = $windowstimezonexml->getElementsByTagName('mapZone');
foreach($zones as $zone) {
if($zone->getAttribute('territory') == '001') {
$windows_timezones[$zone->getAttribute('other')] = $zone->getAttribute('type');
}
}
file_put_contents(__DIR__.'/windows_timezones.php', "<?php\n\$windows_timezones = ".var_export($windows_timezones, true).';');