diff --git a/resources/sql/autopatches/20161003.cal.02.parameters.sql b/resources/sql/autopatches/20161003.cal.02.parameters.sql
new file mode 100644
--- /dev/null
+++ b/resources/sql/autopatches/20161003.cal.02.parameters.sql
@@ -0,0 +1,5 @@
+ALTER TABLE {$NAMESPACE}_calendar.calendar_event
+  ADD parameters LONGTEXT NOT NULL COLLATE {$COLLATE_TEXT};
+
+UPDATE {$NAMESPACE}_calendar.calendar_event
+  SET parameters = '{}' WHERE parameters = '';
diff --git a/src/applications/calendar/storage/PhabricatorCalendarEvent.php b/src/applications/calendar/storage/PhabricatorCalendarEvent.php
--- a/src/applications/calendar/storage/PhabricatorCalendarEvent.php
+++ b/src/applications/calendar/storage/PhabricatorCalendarEvent.php
@@ -44,6 +44,7 @@
   protected $utcInitialEpoch;
   protected $utcUntilEpoch;
   protected $utcInstanceEpoch;
+  protected $parameters = array();
 
   private $parentEvent = self::ATTACHABLE;
   private $invitees = self::ATTACHABLE;
@@ -87,6 +88,11 @@
 
     $default_icon = 'fa-calendar';
 
+    $datetime_start = PhutilCalendarAbsoluteDateTime::newFromEpoch(
+      $now,
+      $actor->getTimezoneIdentifier());
+    $datetime_end = $datetime_start->newRelativeDateTime('PT1H');
+
     return id(new PhabricatorCalendarEvent())
       ->setHostPHID($actor->getPHID())
       ->setIsCancelled(0)
@@ -106,6 +112,8 @@
       ->setDateTo($epoch_max)
       ->setAllDayDateFrom($now_min)
       ->setAllDayDateTo($now_max)
+      ->setStartDateTime($datetime_start)
+      ->setEndDateTime($datetime_end)
       ->applyViewerTimezone($actor);
   }
 
@@ -443,6 +451,7 @@
       ),
       self::CONFIG_SERIALIZATION => array(
         'recurrenceFrequency' => self::SERIALIZATION_JSON,
+        'parameters' => self::SERIALIZATION_JSON,
       ),
     ) + parent::getConfiguration();
   }
