diff --git a/src/applications/calendar/editor/PhabricatorCalendarEventEditor.php b/src/applications/calendar/editor/PhabricatorCalendarEventEditor.php
--- a/src/applications/calendar/editor/PhabricatorCalendarEventEditor.php
+++ b/src/applications/calendar/editor/PhabricatorCalendarEventEditor.php
@@ -175,6 +175,34 @@
     return parent::applyCustomExternalTransaction($object, $xaction);
   }
 
+  protected function validateAllTransactions(
+    PhabricatorLiskDAO $object,
+    array $xactions) {
+    $start_date_xaction = PhabricatorCalendarEventTransaction::TYPE_START_DATE;
+    $end_date_xaction = PhabricatorCalendarEventTransaction::TYPE_END_DATE;
+    $start_date = $object->getDateFrom();
+    $end_date = $object->getDateTo();
+    $errors = array();
+
+    foreach ($xactions as $xaction) {
+      if ($xaction->getTransactionType() == $start_date_xaction) {
+        $start_date = $xaction->getNewValue()->getEpoch();
+      } else if ($xaction->getTransactionType() == $end_date_xaction) {
+        $end_date = $xaction->getNewValue()->getEpoch();
+      }
+    }
+    if ($start_date > $end_date) {
+      $type = PhabricatorCalendarEventTransaction::TYPE_END_DATE;
+      $errors[] = new PhabricatorApplicationTransactionValidationError(
+        $type,
+        pht('Invalid'),
+        pht('End date must be after start date.'),
+        null);
+    }
+
+    return $errors;
+  }
+
   protected function validateTransaction(
     PhabricatorLiskDAO $object,
     $type,
diff --git a/src/applications/calendar/exception/PhabricatorCalendarEventInvalidEpochException.php b/src/applications/calendar/exception/PhabricatorCalendarEventInvalidEpochException.php
deleted file mode 100644
--- a/src/applications/calendar/exception/PhabricatorCalendarEventInvalidEpochException.php
+++ /dev/null
@@ -1,3 +0,0 @@
-<?php
-
-final class PhabricatorCalendarEventInvalidEpochException extends Exception {}
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
@@ -42,10 +42,6 @@
   }
 
   public function save() {
-    if ($this->getDateTo() < $this->getDateFrom()) {
-      throw new PhabricatorCalendarEventInvalidEpochException();
-    }
-
     if (!$this->mailKey) {
       $this->mailKey = Filesystem::readRandomCharacters(20);
     }
diff --git a/src/applications/people/conduit/UserAddStatusConduitAPIMethod.php b/src/applications/people/conduit/UserAddStatusConduitAPIMethod.php
--- a/src/applications/people/conduit/UserAddStatusConduitAPIMethod.php
+++ b/src/applications/people/conduit/UserAddStatusConduitAPIMethod.php
@@ -50,17 +50,13 @@
     $status      = $request->getValue('status');
     $description = $request->getValue('description', '');
 
-    try {
-      id(new PhabricatorCalendarEvent())
-        ->setUserPHID($user_phid)
-        ->setDateFrom($from)
-        ->setDateTo($to)
-        ->setTextStatus($status)
-        ->setDescription($description)
-        ->save();
-    } catch (PhabricatorCalendarEventInvalidEpochException $e) {
-      throw new ConduitException('ERR-BAD-EPOCH');
-    }
+    id(new PhabricatorCalendarEvent())
+      ->setUserPHID($user_phid)
+      ->setDateFrom($from)
+      ->setDateTo($to)
+      ->setTextStatus($status)
+      ->setDescription($description)
+      ->save();
   }
 
 }
diff --git a/src/applications/transactions/editor/PhabricatorApplicationTransactionEditor.php b/src/applications/transactions/editor/PhabricatorApplicationTransactionEditor.php
--- a/src/applications/transactions/editor/PhabricatorApplicationTransactionEditor.php
+++ b/src/applications/transactions/editor/PhabricatorApplicationTransactionEditor.php
@@ -639,6 +639,7 @@
         $errors[] = $this->validateTransaction($object, $type, $type_xactions);
       }
 
+      $errors[] = $this->validateAllTransactions($object, $xactions);
       $errors = array_mergev($errors);
 
       $continue_on_missing = $this->getContinueOnMissingFields();
@@ -1824,6 +1825,12 @@
     return clone $object;
   }
 
+  protected function validateAllTransactions(
+    PhabricatorLiskDAO $object,
+    array $xactions) {
+    return array();
+  }
+
   /**
    * Check for a missing text field.
    *