diff --git a/core/modules/hal/tests/src/Functional/EntityResource/DateFormat/DateFormatHalJsonAnonTest.php b/core/modules/hal/tests/src/Functional/EntityResource/DateFormat/DateFormatHalJsonAnonTest.php
new file mode 100644
index 0000000000000000000000000000000000000000..1bd6eb803c167126e98962918af78e188eee0771
--- /dev/null
+++ b/core/modules/hal/tests/src/Functional/EntityResource/DateFormat/DateFormatHalJsonAnonTest.php
@@ -0,0 +1,30 @@
+<?php
+
+namespace Drupal\Tests\hal\Functional\EntityResource\DateFormat;
+
+use Drupal\Tests\rest\Functional\AnonResourceTestTrait;
+use Drupal\Tests\rest\Functional\EntityResource\DateFormat\DateFormatResourceTestBase;
+
+/**
+ * @group hal
+ */
+class DateFormatHalJsonAnonTest extends DateFormatResourceTestBase {
+
+  use AnonResourceTestTrait;
+
+  /**
+   * {@inheritdoc}
+   */
+  public static $modules = ['hal'];
+
+  /**
+   * {@inheritdoc}
+   */
+  protected static $format = 'hal_json';
+
+  /**
+   * {@inheritdoc}
+   */
+  protected static $mimeType = 'application/hal+json';
+
+}
diff --git a/core/modules/hal/tests/src/Functional/EntityResource/DateFormat/DateFormatHalJsonBasicAuthTest.php b/core/modules/hal/tests/src/Functional/EntityResource/DateFormat/DateFormatHalJsonBasicAuthTest.php
new file mode 100644
index 0000000000000000000000000000000000000000..2627c99dbb0c2db1a7441afc033b4f8b28dfded4
--- /dev/null
+++ b/core/modules/hal/tests/src/Functional/EntityResource/DateFormat/DateFormatHalJsonBasicAuthTest.php
@@ -0,0 +1,35 @@
+<?php
+
+namespace Drupal\Tests\hal\Functional\EntityResource\DateFormat;
+
+use Drupal\Tests\rest\Functional\BasicAuthResourceTestTrait;
+use Drupal\Tests\rest\Functional\EntityResource\DateFormat\DateFormatResourceTestBase;
+
+/**
+ * @group hal
+ */
+class DateFormatHalJsonBasicAuthTest extends DateFormatResourceTestBase {
+
+  use BasicAuthResourceTestTrait;
+
+  /**
+   * {@inheritdoc}
+   */
+  public static $modules = ['hal', 'basic_auth'];
+
+  /**
+   * {@inheritdoc}
+   */
+  protected static $format = 'hal_json';
+
+  /**
+   * {@inheritdoc}
+   */
+  protected static $mimeType = 'application/hal+json';
+
+  /**
+   * {@inheritdoc}
+   */
+  protected static $auth = 'basic_auth';
+
+}
diff --git a/core/modules/hal/tests/src/Functional/EntityResource/DateFormat/DateFormatHalJsonCookieTest.php b/core/modules/hal/tests/src/Functional/EntityResource/DateFormat/DateFormatHalJsonCookieTest.php
new file mode 100644
index 0000000000000000000000000000000000000000..2367d6c0fa9fde2327424a48b8dd8567efc15270
--- /dev/null
+++ b/core/modules/hal/tests/src/Functional/EntityResource/DateFormat/DateFormatHalJsonCookieTest.php
@@ -0,0 +1,35 @@
+<?php
+
+namespace Drupal\Tests\hal\Functional\EntityResource\DateFormat;
+
+use Drupal\Tests\rest\Functional\CookieResourceTestTrait;
+use Drupal\Tests\rest\Functional\EntityResource\DateFormat\DateFormatResourceTestBase;
+
+/**
+ * @group hal
+ */
+class DateFormatHalJsonCookieTest extends DateFormatResourceTestBase {
+
+  use CookieResourceTestTrait;
+
+  /**
+   * {@inheritdoc}
+   */
+  public static $modules = ['hal'];
+
+  /**
+   * {@inheritdoc}
+   */
+  protected static $format = 'hal_json';
+
+  /**
+   * {@inheritdoc}
+   */
+  protected static $mimeType = 'application/hal+json';
+
+  /**
+   * {@inheritdoc}
+   */
+  protected static $auth = 'cookie';
+
+}
diff --git a/core/modules/rest/tests/src/Functional/EntityResource/DateFormat/DateFormatJsonAnonTest.php b/core/modules/rest/tests/src/Functional/EntityResource/DateFormat/DateFormatJsonAnonTest.php
new file mode 100644
index 0000000000000000000000000000000000000000..9fe8ea221c2e918abdeadc30a7ab6b140d883a9e
--- /dev/null
+++ b/core/modules/rest/tests/src/Functional/EntityResource/DateFormat/DateFormatJsonAnonTest.php
@@ -0,0 +1,24 @@
+<?php
+
+namespace Drupal\Tests\rest\Functional\EntityResource\DateFormat;
+
+use Drupal\Tests\rest\Functional\AnonResourceTestTrait;
+
+/**
+ * @group rest
+ */
+class DateFormatJsonAnonTest extends DateFormatResourceTestBase {
+
+  use AnonResourceTestTrait;
+
+  /**
+   * {@inheritdoc}
+   */
+  protected static $format = 'json';
+
+  /**
+   * {@inheritdoc}
+   */
+  protected static $mimeType = 'application/json';
+
+}
diff --git a/core/modules/rest/tests/src/Functional/EntityResource/DateFormat/DateFormatJsonBasicAuthTest.php b/core/modules/rest/tests/src/Functional/EntityResource/DateFormat/DateFormatJsonBasicAuthTest.php
new file mode 100644
index 0000000000000000000000000000000000000000..71f1f7fd659af1c53274911d7d4b79fec6c93f13
--- /dev/null
+++ b/core/modules/rest/tests/src/Functional/EntityResource/DateFormat/DateFormatJsonBasicAuthTest.php
@@ -0,0 +1,34 @@
+<?php
+
+namespace Drupal\Tests\rest\Functional\EntityResource\DateFormat;
+
+use Drupal\Tests\rest\Functional\BasicAuthResourceTestTrait;
+
+/**
+ * @group rest
+ */
+class DateFormatJsonBasicAuthTest extends DateFormatResourceTestBase {
+
+  use BasicAuthResourceTestTrait;
+
+  /**
+   * {@inheritdoc}
+   */
+  public static $modules = ['basic_auth'];
+
+  /**
+   * {@inheritdoc}
+   */
+  protected static $format = 'json';
+
+  /**
+   * {@inheritdoc}
+   */
+  protected static $mimeType = 'application/json';
+
+  /**
+   * {@inheritdoc}
+   */
+  protected static $auth = 'basic_auth';
+
+}
diff --git a/core/modules/rest/tests/src/Functional/EntityResource/DateFormat/DateFormatJsonCookieTest.php b/core/modules/rest/tests/src/Functional/EntityResource/DateFormat/DateFormatJsonCookieTest.php
new file mode 100644
index 0000000000000000000000000000000000000000..07c305f7aad3c08fb374f5fc3f3393a35508e8ad
--- /dev/null
+++ b/core/modules/rest/tests/src/Functional/EntityResource/DateFormat/DateFormatJsonCookieTest.php
@@ -0,0 +1,29 @@
+<?php
+
+namespace Drupal\Tests\rest\Functional\EntityResource\DateFormat;
+
+use Drupal\Tests\rest\Functional\CookieResourceTestTrait;
+
+/**
+ * @group rest
+ */
+class DateFormatJsonCookieTest extends DateFormatResourceTestBase {
+
+  use CookieResourceTestTrait;
+
+  /**
+   * {@inheritdoc}
+   */
+  protected static $format = 'json';
+
+  /**
+   * {@inheritdoc}
+   */
+  protected static $mimeType = 'application/json';
+
+  /**
+   * {@inheritdoc}
+   */
+  protected static $auth = 'cookie';
+
+}
diff --git a/core/modules/rest/tests/src/Functional/EntityResource/DateFormat/DateFormatResourceTestBase.php b/core/modules/rest/tests/src/Functional/EntityResource/DateFormat/DateFormatResourceTestBase.php
new file mode 100644
index 0000000000000000000000000000000000000000..8fce0fed15eccfcea2c6e3753888a6bfa5bd6e80
--- /dev/null
+++ b/core/modules/rest/tests/src/Functional/EntityResource/DateFormat/DateFormatResourceTestBase.php
@@ -0,0 +1,76 @@
+<?php
+
+namespace Drupal\Tests\rest\Functional\EntityResource\DateFormat;
+
+use Drupal\Core\Datetime\Entity\DateFormat;
+use Drupal\Tests\rest\Functional\EntityResource\EntityResourceTestBase;
+
+/**
+ * ResourceTestBase for DateFormat entity.
+ */
+abstract class DateFormatResourceTestBase extends EntityResourceTestBase {
+
+  /**
+   * {@inheritdoc}
+   */
+  public static $modules = [];
+
+  /**
+   * {@inheritdoc}
+   */
+  protected static $entityTypeId = 'date_format';
+
+  /**
+   * The DateFormat entity.
+   *
+   * @var \Drupal\Core\Datetime\DateFormatInterface
+   */
+  protected $entity;
+
+  /**
+   * {@inheritdoc}
+   */
+  protected function setUpAuthorization($method) {
+    $this->grantPermissionsToTestedRole(['administer site configuration']);
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  protected function createEntity() {
+    // Create a date format.
+    $date_format = DateFormat::create([
+      'id' => 'llama',
+      'label' => 'Llama',
+      'pattern' => 'F d, Y',
+    ]);
+
+    $date_format->save();
+
+    return $date_format;
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  protected function getExpectedNormalizedEntity() {
+    return [
+      'dependencies' => [],
+      'id' => 'llama',
+      'label' => 'Llama',
+      'langcode' => 'en',
+      'locked' => FALSE,
+      'pattern' => 'F d, Y',
+      'status' => TRUE,
+      'uuid' => $this->entity->uuid(),
+    ];
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  protected function getNormalizedPostEntity() {
+    // @todo Update in https://www.drupal.org/node/2300677.
+  }
+
+}
diff --git a/core/modules/system/src/DateFormatAccessControlHandler.php b/core/modules/system/src/DateFormatAccessControlHandler.php
index c9cee601ec3896630c0b0d4a6a95720dd84c7549..e56fe92a46a0eb4c493126baf1c6301fc87ca4a9 100644
--- a/core/modules/system/src/DateFormatAccessControlHandler.php
+++ b/core/modules/system/src/DateFormatAccessControlHandler.php
@@ -14,18 +14,23 @@
  */
 class DateFormatAccessControlHandler extends EntityAccessControlHandler {
 
+  /**
+   * {@inheritdoc}
+   */
+  protected $viewLabelOperation = TRUE;
+
   /**
    * {@inheritdoc}
    */
   protected function checkAccess(EntityInterface $entity, $operation, AccountInterface $account) {
-    // There are no restrictions on viewing a date format.
-    if ($operation == 'view') {
+    // There are no restrictions on viewing the label of a date format.
+    if ($operation === 'view label') {
       return AccessResult::allowed();
     }
     // Locked date formats cannot be updated or deleted.
     elseif (in_array($operation, ['update', 'delete'])) {
       if ($entity->isLocked()) {
-        return AccessResult::forbidden()->addCacheableDependency($entity);
+        return AccessResult::forbidden('The DateFormat config entity is locked.')->addCacheableDependency($entity);
       }
       else {
         return parent::checkAccess($entity, $operation, $account)->addCacheableDependency($entity);
diff --git a/core/modules/system/tests/src/Kernel/DateFormatAccessControlHandlerTest.php b/core/modules/system/tests/src/Kernel/DateFormatAccessControlHandlerTest.php
new file mode 100644
index 0000000000000000000000000000000000000000..01b09dc6bbd4cbb0bd424eb199f7a787f0ea4dcd
--- /dev/null
+++ b/core/modules/system/tests/src/Kernel/DateFormatAccessControlHandlerTest.php
@@ -0,0 +1,149 @@
+<?php
+
+namespace Drupal\Tests\system\Kernel;
+
+use Drupal\Core\Access\AccessResult;
+use Drupal\Core\Cache\Context\CacheContextsManager;
+use Drupal\Core\Datetime\Entity\DateFormat;
+use Drupal\Core\DependencyInjection\ContainerBuilder;
+use Drupal\KernelTests\KernelTestBase;
+use Drupal\simpletest\UserCreationTrait;
+
+/**
+ * @coversDefaultClass \Drupal\system\DateFormatAccessControlHandler
+ * @group system
+ */
+class DateFormatAccessControlHandlerTest extends KernelTestBase {
+
+  use UserCreationTrait {
+    createUser as drupalCreateUser;
+  }
+
+  /**
+   * Modules to enable.
+   *
+   * @var array
+   */
+  public static $modules = [
+    'system',
+    'user',
+  ];
+
+  /**
+   * The date_format access control handler.
+   *
+   * @var \Drupal\Core\Entity\EntityAccessControlHandlerInterface
+   */
+  protected $accessControlHandler;
+
+  /**
+   * {@inheritdoc}
+   */
+  protected function setUp() {
+    parent::setUp();
+    $this->installEntitySchema('date_format');
+    $this->installEntitySchema('user');
+    $this->installSchema('system', 'sequences');
+    $this->accessControlHandler = $this->container->get('entity_type.manager')->getAccessControlHandler('date_format');
+  }
+
+  /**
+   * @covers ::checkAccess
+   * @covers ::checkCreateAccess
+   * @dataProvider testAccessProvider
+   */
+  public function testAccess($which_user, $which_entity, $view_label_access_result, $view_access_result, $update_access_result, $delete_access_result, $create_access_result) {
+    // We must always create user 1, so that a "normal" user has a ID >1.
+    $root_user = $this->drupalCreateUser();
+
+    if ($which_user === 'user1') {
+      $user = $root_user;
+    }
+    else {
+      $permissions = ($which_user === 'admin')
+        ? ['administer site configuration']
+        : [];
+      $user = $this->drupalCreateUser($permissions);
+    }
+
+    $entity_values = ($which_entity === 'unlocked')
+      ? ['locked' => FALSE]
+      : ['locked' => TRUE];
+    $entity_values['id'] = $this->randomMachineName();
+    $entity = DateFormat::create($entity_values);
+    $entity->save();
+
+    static::assertEquals($view_label_access_result, $this->accessControlHandler->access($entity, 'view label', $user, TRUE));
+    static::assertEquals($view_access_result, $this->accessControlHandler->access($entity, 'view', $user, TRUE));
+    static::assertEquals($update_access_result, $this->accessControlHandler->access($entity, 'update', $user, TRUE));
+    static::assertEquals($delete_access_result, $this->accessControlHandler->access($entity, 'delete', $user, TRUE));
+    static::assertEquals($create_access_result, $this->accessControlHandler->createAccess(NULL, $user, [], TRUE));
+  }
+
+  public function testAccessProvider() {
+    $c = new ContainerBuilder();
+    $cache_contexts_manager = $this->prophesize(CacheContextsManager::class);
+    $cache_contexts_manager->assertValidTokens()->willReturn(TRUE);
+    $cache_contexts_manager->reveal();
+    $c->set('cache_contexts_manager', $cache_contexts_manager);
+    \Drupal::setContainer($c);
+
+    return [
+      'permissionless + unlocked' => [
+        'permissionless',
+        'unlocked',
+        AccessResult::allowed(),
+        AccessResult::neutral()->addCacheContexts(['user.permissions'])->setReason("The 'administer site configuration' permission is required."),
+        AccessResult::neutral()->addCacheContexts(['user.permissions'])->setReason("The 'administer site configuration' permission is required.")->addCacheTags(['rendered']),
+        AccessResult::neutral()->addCacheContexts(['user.permissions'])->setReason("The 'administer site configuration' permission is required.")->addCacheTags(['rendered']),
+        AccessResult::neutral()->addCacheContexts(['user.permissions'])->setReason("The 'administer site configuration' permission is required."),
+      ],
+      'permissionless + locked' => [
+        'permissionless',
+        'locked',
+        AccessResult::allowed(),
+        AccessResult::neutral()->addCacheContexts(['user.permissions'])->setReason("The 'administer site configuration' permission is required."),
+        AccessResult::forbidden()->addCacheTags(['rendered'])->setReason("The DateFormat config entity is locked."),
+        AccessResult::forbidden()->addCacheTags(['rendered'])->setReason("The DateFormat config entity is locked."),
+        AccessResult::neutral()->addCacheContexts(['user.permissions'])->setReason("The 'administer site configuration' permission is required."),
+      ],
+      'admin + unlocked' => [
+        'admin',
+        'unlocked',
+        AccessResult::allowed(),
+        AccessResult::allowed()->addCacheContexts(['user.permissions']),
+        AccessResult::allowed()->addCacheContexts(['user.permissions'])->addCacheTags(['rendered']),
+        AccessResult::allowed()->addCacheContexts(['user.permissions'])->addCacheTags(['rendered']),
+        AccessResult::allowed()->addCacheContexts(['user.permissions']),
+      ],
+      'admin + locked' => [
+        'admin',
+        'locked',
+        AccessResult::allowed(),
+        AccessResult::allowed()->addCacheContexts(['user.permissions']),
+        AccessResult::forbidden()->addCacheTags(['rendered'])->setReason("The DateFormat config entity is locked."),
+        AccessResult::forbidden()->addCacheTags(['rendered'])->setReason("The DateFormat config entity is locked."),
+        AccessResult::allowed()->addCacheContexts(['user.permissions']),
+      ],
+      'user1 + unlocked' => [
+        'user1',
+        'unlocked',
+        AccessResult::allowed(),
+        AccessResult::allowed()->addCacheContexts(['user.permissions']),
+        AccessResult::allowed()->addCacheContexts(['user.permissions'])->addCacheTags(['rendered']),
+        AccessResult::allowed()->addCacheContexts(['user.permissions'])->addCacheTags(['rendered']),
+        AccessResult::allowed()->addCacheContexts(['user.permissions']),
+      ],
+      'user1 + locked' => [
+        'user1',
+        'locked',
+        AccessResult::allowed(),
+        AccessResult::allowed()->addCacheContexts(['user.permissions']),
+        AccessResult::forbidden()->addCacheTags(['rendered'])->setReason("The DateFormat config entity is locked."),
+        AccessResult::forbidden()->addCacheTags(['rendered'])->setReason("The DateFormat config entity is locked."),
+        AccessResult::allowed()->addCacheContexts(['user.permissions']),
+      ],
+    ];
+  }
+
+}