@@ -785,16 +794,31 @@
   }
 
   public function newStartDateTime() {
+    $datetime = $this->getParameter('startDateTime');
+    if ($datetime) {
+      return $this->newDateTimeFromDictionary($datetime);
+    }
+
     $epoch = $this->getDateFrom();
     return $this->newDateTimeFromEpoch($epoch);
   }
 
   public function newEndDateTime() {
+    $datetime = $this->getParameter('endDateTime');
+    if ($datetime) {
+      return $this->newDateTimeFromDictionary($datetime);
+    }
+
     $epoch = $this->getDateTo();
     return $this->newDateTimeFromEpoch($epoch);
   }
 
   public function newUntilDateTime() {
+    $datetime = $this->getParameter('untilDateTime');
+    if ($datetime) {
+      return $this->newDateTimeFromDictionary($datetime);
+    }
+
     $epoch = $this->getRecurrenceEndDate();
     if (!$epoch) {
       return null;
@@ -824,18 +848,53 @@
   private function newDateTimeFromEpoch($epoch) {
     $datetime = PhutilCalendarAbsoluteDateTime::newFromEpoch($epoch);
 
+    if ($this->getIsAllDay()) {
+      $datetime->setIsAllDay(true);
+    }
+
+    return $this->newDateTimeFromDateTime($datetime);
+  }
+
+  private function newDateTimeFromDictionary(array $dict) {
+    $datetime = PhutilCalendarAbsoluteDateTime::newFromDictionary($dict);
+    return $this->newDateTimeFromDateTime($datetime);
+  }
+
+  private function newDateTimeFromDateTime(PhutilCalendarDateTime $datetime) {
     $viewer_timezone = $this->viewerTimezone;
     if ($viewer_timezone) {
       $datetime->setViewerTimezone($viewer_timezone);
     }
 
-    if ($this->getIsAllDay()) {
-      $datetime->setIsAllDay(true);
-    }
-
     return $datetime;
   }
 
+  public function getParameter($key, $default = null) {
+    return idx($this->parameters, $key, $default);
+  }
+
+  public function setParameter($key, $value) {
+    $this->parameters[$key] = $value;
+    return $this;
+  }
+
+  public function setStartDateTime(PhutilCalendarDateTime $datetime) {
+    return $this->setParameter(
+      'startDateTime',
+      $datetime->newAbsoluteDateTime()->toDictionary());
+  }
+
+  public function setEndDateTime(PhutilCalendarDateTime $datetime) {
+    return $this->setParameter(
+      'endDateTime',
+      $datetime->newAbsoluteDateTime()->toDictionary());
+  }
+
+  public function setUntilDateTime(PhutilCalendarDateTime $datetime) {
+    return $this->setParameter(
+      'untilDateTime',
+      $datetime->newAbsoluteDateTime()->toDictionary());
+  }
 
 /* -(  Markup Interface  )--------------------------------------------------- */
 
diff --git a/src/applications/calendar/xaction/PhabricatorCalendarEventAllDayTransaction.php b/src/applications/calendar/xaction/PhabricatorCalendarEventAllDayTransaction.php
--- a/src/applications/calendar/xaction/PhabricatorCalendarEventAllDayTransaction.php
+++ b/src/applications/calendar/xaction/PhabricatorCalendarEventAllDayTransaction.php
@@ -15,6 +15,25 @@
 
   public function applyInternalEffects($object, $value) {
     $object->setIsAllDay($value);
+
+    // Adjust the flags on any other dates the event has.
+    $keys = array(
+      'startDateTime',
+      'endDateTime',
+      'untilDateTime',
+    );
+
+    foreach ($keys as $key) {
+      $dict = $object->getParameter($key);
+      if (!$dict) {
+        continue;
+      }
+
+      $datetime = PhutilCalendarAbsoluteDateTime::newFromDictionary($dict);
+      $datetime->setIsAllDay($value);
+
+      $object->setParameter($key, $datetime->toDictionary());
+    }
   }
 
   public function getTitle() {
diff --git a/src/applications/calendar/xaction/PhabricatorCalendarEventEndDateTransaction.php b/src/applications/calendar/xaction/PhabricatorCalendarEventEndDateTransaction.php
--- a/src/applications/calendar/xaction/PhabricatorCalendarEventEndDateTransaction.php
+++ b/src/applications/calendar/xaction/PhabricatorCalendarEventEndDateTransaction.php
@@ -12,8 +12,8 @@
   public function applyInternalEffects($object, $value) {
     $actor = $this->getActor();
 
+    // TODO: DEPRECATED.
     $object->setDateTo($value);
-
     $object->setAllDayDateTo(
       $object->getDateEpochForTimezone(
         $value,
@@ -21,6 +21,12 @@
         'Y-m-d 23:59:00',
         null,
         new DateTimeZone('UTC')));
+
+    $datetime = PhutilCalendarAbsoluteDateTime::newFromEpoch(
+      $value,
+      $actor->getTimezoneIdentifier());
+    $datetime->setIsAllDay($object->getIsAllDay());
+    $object->setEndDateTime($datetime);
   }
 
   public function getTitle() {
diff --git a/src/applications/calendar/xaction/PhabricatorCalendarEventStartDateTransaction.php b/src/applications/calendar/xaction/PhabricatorCalendarEventStartDateTransaction.php
--- a/src/applications/calendar/xaction/PhabricatorCalendarEventStartDateTransaction.php
+++ b/src/applications/calendar/xaction/PhabricatorCalendarEventStartDateTransaction.php
@@ -12,8 +12,8 @@
   public function applyInternalEffects($object, $value) {
     $actor = $this->getActor();
 
+    // TODO: DEPRECATED.
     $object->setDateFrom($value);
-
     $object->setAllDayDateFrom(
       $object->getDateEpochForTimezone(
         $value,
@@ -21,6 +21,12 @@
         'Y-m-d',
         null,
         new DateTimeZone('UTC')));
+
+    $datetime = PhutilCalendarAbsoluteDateTime::newFromEpoch(
+      $value,
+      $actor->getTimezoneIdentifier());
+    $datetime->setIsAllDay($object->getIsAllDay());
+    $object->setStartDateTime($datetime);
   }
 
   public function getTitle() {
diff --git a/src/applications/calendar/xaction/PhabricatorCalendarEventUntilDateTransaction.php b/src/applications/calendar/xaction/PhabricatorCalendarEventUntilDateTransaction.php
--- a/src/applications/calendar/xaction/PhabricatorCalendarEventUntilDateTransaction.php
+++ b/src/applications/calendar/xaction/PhabricatorCalendarEventUntilDateTransaction.php
@@ -10,7 +10,16 @@
   }
 
   public function applyInternalEffects($object, $value) {
+    $actor = $this->getActor();
+
+    // TODO: DEPRECATED.
     $object->setRecurrenceEndDate($value);
+
+    $datetime = PhutilCalendarAbsoluteDateTime::newFromEpoch(
+      $value,
+      $actor->getTimezoneIdentifier());
+    $datetime->setIsAllDay($object->getIsAllDay());
+    $object->setUntilDateTime($datetime);
   }
 
   public function getTitle() {