diff --git a/src/applications/conduit/parametertype/ConduitEpochParameterType.php b/src/applications/conduit/parametertype/ConduitEpochParameterType.php
index e8fe095c50..8f2ca2c98a 100644
--- a/src/applications/conduit/parametertype/ConduitEpochParameterType.php
+++ b/src/applications/conduit/parametertype/ConduitEpochParameterType.php
@@ -1,36 +1,52 @@
 <?php
 
 final class ConduitEpochParameterType
   extends ConduitParameterType {
 
+  private $allowNull;
+
+  public function setAllowNull($allow_null) {
+    $this->allowNull = $allow_null;
+    return $this;
+  }
+
+  public function getAllowNull() {
+    return $this->allowNull;
+  }
+
   protected function getParameterValue(array $request, $key, $strict) {
     $value = parent::getParameterValue($request, $key, $strict);
+
+    if ($this->allowNull && ($value === null)) {
+      return $value;
+    }
+
     $value = $this->parseIntValue($request, $key, $value, $strict);
 
     if ($value <= 0) {
       $this->raiseValidationException(
         $request,
         $key,
         pht('Epoch timestamp must be larger than 0, got %d.', $value));
     }
 
     return $value;
   }
 
   protected function getParameterTypeName() {
     return 'epoch';
   }
 
   protected function getParameterFormatDescriptions() {
     return array(
       pht('Epoch timestamp, as an integer.'),
     );
   }
 
   protected function getParameterExamples() {
     return array(
       '1450019509',
     );
   }
 
 }
diff --git a/src/applications/transactions/editfield/PhabricatorEpochEditField.php b/src/applications/transactions/editfield/PhabricatorEpochEditField.php
index 9ac9726593..b50f013177 100644
--- a/src/applications/transactions/editfield/PhabricatorEpochEditField.php
+++ b/src/applications/transactions/editfield/PhabricatorEpochEditField.php
@@ -1,43 +1,44 @@
 <?php
 
 final class PhabricatorEpochEditField
   extends PhabricatorEditField {
 
   private $allowNull;
   private $hideTime;
 
   public function setAllowNull($allow_null) {
     $this->allowNull = $allow_null;
     return $this;
   }
 
   public function getAllowNull() {
     return $this->allowNull;
   }
 
   public function setHideTime($hide_time) {
     $this->hideTime = $hide_time;
     return $this;
   }
 
   public function getHideTime() {
     return $this->hideTime;
   }
 
   protected function newControl() {
     return id(new AphrontFormDateControl())
       ->setAllowNull($this->getAllowNull())
       ->setIsTimeDisabled($this->getHideTime())
       ->setViewer($this->getViewer());
   }
 
   protected function newHTTPParameterType() {
     return id(new AphrontEpochHTTPParameterType())
       ->setAllowNull($this->getAllowNull());
   }
 
   protected function newConduitParameterType() {
-    return new ConduitEpochParameterType();
+    return id(new ConduitEpochParameterType())
+      ->setAllowNull($this->getAllowNull());
   }
 
 }
