diff --git a/core/lib/Drupal/Core/Datetime/DateFormatter.php b/core/lib/Drupal/Core/Datetime/DateFormatter.php
index 7b56e77e0777b981e021c952dc4c0ee6f81c2daf..0b4f817f46fd5013fb146edf8fba84507a079ba0 100644
--- a/core/lib/Drupal/Core/Datetime/DateFormatter.php
+++ b/core/lib/Drupal/Core/Datetime/DateFormatter.php
@@ -192,33 +192,6 @@ public function formatInterval($interval, $granularity = 2, $langcode = NULL) {
     return $output ? $output : $this->t('0 sec', array(), array('langcode' => $langcode));
   }
 
-  /**
-   * Provides values for all date formatting characters for a given timestamp.
-   *
-   * @param string|null $langcode
-   *   (optional) Language code of the date format, if different from the site
-   *   default language.
-   * @param int|null $timestamp
-   *   (optional) The Unix timestamp to format, defaults to the request time.
-   * @param string|null $timezone
-   *   (optional) The timezone to use, if different from the site's default
-   *   timezone.
-   *
-   * @return array
-   *   An array of formatted date values, indexed by the date format character.
-   *
-   * @see date()
-   */
-  public function getSampleDateFormats($langcode = NULL, $timestamp = NULL, $timezone = NULL) {
-    $timestamp = $timestamp ?: (int) $_SERVER['REQUEST_TIME'];
-    // All date format characters for the PHP date() function.
-    $date_chars = str_split('dDjlNSwzWFmMntLoYyaABgGhHisueIOPTZcrU');
-    $date_elements = array_combine($date_chars, $date_chars);
-    return array_map(function($character) use ($timestamp, $timezone, $langcode) {
-      return $this->format($timestamp, 'custom', $character, $timezone, $langcode);
-    }, $date_elements);
-  }
-
   /**
    * Loads the given format pattern for the given langcode.
    *
@@ -227,9 +200,8 @@ public function getSampleDateFormats($langcode = NULL, $timestamp = NULL, $timez
    * @param string $langcode
    *   The langcode of the language to use.
    *
-   * @return string|null
-   *   The pattern for the date format in the given language for non-custom
-   *   formats, NULL otherwise.
+   * @return string
+   *   The pattern for the date format in the given language.
    */
   protected function dateFormat($format, $langcode) {
     if (!isset($this->dateFormats[$format][$langcode])) {
diff --git a/core/modules/config_translation/src/Form/ConfigTranslationFormBase.php b/core/modules/config_translation/src/Form/ConfigTranslationFormBase.php
index c4dfa10ec3499fe166f50ba6a593121d0c3cec6c..9e5372f05893d323a0dd1977e7d19dbedc63b841 100644
--- a/core/modules/config_translation/src/Form/ConfigTranslationFormBase.php
+++ b/core/modules/config_translation/src/Form/ConfigTranslationFormBase.php
@@ -176,9 +176,6 @@ public function buildForm(array $form, FormStateInterface $form_state, Request $
       if ($form_element = $this->createFormElement($schema)) {
         $parents = array('config_names', $name);
         $form['config_names'][$name] += $form_element->getTranslationBuild($this->sourceLanguage, $this->language, $source_config, $translation_config, $parents);
-        if ($attributes = $form_element->getFormAttributes()) {
-          $form = array_merge_recursive($form, $attributes);
-        }
       }
     }
 
diff --git a/core/modules/config_translation/src/FormElement/DateFormat.php b/core/modules/config_translation/src/FormElement/DateFormat.php
index b5979a007a734af9fb3d87db68f86f3ef6fbb66e..729afeee94265366b9c4d065b8628e50c3fbee4f 100644
--- a/core/modules/config_translation/src/FormElement/DateFormat.php
+++ b/core/modules/config_translation/src/FormElement/DateFormat.php
@@ -22,29 +22,51 @@ class DateFormat extends FormElementBase {
    * {@inheritdoc}
    */
   public function getTranslationElement(LanguageInterface $translation_language, $source_config, $translation_config) {
-    /** @var \Drupal\Core\Datetime\DateFormatter $date_formatter */
-    $date_formatter = \Drupal::service('date.formatter');
     $description = $this->t('A user-defined date format. See the <a href="@url">PHP manual</a> for available options.', array('@url' => 'http://php.net/manual/function.date.php'));
-    $format = $this->t('Displayed as %date_format', array('%date_format' => $date_formatter->format((int) $_SERVER['REQUEST_TIME'], 'custom', $translation_config)));
+    $format = $this->t('Displayed as %date_format', array('%date_format' => \Drupal::service('date.formatter')->format(REQUEST_TIME, 'custom', $translation_config)));
 
-    return [
+    return array(
       '#type' => 'textfield',
       '#description' => $description,
-      '#field_suffix' => ' <small data-drupal-date-formatter="preview">' . $format . '</small>',
-      '#attributes' => [
-        'data-drupal-date-formatter' => 'source',
-      ],
-      '#attached' => [
-        'drupalSettings' => array('dateFormats' => $date_formatter->getSampleDateFormats($translation_language->getId())),
-      ],
-    ] + parent::getTranslationElement($translation_language, $source_config, $translation_config);
+      '#field_suffix' => ' <div class="edit-date-format-suffix"><small id="edit-date-format-suffix">' . $format . '</small></div>',
+      '#ajax' => array(
+        'callback' => 'Drupal\config_translation\FormElement\DateFormat::ajaxSample',
+        'event' => 'keyup',
+        'progress' => array('type' => 'throbber', 'message' => NULL),
+      ),
+    ) + parent::getTranslationElement($translation_language, $source_config, $translation_config);
   }
 
   /**
-   * {@inheritdoc}
+   * Ajax callback to render a sample of the input date format.
+   *
+   * @param array $form
+   *   Form API array structure.
+   * @param \Drupal\Core\Form\FormStateInterface $form_state
+   *   Form state information.
+   *
+   * @return AjaxResponse
+   *   Ajax response with the rendered sample date using the given format. If
+   *   the given format cannot be identified or was empty, the response will
+   *   be empty as well.
    */
-  public function getFormAttributes() {
-    return ['#attached' => ['library' => ['system/drupal.system.date']]];
+  public static function ajaxSample(array $form, FormStateInterface $form_state) {
+    $response = new AjaxResponse();
+
+    $format_value = NestedArray::getValue($form_state->getValues(), $form_state->getTriggeringElement()['#array_parents']);
+    if (!empty($format_value)) {
+      // Format the date with a custom date format with the given pattern.
+      // The object is not instantiated in an Ajax context, so $this->t()
+      // cannot be used here.
+      $format = t('Displayed as %date_format', array('%date_format' => \Drupal::service('date.formatter')->format(REQUEST_TIME, 'custom', $format_value)));
+
+      // Return a command instead of a string, since the Ajax framework
+      // automatically prepends an additional empty DIV element for a string,
+      // which breaks the layout.
+      $response->addCommand(new ReplaceCommand('#edit-date-format-suffix', '<small id="edit-date-format-suffix">' . $format . '</small>'));
+    }
+
+    return $response;
   }
 
 }
diff --git a/core/modules/config_translation/src/FormElement/ElementInterface.php b/core/modules/config_translation/src/FormElement/ElementInterface.php
index c9fb0b9ee7b9b27aebd5df9a14deac8bbe0ab47a..286eeba0b847e3d53c4647cbade44c42d509a629 100644
--- a/core/modules/config_translation/src/FormElement/ElementInterface.php
+++ b/core/modules/config_translation/src/FormElement/ElementInterface.php
@@ -70,12 +70,4 @@ public function getTranslationBuild(LanguageInterface $source_language, Language
    */
   public function setConfig(Config $base_config, LanguageConfigOverride $config_translation, $config_values, $base_key = NULL);
 
-  /**
-   * Allows to provide form attributes for the configuration form.
-   *
-   * @return array
-   *   An array of form attributes.
-   */
-  public function getFormAttributes();
-
 }
diff --git a/core/modules/config_translation/src/FormElement/FormElementBase.php b/core/modules/config_translation/src/FormElement/FormElementBase.php
index ef76ef44447abded4fcc34b81d68a3f77724f264..e13cc31227c7af96cddd52cf65685ee733199c3f 100644
--- a/core/modules/config_translation/src/FormElement/FormElementBase.php
+++ b/core/modules/config_translation/src/FormElement/FormElementBase.php
@@ -74,13 +74,6 @@ public function getTranslationBuild(LanguageInterface $source_language, Language
     return $build;
   }
 
-  /**
-   * {@inheritdoc}
-   */
-  public function getFormAttributes() {
-    return [];
-  }
-
   /**
    * Returns the source element for a given configuration definition.
    *
diff --git a/core/modules/config_translation/src/FormElement/ListElement.php b/core/modules/config_translation/src/FormElement/ListElement.php
index 47232038d964ada0bd268fb872aa4abf131158b7..9365fc2a17471ed83492ba23971a6a6095649042 100644
--- a/core/modules/config_translation/src/FormElement/ListElement.php
+++ b/core/modules/config_translation/src/FormElement/ListElement.php
@@ -96,23 +96,6 @@ public function setConfig(Config $base_config, LanguageConfigOverride $config_tr
     }
   }
 
-  /**
-   * {@inheritdoc}
-   */
-  public function getFormAttributes() {
-    $attributes = [];
-    foreach ($this->element as $key => $element) {
-      if ($form_element = ConfigTranslationFormBase::createFormElement($element)) {
-        $form_attributes = $form_element->getFormAttributes();
-        if (empty($form_attributes)) {
-          continue;
-        }
-        $attributes += $form_attributes;
-      }
-    }
-    return $attributes;
-  }
-
   /**
    * Returns the title for the 'details' element of a group of schema elements.
    *
diff --git a/core/modules/config_translation/src/Tests/ConfigTranslationUiTest.php b/core/modules/config_translation/src/Tests/ConfigTranslationUiTest.php
index 00b36c526df309a4060b653f38abe341f19e6978..807307c9338a316306676b5b949cda2686572ab5 100644
--- a/core/modules/config_translation/src/Tests/ConfigTranslationUiTest.php
+++ b/core/modules/config_translation/src/Tests/ConfigTranslationUiTest.php
@@ -446,9 +446,6 @@ public function testDateFormatTranslation() {
       $this->drupalGet($translation_page_url);
       $this->assertText($label);
 
-      // Make sure that the date library is added.
-      $this->assertRaw('core/modules/system/js/system.date.js');
-
       // Update translatable fields.
       $edit = array(
         'translation[config_names][core.date_format.' . $id . '][label]' => $id . ' - FR',
diff --git a/core/modules/system/js/system.date.js b/core/modules/system/js/system.date.js
deleted file mode 100644
index fcab3efd55d91d65776ae374b6709332a4665c3c..0000000000000000000000000000000000000000
--- a/core/modules/system/js/system.date.js
+++ /dev/null
@@ -1,46 +0,0 @@
-(function ($, Drupal, drupalSettings) {
-
-  "use strict";
-
-  var dateFormats = drupalSettings.dateFormats;
-
-  /**
-   * Display the preview for date format entered.
-   */
-  Drupal.behaviors.dateFormat = {
-    attach: function (context) {
-      var $context = $(context);
-      var $source = $context.find('[data-drupal-date-formatter="source"]').once('dateFormat');
-      var $target = $context.find('[data-drupal-date-formatter="preview"]').once('dateFormat');
-      var $preview = $target.find('em');
-
-      // All elements have to exist.
-      if (!$source.length || !$target.length) {
-        return;
-      }
-
-      /**
-       * Event handler that replaces date characters with value.
-       *
-       * @param {object} e
-       */
-      function dateFormatHandler(e) {
-        var baseValue = $(e.target).val() || '';
-        var dateString = baseValue.replace(/\\?(.?)/gi, function (key, value) {
-          return dateFormats[key] ? dateFormats[key] : value;
-        });
-
-        $preview.html(dateString);
-        $target.toggleClass('js-hide', !dateString.length);
-      }
-
-      /**
-       * On given event triggers the date character replacement.
-       */
-      $source.on('keyup.dateFormat change.dateFormat input.dateFormat', dateFormatHandler)
-        // Initialize preview.
-        .trigger('keyup');
-    }
-  };
-
-})(jQuery, Drupal, drupalSettings);
diff --git a/core/modules/system/src/Form/DateFormatEditForm.php b/core/modules/system/src/Form/DateFormatEditForm.php
index 511ad1a935a5e60646c155acc487db610cc9d92c..f8e780f45aa5d6a69c437fb2654752fb2b2e4728 100644
--- a/core/modules/system/src/Form/DateFormatEditForm.php
+++ b/core/modules/system/src/Form/DateFormatEditForm.php
@@ -21,7 +21,7 @@ public function form(array $form, FormStateInterface $form_state) {
     $form = parent::form($form, $form_state);
 
     $now = t('Displayed as %date', array('%date' => $this->dateFormatter->format(REQUEST_TIME, $this->entity->id())));
-    $form['date_format_pattern']['#field_suffix'] = ' <small data-drupal-date-formatter="preview">' . $now . '</small>';
+    $form['date_format_pattern']['#field_suffix'] = ' <small id="edit-date-format-suffix">' . $now . '</small>';
     $form['date_format_pattern']['#default_value'] = $this->entity->getPattern();
 
     return $form;
diff --git a/core/modules/system/src/Form/DateFormatFormBase.php b/core/modules/system/src/Form/DateFormatFormBase.php
index 9061d895fa86eeba666aff6c8e4744142c6cab07..c843ba24210e8adfbbba6de2e116217fd6cde773 100644
--- a/core/modules/system/src/Form/DateFormatFormBase.php
+++ b/core/modules/system/src/Form/DateFormatFormBase.php
@@ -79,6 +79,30 @@ public function exists($entity_id, array $element) {
       ->execute();
   }
 
+  /**
+   * Returns the date for a given format string.
+   *
+   * @param array $form
+   *   An associative array containing the structure of the form.
+   * @param \Drupal\Core\Form\FormStateInterface $form_state
+   *   The current state of the form.
+   *
+   * @return \Drupal\Core\Ajax\AjaxResponse
+   *   An AJAX Response to update the date-time value of the date format.
+   */
+  public static function dateTimeLookup(array $form, FormStateInterface $form_state) {
+    $format = '';
+    if (!$form_state->isValueEmpty('date_format_pattern')) {
+      $format = t('Displayed as %date_format', array('%date_format' => \Drupal::service('date.formatter')->format(REQUEST_TIME, 'custom', $form_state->getValue('date_format_pattern'))));
+    }
+    // Return a command instead of a string, since the Ajax framework
+    // automatically prepends an additional empty DIV element for a string, which
+    // breaks the layout.
+    $response = new AjaxResponse();
+    $response->addCommand(new ReplaceCommand('#edit-date-format-suffix', '<small id="edit-date-format-suffix">' . $format . '</small>'));
+    return $response;
+  }
+
   /**
    * {@inheritdoc}
    */
@@ -102,16 +126,20 @@ public function form(array $form, FormStateInterface $form_state) {
         'error' => $this->t('The machine-readable name must be unique, and can only contain lowercase letters, numbers, and underscores. Additionally, it can not be the reserved word "custom".'),
       ),
     );
+
     $form['date_format_pattern'] = array(
       '#type' => 'textfield',
       '#title' => t('Format string'),
       '#maxlength' => 100,
       '#description' => $this->t('A user-defined date format. See the <a href="@url">PHP manual</a> for available options.', array('@url' => 'http://php.net/manual/function.date.php')),
+      '#default_value' => '',
+      '#field_suffix' => ' <small id="edit-date-format-suffix"></small>',
+      '#ajax' => array(
+        'callback' => '::dateTimeLookup',
+        'event' => 'keyup',
+        'progress' => array('type' => 'throbber', 'message' => NULL),
+      ),
       '#required' => TRUE,
-      '#attributes' => [
-        'data-drupal-date-formatter' => 'source',
-      ],
-      '#field_suffix' => ' <small class="js-hide" data-drupal-date-formatter="preview">' . $this->t('Displayed as %date_format', ['%date_format' => '']) . '</small>',
     );
 
     $form['langcode'] = array(
@@ -120,8 +148,7 @@ public function form(array $form, FormStateInterface $form_state) {
       '#languages' => LanguageInterface::STATE_ALL,
       '#default_value' => $this->entity->language()->getId(),
     );
-    $form['#attached']['drupalSettings']['dateFormats'] = $this->dateFormatter->getSampleDateFormats();
-    $form['#attached']['library'][] = 'system/drupal.system.date';
+
     return parent::form($form, $form_state);
   }
 
diff --git a/core/modules/system/js/system.js b/core/modules/system/system.js
similarity index 100%
rename from core/modules/system/js/system.js
rename to core/modules/system/system.js
diff --git a/core/modules/system/system.libraries.yml b/core/modules/system/system.libraries.yml
index b440e157f4be1e660eef0ec50b754fd660a79004..34c90ddd88d894fcdb2e29e9861bbfdfc4aa981d 100644
--- a/core/modules/system/system.libraries.yml
+++ b/core/modules/system/system.libraries.yml
@@ -29,7 +29,7 @@ maintenance:
 drupal.system:
   version: VERSION
   js:
-    js/system.js: {}
+    system.js: {}
   dependencies:
     - core/jquery
     - core/drupal
@@ -39,7 +39,7 @@ drupal.system:
 drupal.system.modules:
   version: VERSION
   js:
-    js/system.modules.js: {}
+    system.modules.js: {}
   dependencies:
     - core/jquery
     - core/drupal
@@ -50,14 +50,3 @@ diff:
   css:
     component:
       css/system.diff.css: {}
-
-drupal.system.date:
-  version: VERSION
-  js:
-    js/system.date.js: {}
-  dependencies:
-    - core/jquery
-    - core/drupal
-    - core/drupalSettings
-    - core/jquery.once
-    - core/drupal.form
diff --git a/core/modules/system/js/system.modules.js b/core/modules/system/system.modules.js
similarity index 100%
rename from core/modules/system/js/system.modules.js
rename to core/modules/system/system.modules.js
diff --git a/core/tests/Drupal/Tests/Core/Datetime/DateTest.php b/core/tests/Drupal/Tests/Core/Datetime/DateTest.php
index 4534ccd0bf98bcd9f9178f0f1e4d7cdfbb5c4d27..da9ebaa0ba63037784f02b887fa7941c3def1054 100644
--- a/core/tests/Drupal/Tests/Core/Datetime/DateTest.php
+++ b/core/tests/Drupal/Tests/Core/Datetime/DateTest.php
@@ -5,10 +5,9 @@
  * Contains \Drupal\Tests\Core\Datetime\DateTest.
  */
 
-namespace Drupal\Tests\Core\Datetime {
+namespace Drupal\Tests\Core\Datetime;
 
 use Drupal\Core\Datetime\DateFormatter;
-use Drupal\Core\DependencyInjection\ContainerBuilder;
 use Drupal\Tests\UnitTestCase;
 
 /**
@@ -46,21 +45,10 @@ class DateTest extends UnitTestCase {
   protected $dateFormatter;
 
   protected function setUp() {
-    parent::setUp();
-
-    $entity_storage = $this->getMock('Drupal\Core\Entity\EntityStorageInterface');
-
     $this->entityManager = $this->getMock('Drupal\Core\Entity\EntityManagerInterface');
-    $this->entityManager->expects($this->once())->method('getStorage')->with('date_format')->willReturn($entity_storage);
-
     $this->languageManager = $this->getMock('Drupal\Core\Language\LanguageManagerInterface');
     $this->stringTranslation = $this->getMock('Drupal\Core\StringTranslation\TranslationInterface');
 
-    $config_factory = $this->getConfigFactoryStub(['system.date' => ['country' => ['default' => 'GB']]]);
-    $container = new ContainerBuilder();
-    $container->set('config.factory', $config_factory);
-    \Drupal::setContainer($container);
-
     $this->dateFormatter = new DateFormatter($this->entityManager, $this->languageManager, $this->stringTranslation, $this->getConfigFactoryStub());
   }
 
@@ -69,7 +57,7 @@ protected function setUp() {
    *
    * @dataProvider providerTestFormatInterval
    *
-   * @covers \Drupal\Core\Datetime\DateFormatter::formatInterval
+   * @see \Drupal\Core\Datetime\DateFormatter::formatInterval()
    */
   public function testFormatInterval($interval, $granularity, $expected, $langcode = NULL) {
     // Mocks a simple formatPlural implementation.
@@ -140,36 +128,4 @@ public function testFormatIntervalZeroSecond() {
     $this->assertEquals('0 sec', $result);
   }
 
-  /**
-   * Tests the getSampleDateFormats method.
-   *
-   * @covers \Drupal\Core\Datetime\DateFormatter::getSampleDateFormats
-   */
-  public function testGetSampleDateFormats() {
-    include_once $this->root . '/core/includes/common.inc';
-    $timestamp = strtotime('2015-03-22 14:23:00');
-    $expected = $this->dateFormatter->getSampleDateFormats('en', $timestamp, 'Europe/London');
-
-    // Removed characters related to timezone 'e' and 'T', as test does not have
-    // timezone set.
-    $date_characters = 'dDjlNSwzWFmMntLoYyaABgGhHisuIOPZcrU';
-    $date_chars = str_split($date_characters);
-
-    foreach ($date_chars as $val) {
-      $this->assertEquals($expected[$val], date($val, $timestamp));
-    }
-  }
-
-}
-
-}
-
-namespace {
-  use Drupal\Component\Utility\String;
-
-  if (!function_exists('t')) {
-    function t($string, array $args = []) {
-      return String::format($string, $args);
-    }
-  }
 }