diff --git a/modules/recurring_events_registration/recurring_events_registration.module b/modules/recurring_events_registration/recurring_events_registration.module
index aecfde229dd7156b4b3e8a6081248e399aa7b3b2..48b196f4f23239bdaa7c15485fa52d9e61e423d1 100644
--- a/modules/recurring_events_registration/recurring_events_registration.module
+++ b/modules/recurring_events_registration/recurring_events_registration.module
@@ -13,7 +13,6 @@ use Drupal\Core\Entity\EntityInterface;
 use Drupal\recurring_events_registration\Entity\Registrant;
 use Drupal\recurring_events\Entity\EventSeries;
 use Drupal\recurring_events\Entity\EventInstance;
-use Drupal\Core\Form\FormStateInterface;
 use Drupal\Core\Url;
 
 /**
@@ -154,7 +153,7 @@ function recurring_events_registration_recurring_events_registration_notificatio
 /**
  * Implements hook_recurring_events_save_pre_instances_deletion().
  */
-function recurring_events_registration_recurring_events_save_pre_instances_deletion(EventSeries $event_series, FormStateInterface $form_state) {
+function recurring_events_registration_recurring_events_save_pre_instances_deletion(EventSeries $event_series) {
   $registration_creation_service = \Drupal::service('recurring_events_registration.creation_service');
   $registration_creation_service->setEventSeries($event_series);
 
diff --git a/recurring_events.api.php b/recurring_events.api.php
index 272f86d437d73661262f6889f0c31664d468cfc8..cc9bccd9bd77a206648241123e05273b186aa52a 100644
--- a/recurring_events.api.php
+++ b/recurring_events.api.php
@@ -117,10 +117,10 @@ function hook_recurring_events_inheritance_class_alter(&$class, $field) {
  *
  * @param Drupal\recurring_events\Entity\EventSeries $event_series
  *   The eventseries being altered.
- * @param Drupal\Core\Form\FormStateInterface $form_state
- *   The form state of an updated event series entity.
+ * @param Drupal\recurring_events\Entity\EventSeries $original
+ *   The original, unaltered eventseries.
  */
-function hook_recurring_events_save_pre_instances_deletion(EventSeries $event_series, FormStateInterface $form_state) {
+function hook_recurring_events_save_pre_instances_deletion(EventSeries $event_series, EventSeries $original) {
 }
 
 /**
@@ -133,10 +133,10 @@ function hook_recurring_events_save_pre_instances_deletion(EventSeries $event_se
  *
  * @param Drupal\recurring_events\Entity\EventSeries $event_series
  *   The eventseries being altered.
- * @param Drupal\Core\Form\FormStateInterface $form_state
- *   The form state of an updated event series entity.
+ * @param Drupal\recurring_events\Entity\EventSeries $original
+ *   The original, unaltered eventseries.
  */
-function hook_recurring_events_save_post_instances_deletion(EventSeries $event_series, FormStateInterface $form_state) {
+function hook_recurring_events_save_post_instances_deletion(EventSeries $event_series, EventSeries $original) {
 }
 
 /**
diff --git a/recurring_events.module b/recurring_events.module
index 82094d5e4c593e90524a6a899fb2ed054cdd394b..8524af3c5ea34a0bf19df0bebb490bfe45356cb3 100644
--- a/recurring_events.module
+++ b/recurring_events.module
@@ -10,6 +10,7 @@ use Drupal\Core\Entity\EntityInterface;
 use Drupal\Core\Render\Element;
 use Drupal\Core\Entity\EntityTypeInterface;
 use Drupal\Core\Field\BaseFieldDefinition;
+use Drupal\Core\Form\FormStateInterface;
 
 /**
  * Implements hook_help().
@@ -146,3 +147,84 @@ function template_preprocess_eventseries(array &$variables) {
     $variables['content'][$key] = $variables['elements'][$key];
   }
 }
+
+/**
+ * Implements hook_ENTITY_TYPE_presave().
+ */
+function recurring_events_eventseries_presave(EntityInterface $entity) {
+  $original = $entity->original;
+  $creation_service = \Drupal::service('recurring_events.event_creation_service');
+
+  // If the eventseries is being published, or created for the first time then
+  // there may be date recurrence changes that need to be converted into new
+  // eventinstance entities.
+  if ($entity->isPublished() || $entity->isNew()) {
+    if ($entity->isDefaultTranslation()) {
+      $creation_service->saveEvent($entity, $original);
+    }
+  }
+}
+
+/**
+ * Implements hook_ENTITY_TYPE_insert().
+ */
+function recurring_events_eventseries_insert(EntityInterface $entity) {
+  // When we initially create the eventseries we actually create the instances
+  // before the eventseries gets saved for the first time, so we have no ID for
+  // the series at that point. Now that the eventseries is properly saved we can
+  // go and set the eventseries_id on the eventinstances.
+  $instances = $entity->event_instances->referencedEntities();
+  if (!empty($instances)) {
+    foreach ($instances as $instance) {
+      if (empty($instance->eventseries_id->value)) {
+        $instance->set('eventseries_id', $entity->id());
+        $instance->setNewRevision(FALSE);
+        $instance->save();
+      }
+    }
+  }
+}
+
+/**
+ * Implements hook_form_FORM_ID_alter().
+ */
+function recurring_events_form_content_moderation_entity_moderation_form_alter(&$form, FormStateInterface $form_state) {
+  $entity = $form_state->get('entity');
+  if ($entity->getEntityTypeId() === 'eventseries') {
+    $original = \Drupal::entityTypeManager()->getStorage('eventseries')->load($entity->id());
+    $creation_service = \Drupal::service('recurring_events.event_creation_service');
+    if ($creation_service->checkForOriginalRecurConfigChanges($entity, $original)) {
+      $diff_array = $creation_service->buildDiffArray($original, NULL, $entity);
+      if (!empty($diff_array)) {
+        $form['diff'] = [
+          '#type' => 'container',
+          '#weight' => -99,
+        ];
+
+        $form['diff']['diff_title'] = [
+          '#type' => '#markup',
+          '#prefix' => '<h2>',
+          '#markup' => t('Revision Date Changes'),
+          '#suffix' => '</h2>',
+        ];
+
+        $form['diff']['diff_message'] = [
+          '#type' => '#markup',
+          '#prefix' => '<p>',
+          '#markup' => t('Recurrence configuration has been changed in this revision, as a result if you choose to publish this revision all instances will be removed and recreated. This action cannot be undone.'),
+          '#suffix' => '</p>',
+        ];
+
+        $form['diff']['table'] = [
+          '#type' => 'table',
+          '#header' => [
+            t('Data'),
+            t('Stored'),
+            t('Overridden'),
+          ],
+          '#rows' => $diff_array,
+        ];
+      }
+    }
+  }
+}
diff --git a/src/Controller/EventInstanceController.php b/src/Controller/EventInstanceController.php
index 8d151fdf96b81413737a1a243ae9f31e0f97db7e..45bcdb0c86f925c336fbbba740e254597dc113e6 100644
--- a/src/Controller/EventInstanceController.php
+++ b/src/Controller/EventInstanceController.php
@@ -191,7 +191,7 @@ class EventInstanceController extends ControllerBase implements ContainerInjecti
             '#type' => 'inline_template',
             '#template' => '{% trans %}{{ date }} by {{ username }}{% endtrans %}{% if message %}<p class="revision-log">{{ message }}</p>{% endif %}',
             '#context' => [
-              'date' => $link,
+              'date' => $link->toString(),
               'username' => $this->renderer->renderPlain($username),
               'message' => ['#markup' => $revision->getRevisionLogMessage(), '#allowed_tags' => Xss::getHtmlTagList()],
             ],
diff --git a/src/Controller/EventSeriesController.php b/src/Controller/EventSeriesController.php
index 6a23f202d1bf47d8183f39a8e63d0bb848dd2ede..1b495b185809d6b23fcc15ec918c0b985e1802de 100644
--- a/src/Controller/EventSeriesController.php
+++ b/src/Controller/EventSeriesController.php
@@ -168,7 +168,7 @@ class EventSeriesController extends ControllerBase implements ContainerInjection
             '#type' => 'inline_template',
             '#template' => '{% trans %}{{ date }} by {{ username }}{% endtrans %}{% if message %}<p class="revision-log">{{ message }}</p>{% endif %}',
             '#context' => [
-              'date' => $link,
+              'date' => $link->toString(),
               'username' => $this->renderer->renderPlain($username),
               'message' => ['#markup' => $revision->getRevisionLogMessage(), '#allowed_tags' => Xss::getHtmlTagList()],
             ],
diff --git a/src/Entity/EventInstance.php b/src/Entity/EventInstance.php
index 5c085037bd6e6e626eae0872d54ff66e414b25d9..b000dd9a3493aed7ce86ac36f732db61e5df18db 100644
--- a/src/Entity/EventInstance.php
+++ b/src/Entity/EventInstance.php
@@ -254,6 +254,21 @@ class EventInstance extends EditorialContentEntityBase implements EventInterface
     return $this;
   }
 
+  /**
+   * {@inheritdoc}
+   */
+  public function getRevisionCreationTime() {
+    return $this->revision_timestamp->value;
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function setRevisionCreationTime($timestamp) {
+    $this->revision_timestamp->value = $timestamp;
+    return $this;
+  }
+
   /**
    * {@inheritdoc}
    */
diff --git a/src/Entity/EventSeries.php b/src/Entity/EventSeries.php
index e9ac8857fff47a9fe4880f5ccc00b67c1027b9da..2b810deb150d71285580fc654aa8bcad486f0acd 100644
--- a/src/Entity/EventSeries.php
+++ b/src/Entity/EventSeries.php
@@ -253,6 +253,21 @@ class EventSeries extends EditorialContentEntityBase implements EventInterface {
     return $this;
   }
 
+  /**
+   * {@inheritdoc}
+   */
+  public function getRevisionCreationTime() {
+    return $this->revision_timestamp->value;
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function setRevisionCreationTime($timestamp) {
+    $this->revision_timestamp->value = $timestamp;
+    return $this;
+  }
+
   /**
    * {@inheritdoc}
    */
diff --git a/src/EventCreationService.php b/src/EventCreationService.php
index 503567369de4f766c13275b3803973eccead3b00..6d8061e4bb88c8a7ecdefa8af89f30022406b510 100644
--- a/src/EventCreationService.php
+++ b/src/EventCreationService.php
@@ -280,16 +280,29 @@ class EventCreationService {
    * @param Drupal\recurring_events\Entity\EventSeries $event
    *   The stored event series entity.
    * @param Drupal\Core\Form\FormStateInterface $form_state
-   *   The form state of an updated event series entity.
+   *   (Optional) The form state of an updated event series entity.
+   * @param Drupal\recurring_events\Entity\EventSeries $edited
+   *   (Optional) The edited event series entity.
    *
    * @return array
    *   An array of differences.
    */
-  public function buildDiffArray(EventSeries $event, FormStateInterface $form_state) {
+  public function buildDiffArray(EventSeries $event, FormStateInterface $form_state = NULL, EventSeries $edited = NULL) {
     $diff = [];
 
     $entity_config = $this->convertEntityConfigToArray($event);
-    $form_config = $this->convertFormConfigToArray($form_state);
+    $form_config = [];
+
+    if (!is_null($form_state)) {
+      $form_config = $this->convertFormConfigToArray($form_state);
+    }
+    if (!is_null($edited)) {
+      $form_config = $this->convertEntityConfigToArray($edited);
+    }
+
+    if (empty($form_config)) {
+      return $diff;
+    }
 
     if ($entity_config['type'] !== $form_config['type']) {
       $diff['type'] = [
@@ -414,25 +427,25 @@ class EventCreationService {
    *
    * @param Drupal\recurring_events\Entity\EventSeries $event
    *   The stored event series entity.
-   * @param Drupal\Core\Form\FormStateInterface $form_state
-   *   The form state of an updated event series entity.
    * @param Drupal\recurring_events\Entity\EventSeries $original
    *   The original, unsaved event series entity.
    */
-  public function saveEvent(EventSeries $event, FormStateInterface $form_state, EventSeries $original = NULL) {
-    // We only need a revision if this is an existing entity.
+  public function saveEvent(EventSeries $event, EventSeries $original = NULL) {
+    $update_event_id = FALSE;
+
+    // If this is a brand new series, then we don't have an ID for it yet to
+    // save against the instances. So we need to defer that part 'til later. We
+    // also want to always create instances if this is a brand new series.
     if ($event->isNew()) {
       $create_instances = TRUE;
-      // We have to save the event series first so we can use the ID to store
-      // against the event instances we create.
-      $event->save();
+      $update_event_id = TRUE;
     }
     else {
       // If there are date differences, we need to clear out the instances.
-      $create_instances = $this->checkForFormRecurConfigChanges($original, $form_state);
+      $create_instances = $this->checkForOriginalRecurConfigChanges($event, $original);
       if ($create_instances) {
         // Allow other modules to react prior to the deletion of all instances.
-        \Drupal::moduleHandler()->invokeAll('recurring_events_save_pre_instances_deletion', [$event, $form_state]);
+        \Drupal::moduleHandler()->invokeAll('recurring_events_save_pre_instances_deletion', [$event, $original]);
 
         // Find all the instances and delete them.
         $instances = $event->event_instances->referencedEntities();
@@ -454,13 +467,13 @@ class EventCreationService {
         }
 
         // Allow other modules to react after the deletion of all instances.
-        \Drupal::moduleHandler()->invokeAll('recurring_events_save_post_instances_deletion', [$event, $form_state]);
+        \Drupal::moduleHandler()->invokeAll('recurring_events_save_post_instances_deletion', [$event, $original]);
       }
     }
 
     // Only create instances if date changes have been made or the event is new.
     if ($create_instances) {
-      $this->createInstances($event, $form_state);
+      $this->createInstances($event);
     }
   }
 
@@ -469,11 +482,9 @@ class EventCreationService {
    *
    * @param Drupal\recurring_events\Entity\EventSeries $event
    *   The stored event series entity.
-   * @param Drupal\Core\Form\FormStateInterface $form_state
-   *   The form state of an updated event series entity.
    */
-  public function createInstances(EventSeries $event, FormStateInterface $form_state) {
-    $form_data = $this->convertFormConfigToArray($form_state);
+  public function createInstances(EventSeries $event) {
+    $form_data = $this->convertEntityConfigToArray($event);
     $event_instances = [];
 
     $timezone = new \DateTimeZone(drupal_get_user_timezone());
@@ -634,7 +645,7 @@ class EventCreationService {
 
     // If the start date is after the end date then we have an invalid range so
     // just return nothing.
-    if ($start > $end) {
+    if ($start->getTimestamp() > $end->getTimestamp()) {
       return $dates;
     }
 
@@ -646,7 +657,7 @@ class EventCreationService {
 
     // Loop through a week at a time, storing the date in the array to return
     // until the end date is surpassed.
-    while ($start <= $end) {
+    while ($start->getTimestamp() <= $end->getTimestamp()) {
       // If we do not clone here we end up modifying the value of start in
       // the array and get some funky dates returned.
       $dates[] = clone $start;
@@ -682,7 +693,7 @@ class EventCreationService {
 
     // If the start date is after the end date then we have an invalid range so
     // just return nothing.
-    if ($start > $end) {
+    if ($start->getTimestamp() > $end->getTimestamp()) {
       return $dates;
     }
 
@@ -718,7 +729,7 @@ class EventCreationService {
 
     // Loop through each month checking to see if the day of the month is a
     // valid day, until the end date has been surpassed.
-    while ($start <= $end) {
+    while ($start->getTimestamp() <= $end->getTimestamp()) {
       // If we do not clone here we end up modifying the value of start in
       // the array and get some funky dates returned.
       $dates[] = clone $start;
@@ -787,7 +798,7 @@ class EventCreationService {
 
     // If the start date is after the end date then we have an invalid range so
     // just return nothing.
-    if ($start > $end_date) {
+    if ($start->getTimestamp() > $end_date->getTimestamp()) {
       return $dates;
     }
 
@@ -802,7 +813,7 @@ class EventCreationService {
 
     // Loop through a week at a time, storing the date in the array to return
     // until the end date is surpassed.
-    while ($start <= $end_date) {
+    while ($start->getTimestamp() <= $end_date->getTimestamp()) {
       // If we do not clone here we end up modifying the value of start in
       // the array and get some funky dates returned.
       $dates[] = clone $start;
diff --git a/src/EventInstanceStorage.php b/src/EventInstanceStorage.php
index 37abf099ae872d8909b64aeae5a2b4c27254d39a..ed1ae7c32fa8651ecab95b4b488c434384d506ee 100644
--- a/src/EventInstanceStorage.php
+++ b/src/EventInstanceStorage.php
@@ -5,7 +5,6 @@ namespace Drupal\recurring_events;
 use Drupal\Core\Entity\Sql\SqlContentEntityStorage;
 use Drupal\Core\Session\AccountInterface;
 use Drupal\Core\Language\LanguageInterface;
-use Drupal\recurring_events\EventInterface;
 
 /**
  * Defines the storage handler class for eventinstance entities.
diff --git a/src/EventInstanceStorageInterface.php b/src/EventInstanceStorageInterface.php
index 2a6e586eb79c79ff081c5d0532ba910878e302df..021ca2c75a0529b5da1ee1724501815dc6962d07 100644
--- a/src/EventInstanceStorageInterface.php
+++ b/src/EventInstanceStorageInterface.php
@@ -5,7 +5,6 @@ namespace Drupal\recurring_events;
 use Drupal\Core\Entity\ContentEntityStorageInterface;
 use Drupal\Core\Session\AccountInterface;
 use Drupal\Core\Language\LanguageInterface;
-use Drupal\recurring_events\EventInterface;
 
 /**
  * Defines the storage handler class for eventinstance entities.
diff --git a/src/EventInstanceTranslationHandler.php b/src/EventInstanceTranslationHandler.php
index ce1f6810b35bb2718a8c9bc2f88ffe74be110598..6f3e8a4a8d6cfa86e79151ae3c6876d14fb1246b 100644
--- a/src/EventInstanceTranslationHandler.php
+++ b/src/EventInstanceTranslationHandler.php
@@ -10,5 +10,4 @@ use Drupal\content_translation\ContentTranslationHandler;
 class EventInstanceTranslationHandler extends ContentTranslationHandler {
 
   // Override here the needed methods from ContentTranslationHandler.
-
 }
diff --git a/src/EventSeriesStorage.php b/src/EventSeriesStorage.php
index 76f60bb8b84095917075263e2da7edf866588c68..858a69e308522f2de6374e22ff3a23aa55049661 100644
--- a/src/EventSeriesStorage.php
+++ b/src/EventSeriesStorage.php
@@ -5,7 +5,6 @@ namespace Drupal\recurring_events;
 use Drupal\Core\Entity\Sql\SqlContentEntityStorage;
 use Drupal\Core\Session\AccountInterface;
 use Drupal\Core\Language\LanguageInterface;
-use Drupal\recurring_events\EventInterface;
 
 /**
  * Defines the storage handler class for eventseries entities.
diff --git a/src/EventSeriesStorageInterface.php b/src/EventSeriesStorageInterface.php
index 4d05919b53c120b3acf721f7a6190ed3a7d9b228..f4f1d568346446fdc98d043522450b1d75c38abf 100644
--- a/src/EventSeriesStorageInterface.php
+++ b/src/EventSeriesStorageInterface.php
@@ -5,7 +5,6 @@ namespace Drupal\recurring_events;
 use Drupal\Core\Entity\ContentEntityStorageInterface;
 use Drupal\Core\Session\AccountInterface;
 use Drupal\Core\Language\LanguageInterface;
-use Drupal\recurring_events\EventInterface;
 
 /**
  * Defines the storage handler class for eventseries entities.
diff --git a/src/EventSeriesTranslationHandler.php b/src/EventSeriesTranslationHandler.php
index f2e1d8170abb419afee9b6296e29f617305006b0..c6aa726251e80c740d6bd0742d8b958d6e34cf34 100644
--- a/src/EventSeriesTranslationHandler.php
+++ b/src/EventSeriesTranslationHandler.php
@@ -10,5 +10,4 @@ use Drupal\content_translation\ContentTranslationHandler;
 class EventSeriesTranslationHandler extends ContentTranslationHandler {
 
   // Override here the needed methods from ContentTranslationHandler.
-
 }
diff --git a/src/FieldInheritanceHtmlRouteProvider.php b/src/FieldInheritanceHtmlRouteProvider.php
index dd0fba9ebdcad329ca3195296f0d61a88ca6942b..52dd17146dda740ad59c8a7e8201c5fa69a9b24a 100644
--- a/src/FieldInheritanceHtmlRouteProvider.php
+++ b/src/FieldInheritanceHtmlRouteProvider.php
@@ -4,7 +4,6 @@ namespace Drupal\recurring_events;
 
 use Drupal\Core\Entity\EntityTypeInterface;
 use Drupal\Core\Entity\Routing\AdminHtmlRouteProvider;
-use Symfony\Component\Routing\Route;
 
 /**
  * Provides routes for Field inheritance entities.
@@ -21,7 +20,6 @@ class FieldInheritanceHtmlRouteProvider extends AdminHtmlRouteProvider {
     $collection = parent::getRoutes($entity_type);
 
     // Provide your custom entity routes here.
-
     return $collection;
   }
 
diff --git a/src/Form/EventSeriesForm.php b/src/Form/EventSeriesForm.php
index 23701789162f2e84b9a8cb11da1b511662772f95..d15764393c95619ae6cd1b33ff8a44d36d7675d3 100644
--- a/src/Form/EventSeriesForm.php
+++ b/src/Form/EventSeriesForm.php
@@ -231,13 +231,11 @@ class EventSeriesForm extends ContentEntityForm {
     }
 
     if ($entity->isDefaultTranslation()) {
-      $this->creationService->saveEvent($entity, $form_state, $original);
       $this->messenger->addStatus($this->t('Successfully saved the %name event series', [
         '%name' => $entity->title->value,
       ]));
     }
     else {
-
       $this->messenger->addStatus($this->t('@language translation of the @type %label has been saved.', [
         '@language' => $entity->language()->getName(),
         '@type' => 'Event ',