Page MenuHomePhabricator

D16653.id40088.diff
No OneTemporary

D16653.id40088.diff

diff --git a/src/parser/calendar/data/PhutilCalendarAbsoluteDateTime.php b/src/parser/calendar/data/PhutilCalendarAbsoluteDateTime.php
--- a/src/parser/calendar/data/PhutilCalendarAbsoluteDateTime.php
+++ b/src/parser/calendar/data/PhutilCalendarAbsoluteDateTime.php
@@ -75,6 +75,75 @@
->setTimezone($timezone);
}
+ public static function newFromDictionary(array $dict) {
+ static $keys;
+ if ($keys === null) {
+ $keys = array_fuse(
+ array(
+ 'kind',
+ 'year',
+ 'month',
+ 'day',
+ 'hour',
+ 'minute',
+ 'second',
+ 'timezone',
+ 'isAllDay',
+ ));
+ }
+
+ foreach ($dict as $key => $value) {
+ if (!isset($keys[$key])) {
+ throw new Exception(
+ pht(
+ 'Unexpected key "%s" in datetime dictionary, expected keys: %s.',
+ $key,
+ implode(', ', array_keys($keys))));
+ }
+ }
+
+ if (idx($dict, 'kind') !== 'absolute') {
+ throw new Exception(
+ pht(
+ 'Expected key "%s" with value "%s" in datetime dictionary.',
+ 'kind',
+ 'absolute'));
+ }
+
+ if (!isset($dict['year'])) {
+ throw new Exception(
+ pht(
+ 'Expected key "%s" in datetime dictionary.',
+ 'year'));
+ }
+
+ $datetime = id(new self())
+ ->setYear(idx($dict, 'year'))
+ ->setMonth(idx($dict, 'month', 1))
+ ->setDay(idx($dict, 'day', 1))
+ ->setHours(idx($dict, 'hour', 0))
+ ->setMinutes(idx($dict, 'minute', 0))
+ ->setSeconds(idx($dict, 'second', 0))
+ ->setTimezone(idx($dict, 'timezone'))
+ ->setIsAllDay(idx($dict, 'isAllDay', false));
+
+ return $datetime;
+ }
+
+ public function toDictionary() {
+ return array(
+ 'kind' => 'absolute',
+ 'year' => $this->getYear(),
+ 'month' => $this->getMonth(),
+ 'day' => $this->getDay(),
+ 'hour' => $this->getHour(),
+ 'minute' => $this->getMinute(),
+ 'second' => $this->getSecond(),
+ 'timezone' => $this->getTimezone(),
+ 'isAllDay' => $this->getIsAllDay(),
+ );
+ }
+
public function setYear($year) {
$this->year = $year;
return $this;
diff --git a/src/parser/calendar/data/PhutilCalendarDateTime.php b/src/parser/calendar/data/PhutilCalendarDateTime.php
--- a/src/parser/calendar/data/PhutilCalendarDateTime.php
+++ b/src/parser/calendar/data/PhutilCalendarDateTime.php
@@ -31,16 +31,30 @@
public function getISO8601() {
$datetime = $this->newPHPDateTime();
- $datetime->setTimezone(new DateTimeZone('UTC'));
if ($this->getIsAllDay()) {
return $datetime->format('Ymd');
- } else {
+ } else if ($this->getTimezone()) {
+ // With a timezone, the event occurs at a specific second universally.
+ // We return the UTC representation of that point in time.
+ $datetime->setTimezone(new DateTimeZone('UTC'));
return $datetime->format('Ymd\\THis\\Z');
+ } else {
+ // With no timezone, events are "floating" and occur at local time.
+ // We return a representation without the "Z".
+ return $datetime->format('Ymd\\THis');
}
}
+ public function newAbsoluteDateTime() {
+ return PhutilCalendarAbsoluteDateTime::newFromEpoch($this->getEpoch())
+ ->setTimezone($this->getTimezone())
+ ->setIsAllDay($this->getIsAllDay())
+ ->setViewerTimezone($this->getViewerTimezone());
+ }
+
abstract protected function newPHPDateTimeZone();
abstract protected function newPHPDateTime();
+ abstract public function getTimezone();
}
diff --git a/src/parser/calendar/data/PhutilCalendarDuration.php b/src/parser/calendar/data/PhutilCalendarDuration.php
--- a/src/parser/calendar/data/PhutilCalendarDuration.php
+++ b/src/parser/calendar/data/PhutilCalendarDuration.php
@@ -3,12 +3,58 @@
final class PhutilCalendarDuration extends Phobject {
private $isNegative = false;
- private $days = 0;
private $weeks = 0;
+ private $days = 0;
private $hours = 0;
private $minutes = 0;
private $seconds = 0;
+ public static function newFromDictionary(array $dict) {
+ static $keys;
+ if ($keys === null) {
+ $keys = array_fuse(
+ array(
+ 'isNegative',
+ 'weeks',
+ 'days',
+ 'hours',
+ 'minutes',
+ 'seconds',
+ ));
+ }
+
+ foreach ($dict as $key => $value) {
+ if (!isset($keys[$key])) {
+ throw new Exception(
+ pht(
+ 'Unexpected key "%s" in duration dictionary, expected keys: %s.',
+ $key,
+ implode(', ', array_keys($keys))));
+ }
+ }
+
+ $duration = id(new self())
+ ->setIsNegative(idx($dict, 'isNegative', false))
+ ->setWeeks(idx($dict, 'weeks', 0))
+ ->setDays(idx($dict, 'days', 0))
+ ->setHours(idx($dict, 'hours', 0))
+ ->setMinutes(idx($dict, 'minutes', 0))
+ ->setSeconds(idx($dict, 'seconds', 0));
+
+ return $duration;
+ }
+
+ public function toDictionary() {
+ return array(
+ 'isNegative' => $this->getIsNegative(),
+ 'weeks' => $this->getWeeks(),
+ 'days' => $this->getDays(),
+ 'hours' => $this->getHours(),
+ 'minutes' => $this->getMinutes(),
+ 'seconds' => $this->getSeconds(),
+ );
+ }
+
public function setIsNegative($is_negative) {
$this->isNegative = $is_negative;
return $this;
@@ -18,22 +64,22 @@
return $this->isNegative;
}
- public function setDays($days) {
- $this->days = $days;
+ public function setWeeks($weeks) {
+ $this->weeks = $weeks;
return $this;
}
- public function getDays() {
- return $this->days;
+ public function getWeeks() {
+ return $this->weeks;
}
- public function setWeeks($weeks) {
- $this->weeks = $weeks;
+ public function setDays($days) {
+ $this->days = $days;
return $this;
}
- public function getWeeks() {
- return $this->weeks;
+ public function getDays() {
+ return $this->days;
}
public function setHours($hours) {
diff --git a/src/parser/calendar/data/PhutilCalendarProxyDateTime.php b/src/parser/calendar/data/PhutilCalendarProxyDateTime.php
--- a/src/parser/calendar/data/PhutilCalendarProxyDateTime.php
+++ b/src/parser/calendar/data/PhutilCalendarProxyDateTime.php
@@ -40,4 +40,8 @@
return $this->getProxy()->newPHPDateTime();
}
+ public function getTimezone() {
+ return $this->getProxy()->getTimezone();
+ }
+
}
diff --git a/src/parser/calendar/data/PhutilCalendarRecurrenceRule.php b/src/parser/calendar/data/PhutilCalendarRecurrenceRule.php
--- a/src/parser/calendar/data/PhutilCalendarRecurrenceRule.php
+++ b/src/parser/calendar/data/PhutilCalendarRecurrenceRule.php
@@ -703,6 +703,7 @@
}
$result = id(new PhutilCalendarAbsoluteDateTime())
+ ->setTimezone($this->getStartDateTime()->getTimezone())
->setViewerTimezone($this->getViewerTimezone())
->setYear($this->stateYear)
->setMonth($this->stateMonth)

File Metadata

Mime Type
text/plain
Expires
Tue, Mar 25, 8:28 AM (4 d, 6 h ago)
Storage Engine
blob
Storage Format
Encrypted (AES-256-CBC)
Storage Handle
7721766
Default Alt Text
D16653.id40088.diff (6 KB)

Event Timeline