diff --git a/core/lib/Drupal/Component/Datetime/DateTimePlus.php b/core/lib/Drupal/Component/Datetime/DateTimePlus.php
index 56bd92f237..fb13b0f412 100644
--- a/core/lib/Drupal/Component/Datetime/DateTimePlus.php
+++ b/core/lib/Drupal/Component/Datetime/DateTimePlus.php
@@ -23,7 +23,7 @@
  * to abort processing. The calling script can decide what to do about
  * errors using hasErrors() and getErrors().
  */
-class DateTimePlus {
+class DateTimePlus implements \JsonSerializable {
 
   use ToStringTrait;
 
@@ -288,6 +288,15 @@ public function __construct($time = 'now', $timezone = NULL, $settings = array()
   }
 
   /**
+   * Returns the DateTime object and langcode for use in JSON serialization.
+   *
+   * @return string
+   */
+  public function jsonSerialize() {
+    return array('datetime' => $this->dateTimeObject, 'langcode' => $this->langcode);
+  }
+
+  /**
    * Renders the timezone name.
    *
    * @return string
diff --git a/core/tests/Drupal/Tests/Component/Datetime/DateTimePlusTest.php b/core/tests/Drupal/Tests/Component/Datetime/DateTimePlusTest.php
old mode 100644
new mode 100755
index b8be130c30..a047cd4b61
--- a/core/tests/Drupal/Tests/Component/Datetime/DateTimePlusTest.php
+++ b/core/tests/Drupal/Tests/Component/Datetime/DateTimePlusTest.php
@@ -666,4 +666,101 @@ public function providerTestInvalidDateDiff() {
     );
   }
 
+  /**
+   * Tests that DateTimePlus objects can be encoded as JSON.
+   */
+  public function testIsSerializable() {
+    // Create a DateTimePlus, and go through a encode/decode round-trip.
+    $date = DateTimePlus::createFromTimestamp(1400000000);
+    $decoded = json_decode(json_encode($date), TRUE);
+
+    // Make sure the decoded value isn't empty.
+    $decoded = array_filter($decoded);
+    $this->assertFalse(empty($decoded));
+  }
+
+  /**
+   * Tests the DateTimePlus JSON encoding format.
+   *
+   * @param \Drupal\Component\Datetime\DateTimePlus $date
+   *   The test date.
+   * @param object $expected
+   *   The expected value when $date undergoes a JSON encode/decode.
+   *
+   * @dataProvider providerTestSerialization
+   */
+  public function testSerialization($date, $expected) {
+    // Perform an encode/decode round trip so we can compare simple objects,
+    // rather than precise strings.
+    $actual = json_decode(json_encode($date), TRUE);
+    $this->assertEquals($expected, $actual);
+  }
+
+  /**
+   * Provider function for testIsSerializable.
+   *
+   * @return array[]
+   *   An array of arrays, where each are the input values for
+   *   testIsSerializable.
+   */
+  function providerTestSerialization() {
+    return [
+      [
+        DateTimePlus::createFromTimestamp(1400000000),
+        [
+          'datetime' => [
+            'date' => '2014-05-14 02:53:20.000000',
+            'timezone_type' => 3,
+            'timezone' => 'Australia/Sydney',
+          ],
+          'langcode' => NULL,
+        ],
+      ],
+      [
+        DateTimePlus::createFromTimestamp(1482876655),
+        [
+          'datetime' => [
+            'date' => '2016-12-28 09:10:55.000000',
+            'timezone_type' => 3,
+            'timezone' => 'Australia/Sydney',
+          ],
+          'langcode' => NULL,
+        ],
+      ],
+      [
+        DateTimePlus::createFromTimestamp(1300000000,'UTC'),
+        [
+          'datetime' => [
+            'date' => '2011-03-13 07:06:40.000000',
+            'timezone_type' => 3,
+            'timezone' => 'UTC',
+          ],
+          'langcode' => NULL,
+        ],
+      ],
+      [
+        DateTimePlus::createFromTimestamp(139000000,'Europe/Berlin',array('langcode'=> 'EN')),
+        [
+          'datetime' => [
+            'date' => '1974-05-28 20:06:40.000000',
+            'timezone_type' => 3,
+            'timezone' => 'Europe/Berlin',
+          ],
+          'langcode' => 'EN',
+        ],
+      ],
+      [
+        DateTimePlus::createFromTimestamp(1300000000,'UTC','langcode'=>'EN'),
+        [
+          'datetime' => [
+            'date' => '2011-03-13 07:06:40.000000',
+            'timezone_type' => 3,
+            'timezone' => 'UTC',
+          ],
+          'langcode' => 'EN',
+        ],
+      ],
+    ];
+  }
+
 }
