diff --git a/core/core.services.yml b/core/core.services.yml
index 1ee07fe..4e39190 100644
--- a/core/core.services.yml
+++ b/core/core.services.yml
@@ -338,6 +338,9 @@ services:
     class: Drupal\Core\Database\Connection
     factory: Drupal\Core\Database\Database::getConnection
     arguments: [default]
+  datetime.time:
+    class: Drupal\Component\Datetime\Time
+    arguments: ['@request_stack']
   file_system:
     class: Drupal\Core\File\FileSystem
     arguments: ['@stream_wrapper_manager', '@settings', '@logger.channel.file']
diff --git a/core/includes/bootstrap.inc b/core/includes/bootstrap.inc
index ec12097..d551672 100644
--- a/core/includes/bootstrap.inc
+++ b/core/includes/bootstrap.inc
@@ -82,6 +82,9 @@
  *
  * @see http://php.net/manual/reserved.variables.server.php
  * @see http://php.net/manual/function.time.php
+ *
+ * @deprecated in Drupal 8.2.0, will be removed before Drupal 9.0.0.
+ *   Use \Drupal::time()->getRequestTime();
  */
 define('REQUEST_TIME', (int) $_SERVER['REQUEST_TIME']);
 
diff --git a/core/lib/Drupal.php b/core/lib/Drupal.php
index 5d1588d..5451990 100644
--- a/core/lib/Drupal.php
+++ b/core/lib/Drupal.php
@@ -721,4 +721,14 @@ public static function entityDefinitionUpdateManager() {
     return static::getContainer()->get('entity.definition_update_manager');
   }
 
+  /**
+   * Returns the time service.
+   *
+   * @return \Drupal\Component\Datetime\TimeInterface
+   *   The time service.
+   */
+  public static function time() {
+    return static::getContainer()->get('datetime.time');
+  }
+
 }