diff --git a/src/infrastructure/customfield/standard/PhabricatorStandardCustomFieldDate.php b/src/infrastructure/customfield/standard/PhabricatorStandardCustomFieldDate.php
index 994bb99403..4aba7543e7 100644
--- a/src/infrastructure/customfield/standard/PhabricatorStandardCustomFieldDate.php
+++ b/src/infrastructure/customfield/standard/PhabricatorStandardCustomFieldDate.php
@@ -1,249 +1,243 @@
 <?php
 
 final class PhabricatorStandardCustomFieldDate
   extends PhabricatorStandardCustomField {
 
   public function getFieldType() {
     return 'date';
   }
 
   public function buildFieldIndexes() {
     $indexes = array();
 
     $value = $this->getFieldValue();
     if (strlen($value)) {
       $indexes[] = $this->newNumericIndex((int)$value);
     }
 
     return $indexes;
   }
 
   public function buildOrderIndex() {
     return $this->newNumericIndex(0);
   }
 
   public function getValueForStorage() {
     $value = $this->getFieldValue();
     if (strlen($value)) {
       return (int)$value;
     } else {
       return null;
     }
   }
 
   public function setValueFromStorage($value) {
     if (strlen($value)) {
       $value = (int)$value;
     } else {
       $value = null;
     }
     return $this->setFieldValue($value);
   }
 
   public function renderEditControl(array $handles) {
     return $this->newDateControl();
   }
 
   public function readValueFromRequest(AphrontRequest $request) {
     $control = $this->newDateControl();
     $control->setUser($request->getUser());
     $value = $control->readValueFromRequest($request);
 
     $this->setFieldValue($value);
   }
 
   public function renderPropertyViewValue(array $handles) {
     $value = $this->getFieldValue();
     if (!$value) {
       return null;
     }
 
     return phabricator_datetime($value, $this->getViewer());
   }
 
   private function newDateControl() {
     $control = id(new AphrontFormDateControl())
       ->setLabel($this->getFieldName())
       ->setName($this->getFieldKey())
       ->setUser($this->getViewer())
       ->setCaption($this->getCaption())
       ->setAllowNull(!$this->getRequired());
 
     // If the value is already numeric, treat it as an epoch timestamp and set
     // it directly. Otherwise, it's likely a field default, which we let users
     // specify as a string. Parse the string into an epoch.
 
     $value = $this->getFieldValue();
     if (!ctype_digit($value)) {
       $value = PhabricatorTime::parseLocalTime($value, $this->getViewer());
     }
 
     // If we don't have anything valid, make sure we pass `null`, since the
     // control special-cases that.
     $control->setValue(nonempty($value, null));
 
     return $control;
   }
 
   public function readApplicationSearchValueFromRequest(
     PhabricatorApplicationSearchEngine $engine,
     AphrontRequest $request) {
 
     $key = $this->getFieldKey();
 
     return array(
       'min' => $request->getStr($key.'.min'),
       'max' => $request->getStr($key.'.max'),
     );
   }
 
   public function applyApplicationSearchConstraintToQuery(
     PhabricatorApplicationSearchEngine $engine,
     PhabricatorCursorPagedPolicyAwareQuery $query,
     $value) {
 
     $viewer = $this->getViewer();
 
     if (!is_array($value)) {
       $value = array();
     }
 
     $min_str = idx($value, 'min', '');
     if (strlen($min_str)) {
       $min = PhabricatorTime::parseLocalTime($min_str, $viewer);
     } else {
       $min = null;
     }
 
     $max_str = idx($value, 'max', '');
     if (strlen($max_str)) {
       $max = PhabricatorTime::parseLocalTime($max_str, $viewer);
     } else {
       $max = null;
     }
 
     if (($min !== null) || ($max !== null)) {
       $query->withApplicationSearchRangeConstraint(
         $this->newNumericIndex(null),
         $min,
         $max);
     }
   }
 
   public function appendToApplicationSearchForm(
     PhabricatorApplicationSearchEngine $engine,
     AphrontFormView $form,
     $value) {
 
     if (!is_array($value)) {
       $value = array();
     }
 
     $form
       ->appendChild(
         id(new AphrontFormTextControl())
           ->setLabel(pht('%s After', $this->getFieldName()))
           ->setName($this->getFieldKey().'.min')
           ->setValue(idx($value, 'min', '')))
       ->appendChild(
         id(new AphrontFormTextControl())
           ->setLabel(pht('%s Before', $this->getFieldName()))
           ->setName($this->getFieldKey().'.max')
           ->setValue(idx($value, 'max', '')));
   }
 
   public function getApplicationTransactionTitle(
     PhabricatorApplicationTransaction $xaction) {
     $author_phid = $xaction->getAuthorPHID();
     $old = $xaction->getOldValue();
     $new = $xaction->getNewValue();
 
     $viewer = $this->getViewer();
 
     $old_date = null;
     if ($old) {
       $old_date = phabricator_datetime($old, $viewer);
     }
 
     $new_date = null;
     if ($new) {
       $new_date = phabricator_datetime($new, $viewer);
     }
 
     if (!$old) {
       return pht(
         '%s set %s to %s.',
         $xaction->renderHandleLink($author_phid),
         $this->getFieldName(),
         $new_date);
     } else if (!$new) {
       return pht(
         '%s removed %s.',
         $xaction->renderHandleLink($author_phid),
         $this->getFieldName());
     } else {
       return pht(
         '%s changed %s from %s to %s.',
         $xaction->renderHandleLink($author_phid),
         $this->getFieldName(),
         $old_date,
         $new_date);
     }
   }
 
   public function getApplicationTransactionTitleForFeed(
     PhabricatorApplicationTransaction $xaction) {
 
     $viewer = $this->getViewer();
 
     $author_phid = $xaction->getAuthorPHID();
     $object_phid = $xaction->getObjectPHID();
 
     $old = $xaction->getOldValue();
     $new = $xaction->getNewValue();
 
     if (!$old) {
       return pht(
         '%s set %s to %s on %s.',
         $xaction->renderHandleLink($author_phid),
         $this->getFieldName(),
         phabricator_datetime($new, $viewer),
         $xaction->renderHandleLink($object_phid));
     } else if (!$new) {
       return pht(
         '%s removed %s on %s.',
         $xaction->renderHandleLink($author_phid),
         $this->getFieldName(),
         $xaction->renderHandleLink($object_phid));
     } else {
       return pht(
         '%s changed %s from %s to %s on %s.',
         $xaction->renderHandleLink($author_phid),
         $this->getFieldName(),
         phabricator_datetime($old, $viewer),
         phabricator_datetime($new, $viewer),
         $xaction->renderHandleLink($object_phid));
     }
   }
 
-
-  public function shouldAppearInConduitTransactions() {
-    // TODO: Dates are complicated and we don't yet support handling them from
-    // Conduit.
-    return false;
-  }
-
   protected function newConduitSearchParameterType() {
     // TODO: Build a new "pair<epoch|null, epoch|null>" type or similar.
     return null;
   }
 
   protected function newConduitEditParameterType() {
-    return new ConduitEpochParameterType();
+    return id(new ConduitEpochParameterType())
+      ->setAllowNull(!$this->getRequired());
   }
 
   protected function newExportFieldType() {
     return new PhabricatorEpochExportField();
   }
 
 }