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 921010b2bb74f7279b5b8e8a5e1120d98fe2cc04..7900a35ce5d2f07de4475cc48dcb27701f99f702 100644
--- a/core/modules/datetime_range/config/schema/datetime_range.schema.yml
+++ b/core/modules/datetime_range/config/schema/datetime_range.schema.yml
@@ -7,12 +7,12 @@ field.storage_settings.daterange:
   label: 'Date range settings'
 
 field.field_settings.daterange:
-  type: field.field_settings.datetime
+  type: mapping
   label: 'Date range settings'
   mapping:
-    optional_end_date:
-      type: boolean
-      label: 'Optional end date'
+    optional_values:
+      type: integer
+      label: 'Optional values'
 
 field.value.daterange:
   type: mapping
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 9c5184ddcad377ff18c6a1336638f505d0ab2ee3..18bc48834ece8d7f8791327f3975d7d52f5d51c1 100644
--- a/core/modules/datetime_range/src/Plugin/Field/FieldType/DateRangeItem.php
+++ b/core/modules/datetime_range/src/Plugin/Field/FieldType/DateRangeItem.php
@@ -29,7 +29,7 @@ class DateRangeItem extends DateTimeItem {
    */
   public static function defaultFieldSettings() {
     return [
-      'optional_end_date' => FALSE,
+      'optional_values' => FALSE,
     ] + parent::defaultFieldSettings();
   }
 
@@ -38,6 +38,16 @@ public static function defaultFieldSettings() {
    */
   const DATETIME_TYPE_ALLDAY = 'allday';
 
+  /**
+   * Optional values setting, require a bounded datetime range.
+   */
+  const OPTIONAL_NONE = 0x01;
+
+  /**
+   * Optional values setting, do not require an end date.
+   */
+  const OPTIONAL_END = 0x02;
+
   /**
    * {@inheritdoc}
    */
@@ -89,11 +99,15 @@ public static function schema(FieldStorageDefinitionInterface $field_definition)
    */
   public function fieldSettingsForm(array $form, FormStateInterface $form_state) {
     $element = [];
-    $element['optional_end_date'] = [
-      '#type' => 'checkbox',
-      '#title' => $this->t('Optional end date'),
-      '#description' => $this->t('Allow end date to be optional opposed to the default behaviour where end date is required when "Required field" is checked.'),
-      '#default_value' => $this->getSetting('optional_end_date'),
+    $element['optional_values'] = [
+      '#type' => 'radios',
+      '#title' => $this->t('End date'),
+      '#description' => $this->t('Applies regardless of whether the whole field is required'),
+      '#default_value' => $this->getSetting('optional_values'),
+      '#options' => [
+        static::OPTIONAL_NONE => $this->t('Required'),
+        static::OPTIONAL_END => $this->t('Optional end date'),
+      ],
     ];
 
     return $element;
@@ -151,19 +165,29 @@ public function getConstraints() {
       ->getValidationConstraintManager();
     $constraints = parent::getConstraints();
 
-    if (!empty($this->getSetting('optional_end_date'))) {
-      return $constraints;
-    }
-
-    $label = $this->getFieldDefinition()->getLabel();
-    $constraints[] = $constraint_manager
-      ->create('ComplexData', [
-        'end_value' => [
-          'NotNull' => [
-            'message' => $this->t('The @title end date is required', ['@title' => $label]),
+    if (!$this->getFieldDefinition()->isRequired()) {
+      $label = $this->getFieldDefinition()->getLabel();
+      // If the end date triggers constraint validation then test the start date.
+      $constraints[] = $constraint_manager
+        ->create('ComplexData', [
+          'value' => [
+            'NotNull' => [
+              'message' => $this->t('The @title start date is required', ['@title' => $label]),
+            ],
           ],
-        ],
-      ]);
+        ]);
+      // Testing the end date is only needed if not required and not optional.
+      if ($this->getSetting('optional_values') == static::OPTIONAL_NONE) {
+        $constraints[] = $constraint_manager
+          ->create('ComplexData', [
+            'end_value' => [
+              'NotNull' => [
+                'message' => $this->t('The @title end date is required', ['@title' => $label]),
+              ],
+            ],
+          ]);
+      }
+    }
 
     return $constraints;
   }
diff --git a/core/modules/datetime_range/src/Plugin/Field/FieldWidget/DateRangeWidgetBase.php b/core/modules/datetime_range/src/Plugin/Field/FieldWidget/DateRangeWidgetBase.php
index ee894f56da493d7e54c0b5f8e3cb19fdf71df9e6..a5de90790394141abeedd8ee41df91e623950804 100644
--- a/core/modules/datetime_range/src/Plugin/Field/FieldWidget/DateRangeWidgetBase.php
+++ b/core/modules/datetime_range/src/Plugin/Field/FieldWidget/DateRangeWidgetBase.php
@@ -19,7 +19,7 @@ class DateRangeWidgetBase extends DateTimeWidgetBase {
    */
   public function formElement(FieldItemListInterface $items, $delta, array $element, array &$form, FormStateInterface $form_state) {
     $element = parent::formElement($items, $delta, $element, $form, $form_state);
-    $optional_end_date = $this->getFieldSetting('optional_end_date');
+    $optional_values = $this->getFieldSetting('optional_values');
 
     // Wrap all of the select elements with a fieldset.
     $element['#theme_wrappers'][] = 'fieldset';
@@ -31,7 +31,7 @@ public function formElement(FieldItemListInterface $items, $delta, array $elemen
       '#title' => $this->t('End date'),
     ] + $element['value'];
 
-    if ($element['#required'] && $optional_end_date) {
+    if ($element['#required'] && $optional_values == DateRangeItem::OPTIONAL_END) {
       $element['end_value']['#required'] = FALSE;
       $element['#required'] = FALSE;
     }
diff --git a/core/modules/datetime_range/tests/src/Kernel/DateRangeItemTest.php b/core/modules/datetime_range/tests/src/Kernel/DateRangeItemTest.php
index 4a8cb580157930c91714a9e3946ec532942e7b8b..a7e5b174997334aaa8303f29d08659d197250fcf 100644
--- a/core/modules/datetime_range/tests/src/Kernel/DateRangeItemTest.php
+++ b/core/modules/datetime_range/tests/src/Kernel/DateRangeItemTest.php
@@ -110,7 +110,7 @@ public function testOptionalEndDate() {
     $field_name = $this->fieldStorage->getName();
 
     $this->field->setSettings([
-      'optional_end_date' => FALSE,
+      'optional_values' => DateRangeItem::OPTIONAL_NONE,
     ])
       ->save();
 
@@ -126,7 +126,7 @@ public function testOptionalEndDate() {
     $this->assertNotEquals(count($entity->validate()), 0);
 
     // Verify entity with the optional_end_date enabled.
-    $this->field->setSetting('optional_end_date', TRUE)
+    $this->field->setSetting('optional_values', DateRangeItem::OPTIONAL_END)
       ->save();
     $entity = EntityTest::create([
       'name' => $this->randomString(),