diff --git a/core/includes/theme.inc b/core/includes/theme.inc
index 9b89250..14be5db 100644
--- a/core/includes/theme.inc
+++ b/core/includes/theme.inc
@@ -24,6 +24,7 @@
 use Drupal\Component\Utility\NestedArray;
 use Drupal\Core\Render\Element;
 use Drupal\Core\Render\Markup;
+use Drupal\Component\Utility\Xss;
 
 /**
  * @defgroup content_flags Content markers
@@ -577,7 +578,13 @@ function template_preprocess_datetime_wrapper(&$variables) {
   $variables['errors'] = NULL;
 
   if (!empty($element['#description'])) {
+    // Add aria-describedby attribute to title tag for screen readers.
     $variables['description'] = $element['#description'];
+    $variables['attributes']['class'][] = 'description';
+    // Associate the description with the aria-describedby attribute.
+    $variables['attributes']['id'] = $variables['attributes']['aria-describedby'];
+    // Remove aria-describedby attribute as it shouldn't be visible here.
+    unset($variables['attributes']['aria-describedby']);
   }
 
   $variables['required'] = FALSE;
@@ -590,6 +597,45 @@ function template_preprocess_datetime_wrapper(&$variables) {
 }
 
 /**
+ * Prepares variables for datetime fieldset form wrapper templates.
+ *
+ * Default template: datetime-fieldset-wrapper.html.twig.
+ *
+ * @param array $variables
+ *   An associative array containing:
+ *   - element: An associative array containing the properties of the element.
+ *     Properties used: #attributes, ,#content, #description, #id, #title,
+ *     #required.
+ */
+function template_preprocess_datetime_fieldset_wrapper(&$variables) {
+  $element = $variables['element'];
+  $variables['content'] = $element['#children'];
+  $variables['attributes'] = $element['#attributes'];
+  $variables['attributes']['class'][] = 'form-item';
+  $legend_attributes = array();
+  if (isset($element['#title_display']) && $element['#title_display'] == 'invisible') {
+    $legend_attributes['class'][] = 'visually-hidden';
+  }
+  $variables['legend']['attributes'] = new Attribute($legend_attributes);
+  if (!empty($element['#title'])) {
+    $variables['legend']['title'] = Xss::filterAdmin($element['#title']);
+  }
+  $legend_span_attributes = array('class' => array('fieldset-legend'));
+  if (!empty($element['#required'])) {
+    $legend_span_attributes['class'][] = 'form-required';
+    $variables['legend_span']['attributes'] = new Attribute($legend_span_attributes);
+  }
+  if (!empty($element['#description'])) {
+    $description_attributes = array(
+      'class' => 'description',
+      'id' => $element['#attributes']['aria-describedby'],
+    );
+    $variables['description']['attributes'] = new Attribute($description_attributes);
+    $variables['description']['content'] = $element['#description'];
+  }
+}
+
+/**
  * Prepares variables for links templates.
  *
  * Default template: links.html.twig.
@@ -1736,6 +1782,10 @@ function drupal_common_theme() {
     'datetime_wrapper' => array(
       'render element' => 'element',
     ),
+    'datetime_fieldset_wrapper' => array(
+      'template' => 'datetime-fieldset-wrapper',
+      'render element' => 'element',
+    ),
     'status_messages' => array(
       'variables' => ['status_headings' => [], 'message_list' => NULL],
     ),
diff --git a/core/modules/datetime/src/Plugin/Field/FieldWidget/DateTimeDefaultWidget.php b/core/modules/datetime/src/Plugin/Field/FieldWidget/DateTimeDefaultWidget.php
index 89381ab..61925af 100644
--- a/core/modules/datetime/src/Plugin/Field/FieldWidget/DateTimeDefaultWidget.php
+++ b/core/modules/datetime/src/Plugin/Field/FieldWidget/DateTimeDefaultWidget.php
@@ -64,6 +64,7 @@ public function formElement(FieldItemListInterface $items, $delta, array $elemen
       case DateTimeItem::DATETIME_TYPE_DATE:
         $date_type = 'date';
         $time_type = 'none';
+        $element['#theme_wrappers'][] = 'datetime_wrapper';
         $date_format = $this->dateStorage->load('html_date')->getPattern();
         $time_format = '';
         break;
@@ -71,6 +72,7 @@ public function formElement(FieldItemListInterface $items, $delta, array $elemen
       default:
         $date_type = 'date';
         $time_type = 'time';
+        $element['#theme_wrappers'][] = 'datetime_fieldset_wrapper';
         $date_format = $this->dateStorage->load('html_date')->getPattern();
         $time_format = $this->dateStorage->load('html_time')->getPattern();
         break;
diff --git a/core/modules/datetime/src/Tests/DateTimeFieldTest.php b/core/modules/datetime/src/Tests/DateTimeFieldTest.php
index ce598bf..9e6a776 100644
--- a/core/modules/datetime/src/Tests/DateTimeFieldTest.php
+++ b/core/modules/datetime/src/Tests/DateTimeFieldTest.php
@@ -297,6 +297,7 @@ function testDatetimeField() {
     $this->drupalGet('entity_test/add');
     $this->assertFieldByName("{$field_name}[0][value][date]", '', 'Date element found.');
     $this->assertFieldByName("{$field_name}[0][value][time]", '', 'Time element found.');
+    $this->assertFieldByXPath('//*[@id="edit-' . $field_name . '-wrapper"]/fieldset/legend/span[contains(@class, "form-required")]', TRUE, 'Required markup found');
 
     // Build up a date in the UTC timezone.
     $value = '2012-12-31 00:00:00';
diff --git a/core/modules/system/css/components/container-inline.module.css b/core/modules/system/css/components/container-inline.module.css
index ba99a36..5533e8a 100644
--- a/core/modules/system/css/components/container-inline.module.css
+++ b/core/modules/system/css/components/container-inline.module.css
@@ -11,3 +11,6 @@
 .container-inline .details-wrapper {
   display: block;
 }
+.container-inline .description {
+  display: block;
+}
diff --git a/core/modules/system/templates/datetime-fieldset-wrapper.html.twig b/core/modules/system/templates/datetime-fieldset-wrapper.html.twig
new file mode 100644
index 0000000..91cc75f
--- /dev/null
+++ b/core/modules/system/templates/datetime-fieldset-wrapper.html.twig
@@ -0,0 +1,34 @@
+{#
+/**
+ * @file
+ * Default theme implementation of a datetime fieldset form wrapper.
+ *
+ * Available variables:
+ * - attributes: HTML attributes for the fieldset element.
+ * - required: The required marker or empty if the associated fieldset is
+ *   not required.
+ * - legend: The legend element containing the following properties:
+ *   - title: Title of the fieldset, intended for use as the text of the legend.
+ *   - attributes: HTML attributes to apply to the legend.
+ * - description: The description element containing the following properties:
+ *   - content: The description content of the fieldset.
+ *   - attributes: HTML attributes to apply to the description container.
+ * - content: The form element to be output.
+ *
+ * @see template_preprocess_datetime_fieldset_wrapper()
+ *
+ * @ingroup themeable
+ */
+#}
+<fieldset{{ attributes }}>
+  {% if legend.title is not empty or required -%}
+    {#  Always wrap fieldset legends in a SPAN for CSS positioning. #}
+    <legend{{ legend.attributes }}><span class="{{ legend_span.attributes.class }}">{{ legend.title }}{{ required }}</span></legend>
+  {%- endif %}
+  <div class="fieldset-wrapper">
+    {{ content }}
+    {% if description.content %}
+      <div{{ description.attributes }}>{{ description.content }}</div>
+    {% endif %}
+  </div>
+</fieldset>
diff --git a/core/modules/system/templates/datetime-wrapper.html.twig b/core/modules/system/templates/datetime-wrapper.html.twig
index 8430baa..7036633 100644
--- a/core/modules/system/templates/datetime-wrapper.html.twig
+++ b/core/modules/system/templates/datetime-wrapper.html.twig
@@ -8,6 +8,7 @@
  * - title: The title of the form element.
  * - title_attributes: HTML attributes for the title wrapper.
  * - description: Description text for the form element.
+ * - attributes: Attributes for the description field.
  * - required: An indicator for whether the associated form element is required.
  *
  * @see template_preprocess_datetime_wrapper()
@@ -30,4 +31,4 @@
     {{ errors }}
   </div>
 {% endif %}
-{{ description }}
+<div{{ attributes }}>{{ description }}</div>
diff --git a/core/modules/system/templates/fieldset.html.twig b/core/modules/system/templates/fieldset.html.twig
index bacd1d4..8b118fda 100644
--- a/core/modules/system/templates/fieldset.html.twig
+++ b/core/modules/system/templates/fieldset.html.twig
@@ -17,6 +17,7 @@
  * - children: The rendered child elements of the <fieldset>.
  * - prefix: The content to add before the <fieldset> children.
  * - suffix: The content to add after the <fieldset> children.
+ * - content: The form element to be output.
  *
  * @see template_preprocess_fieldset()
  *
@@ -53,6 +54,7 @@
       <span class="field-prefix">{{ prefix }}</span>
     {% endif %}
     {{ children }}
+    {{ content }}
     {% if suffix %}
       <span class="field-suffix">{{ suffix }}</span>
     {% endif %}
diff --git a/core/themes/stable/templates/form/datetime-fieldset-wrapper.html.twig b/core/themes/stable/templates/form/datetime-fieldset-wrapper.html.twig
new file mode 100644
index 0000000..91cc75f
--- /dev/null
+++ b/core/themes/stable/templates/form/datetime-fieldset-wrapper.html.twig
@@ -0,0 +1,34 @@
+{#
+/**
+ * @file
+ * Default theme implementation of a datetime fieldset form wrapper.
+ *
+ * Available variables:
+ * - attributes: HTML attributes for the fieldset element.
+ * - required: The required marker or empty if the associated fieldset is
+ *   not required.
+ * - legend: The legend element containing the following properties:
+ *   - title: Title of the fieldset, intended for use as the text of the legend.
+ *   - attributes: HTML attributes to apply to the legend.
+ * - description: The description element containing the following properties:
+ *   - content: The description content of the fieldset.
+ *   - attributes: HTML attributes to apply to the description container.
+ * - content: The form element to be output.
+ *
+ * @see template_preprocess_datetime_fieldset_wrapper()
+ *
+ * @ingroup themeable
+ */
+#}
+<fieldset{{ attributes }}>
+  {% if legend.title is not empty or required -%}
+    {#  Always wrap fieldset legends in a SPAN for CSS positioning. #}
+    <legend{{ legend.attributes }}><span class="{{ legend_span.attributes.class }}">{{ legend.title }}{{ required }}</span></legend>
+  {%- endif %}
+  <div class="fieldset-wrapper">
+    {{ content }}
+    {% if description.content %}
+      <div{{ description.attributes }}>{{ description.content }}</div>
+    {% endif %}
+  </div>
+</fieldset>
