diff --git a/core/lib/Drupal/Core/Datetime/Entity/DateFormat.php b/core/lib/Drupal/Core/Datetime/Entity/DateFormat.php
index 888a36bd49..41e641a7ec 100644
--- a/core/lib/Drupal/Core/Datetime/Entity/DateFormat.php
+++ b/core/lib/Drupal/Core/Datetime/Entity/DateFormat.php
@@ -5,6 +5,7 @@
 use Drupal\Core\Config\Entity\ConfigEntityBase;
 use Drupal\Core\Config\Entity\ConfigEntityInterface;
 use Drupal\Core\Datetime\DateFormatInterface;
+use Drupal\Core\Entity\EntityStorageInterface;
 
 /**
  * Defines the Date Format configuration entity class.
@@ -100,4 +101,22 @@ public function getCacheTagsToInvalidate() {
     return ['rendered'];
   }
 
+  /**
+   * {@inheritdoc}
+   */
+  public static function postDelete(EntityStorageInterface $storage, array $entities) {
+    parent::postDelete($storage, $entities);
+    \Drupal::token()->resetInfo();
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function postSave(EntityStorageInterface $storage, $update = TRUE) {
+    parent::postSave($storage, $update);
+    if (!$update) {
+      \Drupal::token()->resetInfo();
+    }
+  }
+
 }
diff --git a/core/modules/system/system.tokens.inc b/core/modules/system/system.tokens.inc
index a3a670a002..562be7ac0a 100644
--- a/core/modules/system/system.tokens.inc
+++ b/core/modules/system/system.tokens.inc
@@ -65,6 +65,19 @@ function system_token_info() {
     'name' => t("Long format"),
     'description' => t("A date in 'long' format. (%date)", ['%date' => $date_formatter->format(REQUEST_TIME, 'long')]),
   ];
+
+  /** @var \Drupal\Core\Datetime\DateFormatInterface[] $date_formats */
+  $date_formats = \Drupal::entityTypeManager()->getStorage('date_format')->loadMultiple();
+  foreach ($date_formats as $date_format) {
+    $date[$date_format->id()] = [
+      'name' => $date_format->label(),
+      'description' => t("A date in the %name format. (%date)", [
+        '%name' => $date_format->label(),
+        '%date' => $date_formatter->format(REQUEST_TIME, $date_format->id()),
+      ]),
+    ];
+  }
+
   $date['custom'] = [
     'name' => t("Custom format"),
     'description' => t('A date in a custom format. See <a href="http://php.net/manual/function.date.php">the PHP documentation</a> for details.'),
@@ -165,16 +178,17 @@ function system_tokens($type, $tokens, array $data, array $options, BubbleableMe
       $date = $data['date'];
     }
 
+    /** @var \Drupal\Core\Entity\EntityStorageInterface $date_format_storage */
+    $date_format_storage = \Drupal::entityTypeManager()->getStorage('date_format');
     foreach ($tokens as $name => $original) {
+      // Date type token replacement.
+      $date_format = $date_format_storage->load($name);
+      if ($date_format) {
+        $bubbleable_metadata->addCacheableDependency($date_format);
+        $replacements[$original] = \Drupal::service('date.formatter')->format($date, $name, '', NULL, $langcode);
+        continue;
+      }
       switch ($name) {
-        case 'short':
-        case 'medium':
-        case 'long':
-          $date_format = DateFormat::load($name);
-          $bubbleable_metadata->addCacheableDependency($date_format);
-          $replacements[$original] = \Drupal::service('date.formatter')->format($date, $name, '', NULL, $langcode);
-          break;
-
         case 'since':
           $replacements[$original] = \Drupal::service('date.formatter')->formatTimeDiffSince($date, ['langcode' => $langcode]);
           $bubbleable_metadata->setCacheMaxAge(0);
diff --git a/core/modules/system/tests/src/Kernel/Token/TokenReplaceKernelTest.php b/core/modules/system/tests/src/Kernel/Token/TokenReplaceKernelTest.php
index 9e878f5112..fb60e103e6 100644
--- a/core/modules/system/tests/src/Kernel/Token/TokenReplaceKernelTest.php
+++ b/core/modules/system/tests/src/Kernel/Token/TokenReplaceKernelTest.php
@@ -5,6 +5,7 @@
 use Drupal\Component\Render\FormattableMarkup;
 use Drupal\Component\Utility\Html;
 use Drupal\Component\Utility\Xss;
+use Drupal\Core\Datetime\Entity\DateFormat;
 use Drupal\Core\Render\BubbleableMetadata;
 
 /**
@@ -136,10 +137,20 @@ public function testSystemDateTokenReplacement() {
 
     // Generate and test tokens.
     $tests = [];
+    /** @var \Drupal\Core\Datetime\DateFormatterInterface $date_formatter */
     $date_formatter = \Drupal::service('date.formatter');
-    $tests['[date:short]'] = $date_formatter->format($date, 'short', '', NULL, $this->interfaceLanguage->getId());
-    $tests['[date:medium]'] = $date_formatter->format($date, 'medium', '', NULL, $this->interfaceLanguage->getId());
-    $tests['[date:long]'] = $date_formatter->format($date, 'long', '', NULL, $this->interfaceLanguage->getId());
+
+    // Test standard date format tokens.
+    $date_formats = array_keys(\Drupal::entityTypeManager()->getStorage('date_format')->loadMultiple());
+    $this->assertCount(11, $date_formats);
+    $this->assertTrue(in_array('short', $date_formats));
+    $this->assertTrue(in_array('medium', $date_formats));
+    $this->assertTrue(in_array('long', $date_formats));
+    $this->assertTrue(in_array('html_date', $date_formats));
+    foreach ($date_formats as $date_format) {
+      $tests['[date:' . $date_format . ']'] = $date_formatter->format($date, $date_format, '', NULL, $this->interfaceLanguage->getId());
+    }
+
     $tests['[date:custom:m/j/Y]'] = $date_formatter->format($date, 'custom', 'm/j/Y', NULL, $this->interfaceLanguage->getId());
     $tests['[date:since]'] = $date_formatter->formatTimeDiffSince($date, ['langcode' => $this->interfaceLanguage->getId()]);
     $tests['[date:raw]'] = Xss::filter($date);
@@ -153,4 +164,30 @@ public function testSystemDateTokenReplacement() {
     }
   }
 
+  /**
+   * Tests the generation of all system date format tokens when formats change.
+   */
+  public function testSystemDateTokenGetInfo() {
+    $tokens = \Drupal::token()->getInfo();
+    $this->assertArrayNotHasKey('y2k', $tokens['tokens']['date']);
+
+    // Add new tokens.
+    $date_format = DateFormat::create([
+      'id' => 'y2k',
+      'label' => 'Y2K',
+      'pattern' => 'y',
+    ]);
+    $date_format->save();
+
+    $tokens = \Drupal::token()->getInfo();
+    $this->assertArrayHasKey('y2k', $tokens['tokens']['date']);
+
+    // Delete new token.
+    DateFormat::load('y2k')->delete();
+
+    // Get the count of removed tokens.
+    $tokens = \Drupal::token()->getInfo();
+    $this->assertArrayNotHasKey('y2k', $tokens['tokens']['date']);
+  }
+
 }
