diff --git a/core/modules/datetime_range/config/schema/datetime_range.schema.yml b/core/modules/datetime_range/config/schema/datetime_range.schema.yml
index f0f9325..f4765d3 100644
--- a/core/modules/datetime_range/config/schema/datetime_range.schema.yml
+++ b/core/modules/datetime_range/config/schema/datetime_range.schema.yml
@@ -5,6 +5,10 @@
 field.storage_settings.daterange:
   type: field.storage_settings.datetime
   label: 'Date range settings'
+  mapping:
+    optional_end_date:
+      type: boolean
+      label: 'Optional end date'
 
 field.field_settings.daterange:
   type: field.field_settings.datetime
diff --git a/core/modules/datetime_range/src/DateTimeRangeTrait.php b/core/modules/datetime_range/src/DateTimeRangeTrait.php
index 3f05b82..806e93f 100644
--- a/core/modules/datetime_range/src/DateTimeRangeTrait.php
+++ b/core/modules/datetime_range/src/DateTimeRangeTrait.php
@@ -17,13 +17,13 @@ public function viewElements(FieldItemListInterface $items, $langcode) {
     $separator = $this->getSetting('separator');
 
     foreach ($items as $delta => $item) {
-      if (!empty($item->start_date) && !empty($item->end_date)) {
+      if (!empty($item->start_date)) {
         /** @var \Drupal\Core\Datetime\DrupalDateTime $start_date */
         $start_date = $item->start_date;
         /** @var \Drupal\Core\Datetime\DrupalDateTime $end_date */
         $end_date = $item->end_date;
 
-        if ($start_date->getTimestamp() !== $end_date->getTimestamp()) {
+        if ($end_date !== NULL && $start_date->getTimestamp() !== $end_date->getTimestamp()) {
           $elements[$delta] = [
             'start_date' => $this->buildDateWithIsoAttribute($start_date),
             'separator' => ['#plain_text' => ' ' . $separator . ' '],
diff --git a/core/modules/datetime_range/src/Plugin/Field/FieldType/DateRangeItem.php b/core/modules/datetime_range/src/Plugin/Field/FieldType/DateRangeItem.php
index 7c34ed1..22e6c10 100644
--- a/core/modules/datetime_range/src/Plugin/Field/FieldType/DateRangeItem.php
+++ b/core/modules/datetime_range/src/Plugin/Field/FieldType/DateRangeItem.php
@@ -25,6 +25,15 @@
 class DateRangeItem extends DateTimeItem {
 
   /**
+   * {@inheritdoc}
+   */
+  public static function defaultStorageSettings() {
+    return [
+      'optional_end_date' => FALSE,
+    ] + parent::defaultStorageSettings();
+  }
+
+  /**
    * Value for the 'datetime_type' setting: store a date and time.
    */
   const DATETIME_TYPE_ALLDAY = 'allday';
@@ -46,7 +55,7 @@ public static function propertyDefinitions(FieldStorageDefinitionInterface $fiel
 
     $properties['end_value'] = DataDefinition::create('datetime_iso8601')
       ->setLabel(t('End date value'))
-      ->setRequired(TRUE);
+      ->setRequired(!$field_definition->getSetting('optional_end_date'));
 
     $properties['end_date'] = DataDefinition::create('any')
       ->setLabel(t('Computed end date'))
@@ -83,6 +92,12 @@ public function storageSettingsForm(array &$form, FormStateInterface $form_state
 
     $element['datetime_type']['#options'][static::DATETIME_TYPE_ALLDAY] = $this->t('All Day');
 
+    $element['optional_end_date'] = [
+      '#type' => 'checkbox',
+      '#title' => t('Optional end date'),
+      '#default_value' => $this->getSetting('optional_end_date'),
+    ];
+
     return $element;
   }
 
@@ -112,6 +127,10 @@ public static function generateSampleValue(FieldDefinitionInterface $field_defin
    */
   public function isEmpty() {
     $start_value = $this->get('value')->getValue();
+    if ($this->getFieldDefinition()->getFieldStorageDefinition()->getSetting('optional_end_date')) {
+      return $start_value === NULL || $start_value === '';
+    }
+
     $end_value = $this->get('end_value')->getValue();
     return ($start_value === NULL || $start_value === '') && ($end_value === NULL || $end_value === '');
   }