diff --git a/core/lib/Drupal/Component/Datetime/Time.php b/core/lib/Drupal/Component/Datetime/Time.php
new file mode 100644
index 0000000..d66d28b
--- /dev/null
+++ b/core/lib/Drupal/Component/Datetime/Time.php
@@ -0,0 +1,57 @@
+<?php
+
+namespace Drupal\Component\Datetime;
+
+use Symfony\Component\HttpFoundation\RequestStack;
+
+/**
+ * Provides a class which provides an abstraction for obtaining time.
+ */
+class Time implements TimeInterface {
+
+  /**
+   * The request stack.
+   *
+   * @var \Symfony\Component\HttpFoundation\RequestStack
+   */
+  protected $requestStack;
+
+  /**
+   * Constructs a Time object.
+   *
+   * @param \Symfony\Component\HttpFoundation\RequestStack $request_stack
+   *   The request stack.
+   */
+  public function __construct(RequestStack $request_stack) {
+    $this->requestStack = $request_stack;
+  }
+
+  /**
+   * @{inheritdoc}
+   */
+  public function getRequestTime() {
+    return $this->requestStack->getCurrentRequest()->server->get('REQUEST_TIME');
+  }
+
+  /**
+   * @{inheritdoc}
+   */
+  public function getRequestMicroTime() {
+    return $this->requestStack->getCurrentRequest()->server->get('REQUEST_TIME_FLOAT');
+  }
+
+  /**
+   * @{inheritdoc}
+   */
+  public function getCurrentTime() {
+    return time();
+  }
+
+  /**
+   * @{inheritdoc}
+   */
+  public function getCurrentMicroTime() {
+    return microtime(TRUE);
+  }
+
+}
diff --git a/core/lib/Drupal/Component/Datetime/TimeInterface.php b/core/lib/Drupal/Component/Datetime/TimeInterface.php
new file mode 100644
index 0000000..4464b59
--- /dev/null
+++ b/core/lib/Drupal/Component/Datetime/TimeInterface.php
@@ -0,0 +1,149 @@
+<?php
+
+namespace Drupal\Component\Datetime;
+
+/**
+ * Defines an interface for providing an abstraction for obtaining time.
+ */
+interface TimeInterface {
+
+  /**
+   * Returns the timestamp for the current request.
+   *
+   * In general, this method should be used to obtain the current system time
+   * at the start of the request. It will be the same value for the life of
+   * the request (even for long execution times).
+   *
+   * This method can replace instances of
+   * @code
+   * $request_time = $_SERVER['REQUEST_TIME'];
+   * $request_time = REQUEST_TIME;
+   * $request_time = $requestStack->getCurrentRequest()->server->get('REQUEST_TIME');
+   * $request_time = $request->server->get('REQUEST_TIME');
+   * @endcode
+   * and most instances of
+   * @code
+   * $time = time();
+   * @endcode
+   * with
+   * @code
+   * $request_time = \Drupal::time()->getRequestTime();
+   * @endcode
+   * or the equivalent using the injected service.
+   *
+   * Using the time service, rather than other methods, is especially
+   * important to create tests that run that require predictable timestamps.
+   *
+   * @return int
+   *   A Unix timestamp.
+   *
+   * @see \Drupal\Component\Datetime::getRequestMicroTime()
+   * @see \Drupal\Component\Datetime::getCurrentTime()
+   * @see \Drupal\Component\Datetime::getCurrentMicroTime()
+   */
+  public function getRequestTime();
+
+  /**
+   * Returns the timestamp for the current request with microsecond precision.
+   *
+   * This method should be used to obtain the current system time, with
+   * microsecond precision, at the start of the request. It will be the same
+   * value for the life of the request (even for long execution times).
+   *
+   * This method can replace instances of
+   * @code
+   * $request_time_float = $_SERVER['REQUEST_TIME_FLOAT'];
+   * $request_time_float = $requestStack->getCurrentRequest()->server->get('REQUEST_TIME_FLOAT');
+   * $request_time_float = $request->server->get('REQUEST_TIME_FLOAT');
+   * @endcode
+   * and many instances of
+   * @code
+   * $microtime = microtime();
+   * $microtime = microtime(TRUE);
+   * @endcode
+   * with
+   * @code
+   * $request_time = \Drupal::time()->getRequestMicroTime();
+   * @endcode
+   * or the equivalent using the injected service.
+   *
+   * Using the time service, rather than other methods, is especially
+   * important to create tests that run that require predictable timestamps.
+   *
+   * @return float
+   *  A Unix timestamp with a factional portion.
+   *
+   * @see \Drupal\Component\Datetime::getRequestTime()
+   * @see \Drupal\Component\Datetime::getCurrentTime()
+   * @see \Drupal\Component\Datetime::getCurrentMicroTime()
+   */
+  public function getRequestMicroTime();
+
+  /**
+   * Returns the current system time as an integer.
+   *
+   * This method should be used to obtain the current system time, at the time
+   * the method was called.
+   *
+   * This method can replace many instances of
+   * @code
+   * $time = time();
+   * @endcode
+   * with
+   * @code
+   * $request_time = \Drupal::time()->getCurrentTime();
+   * @endcode
+   * or the equivalent using the injected service.
+   *
+   * This method should only be used when the current system time is actually
+   * needed, such as with timers or time interval calculations. If only the
+   * time at the start of the request is needed,
+   * use TimeInterface::getRequestTime().
+   *
+   * Using the time service, rather than other methods, is especially
+   * important to create tests that run that require predictable timestamps.
+   *
+   * @return int
+   *   A Unix timestamp.
+   *
+   * @see \Drupal\Component\Datetime::getRequestTime()
+   * @see \Drupal\Component\Datetime::getRequestMicroTime()
+   * @see \Drupal\Component\Datetime::getCurrentMicroTime()
+   */
+  public function getCurrentTime();
+
+  /**
+   * Returns the current system time with microsecond precision.
+   *
+   * This method should be used to obtain the current system time, with
+   * microsecond precision, at the time the method was called.
+   *
+   * This method can replace many instances of
+   * @code
+   * $microtime = microtime();
+   * $microtime = microtime(TRUE);
+   * @endcode
+   * with
+   * @code
+   * $request_time = \Drupal::time()->getCurrentMicroTime();
+   * @endcode
+   * or the equivalent using the injected service.
+   *
+   * This method should only be used when the current system time is actually
+   * needed, such as with timers or time interval calculations. If only the
+   * time at the start of the request and microsecond precision is needed,
+   * use TimeInterface::getRequestTime().
+   *
+   * Using the time service, rather than other methods, is especially
+   * important to create tests that run that require predictable timestamps.
+   *
+   * @return float
+   *   A Unix timestamp with a factional portion.
+   *
+   * @see \Drupal\Component\Datetime::getRequestTime()
+   * @see \Drupal\Component\Datetime::getRequestMicroTime()
+   * @see \Drupal\Component\Datetime::getCurrentTime()
+   */
+  public function getCurrentMicroTime();
+
+}
diff --git a/core/tests/Drupal/Tests/Component/Datetime/TimeTest.php b/core/tests/Drupal/Tests/Component/Datetime/TimeTest.php
new file mode 100644
index 0000000..be97b87
--- /dev/null
+++ b/core/tests/Drupal/Tests/Component/Datetime/TimeTest.php
@@ -0,0 +1,135 @@
+<?php
+
+/**
+ * @file
+ * Provides test coverage for the \Drupal\Component\Datetime\Time service.
+ *
+ * This file contains the primary unit test, TimeTest, and also contains a
+ * shadow namespace for overriding PHP global functions within the test. PHP
+ * scope resolution will look for a symbol in the current namespace before
+ * checking the global namespace. So, the shadow namespace gets used to mock
+ * global functions used by the class under test.
+ *
+ * @see https://www.schmengler-se.de/en/2011/03/php-mocking-built-in-functions-like-time-in-unit-tests/
+ */
+
+/**
+ * Set up the real namespace for the test.
+ */
+namespace Drupal\Tests\Component\Datetime;
+
+use Drupal\Component\Datetime\Time;
+use Drupal\Tests\UnitTestCase;
+use Symfony\Component\HttpFoundation\Request;
+
+/**
+ * @coversDefaultClass \Drupal\Component\Datetime\Time
+ * @group Datetime
+ */
+class TimeTest extends UnitTestCase {
+
+  /**
+   * The mocked request stack.
+   *
+   * @var \Symfony\Component\HttpFoundation\RequestStack|\PHPUnit_Framework_MockObject_MockObject
+   */
+  protected $requestStack;
+
+  /**
+   * The mocked time class.
+   *
+   * @var \Drupal\Component\Datetime\Time
+   */
+  protected $time;
+
+  protected function setUp() {
+    parent::setUp();
+
+    $this->requestStack = $this->getMock('Symfony\Component\HttpFoundation\RequestStack');
+
+    $this->time = new Time($this->requestStack);
+  }
+
+
+  /**
+   * Tests the getRequestTime method.
+   *
+   * @covers ::getRequestTime
+   */
+  public function testGetRequestTime() {
+    $expected = 12345678;
+
+    $request = Request::createFromGlobals();
+    $request->server->set('REQUEST_TIME', $expected);
+
+    // Mocks a the request stack getting the current request.
+    $this->requestStack->expects($this->any())
+      ->method('getCurrentRequest')
+      ->willReturn($request);
+
+    $this->assertEquals($expected, $this->time->getRequestTime());
+  }
+
+  /**
+   * Tests the getRequestMicroTime method.
+   *
+   * @covers ::getRequestMicroTime
+   */
+  public function testGetRequestMicroTime() {
+    $expected = 1234567.89;
+
+    $request = Request::createFromGlobals();
+    $request->server->set('REQUEST_TIME_FLOAT', $expected);
+
+    // Mocks a the request stack getting the current request.
+    $this->requestStack->expects($this->any())
+      ->method('getCurrentRequest')
+      ->willReturn($request);
+
+    $this->assertEquals($expected, $this->time->getRequestMicroTime());
+  }
+
+  /**
+   * Tests the getCurrentTime method.
+   *
+   * @covers ::getCurrentTime
+   */
+  public function testGetCurrentTime() {
+    $expected = 12345678;
+    $this->assertEquals($expected, $this->time->getCurrentTime());
+  }
+
+  /**
+   * Tests the getCurrentMicroTime method.
+   *
+   * @covers ::getCurrentMicroTime
+   */
+  public function testGetCurrentMicroTime() {
+    $expected = 1234567.89;
+    $this->assertEquals($expected, $this->time->getCurrentMicroTime());
+  }
+
+}
+
+/**
+ * Set up the shadow namespace so global system calls can be mocked.
+ */
+namespace Drupal\Component\Datetime;
+
+/**
+ * Shadow time() system call.
+ *
+ * @returns int
+ */
+function time() {
+  return 12345678;
+}
+
+/**
+ * Shadow microtime system call.
+ *
+ * @returns float
+ */
+function microtime() {
+  return 1234567.89;
+}
