diff --git a/scheduler.cron.inc b/scheduler.cron.inc
index 570bbdb..f66d5d3 100644
--- a/scheduler.cron.inc
+++ b/scheduler.cron.inc
@@ -18,6 +18,7 @@ use Drupal\node\Entity\Node;
  *   TRUE if any node has been published, FALSE otherwise.
  */
 function _scheduler_publish() {
+  $date_formatter = \Drupal::service('date.formatter');
   $result = FALSE;
 
   // If the time now is greater than the time to publish a node, publish it.
@@ -58,8 +59,8 @@ function _scheduler_publish() {
       $node->setNewRevision();
       // Use a core date format to guarantee a time is included.
       $node->revision_log = t('Node published by Scheduler on @now. Previous creation date was @date.', array(
-        '@now' => format_date(REQUEST_TIME, 'short'),
-        '@date' => format_date($old_creation_date, 'short'),
+        '@now' => $date_formatter->format(REQUEST_TIME, 'short'),
+        '@date' => $date_formatter->format($old_creation_date, 'short'),
       ));
     }
     // Unset publish_on so the node will not get rescheduled by subsequent calls
@@ -99,6 +100,7 @@ function _scheduler_publish() {
  *   TRUE is any node has been unpublished, FALSE otherwise.
  */
 function _scheduler_unpublish() {
+  $date_formatter = \Drupal::service('date.formatter');
   $result = FALSE;
 
   // If the time is greater than the time to unpublish a node, unpublish it.
@@ -144,8 +146,8 @@ function _scheduler_unpublish() {
       $node->setNewRevision();
       // Use a core date format to guarantee a time is included.
       $node->revision_log = t('Node unpublished by Scheduler on @now. Previous change date was @date.', array(
-        '@now' => format_date(REQUEST_TIME, 'short'),
-        '@date' => format_date($old_change_date, 'short'),
+        '@now' => $date_formatter->format(REQUEST_TIME, 'short'),
+        '@date' => $date_formatter->format($old_change_date, 'short'),
       ));
     }
     // Unset unpublish_on so the node will not get rescheduled by subsequent
diff --git a/scheduler.edit.inc b/scheduler.edit.inc
index f5342b1..4091a6c 100644
--- a/scheduler.edit.inc
+++ b/scheduler.edit.inc
@@ -17,6 +17,7 @@ use Drupal\Core\Form\FormStateInterface;
  * @see scheduler_form_alter()
  */
 function _scheduler_form_alter(array &$form, FormStateInterface $form_state) {
+  $date_formatter = \Drupal::service('date.formatter');
   /** @var \Drupal\node\NodeTypeInterface $type */
   $type = $form_state->getFormObject()->getEntity()->type->entity;
   $publishing_enabled = $type->getThirdPartySetting('scheduler', 'publish_enable', FALSE);
@@ -66,13 +67,14 @@ function _scheduler_form_alter(array &$form, FormStateInterface $form_state) {
   $descriptions = array();
   if ($date_only_allowed && ($date_only_format != $date_format)) {
     $descriptions['format'] = t('Format: %date_only_format or %standard_format.', array(
-      '%date_only_format' => format_date(time(), 'custom', $date_only_format),
-      '%standard_format' => format_date(time(), 'custom', $date_format),
+      '%date_only_format' => $date_formatter->format(time(), 'custom', $date_only_format),
+      $date_formatter->format(time(), 'custom', $date_only_format),
+      '%standard_format' => $date_formatter->format(time(), 'custom', $date_format),
     ));
   }
   else {
     $descriptions['format'] = t('Format: %standard_format.', array(
-      '%standard_format' => format_date(time(), 'custom', $date_format),
+      '%standard_format' => $date_formatter->format(time(), 'custom', $date_format),
     ));
   }
   // Show the default time so users know what they will get if they do not
@@ -80,7 +82,7 @@ function _scheduler_form_alter(array &$form, FormStateInterface $form_state) {
   if ($date_only_allowed) {
     $default_time = strtotime(\Drupal::config('scheduler.settings')->get('default_time'));
     $descriptions['default'] = t('The default time is @default_time.', array(
-      '@default_time' => format_date($default_time, 'custom', $time_only_format ? $time_only_format : SCHEDULER_TIME_ONLY_FORMAT),
+      '@default_time' => $date_formatter->format($default_time, 'custom', $time_only_format ? $time_only_format : SCHEDULER_TIME_ONLY_FORMAT),
     ));
   }
 
diff --git a/scheduler.module b/scheduler.module
index 03fb2a4..208f778 100644
--- a/scheduler.module
+++ b/scheduler.module
@@ -336,11 +336,12 @@ function scheduler_node_validate($node, array $form, FormStateInterface $form_st
   // already converted. This is needed because Drupal 6 removed 'submit' and
   // added 'presave' and all this happens at different times.
   $date_format = \Drupal::config('scheduler.settings')->get('date_format');
+  $date_formatter = \Drupal::service('date.formatter');
 
   if (!empty($node->publish_on->value) && !is_numeric($node->publish_on->value)) {
     $publishtime = $node->publish_on->value;
     if ($publishtime === FALSE) {
-      $form_state->setErrorByName('publish_on', t("The 'publish on' value does not match the expected format of %time", array('%time' => format_date(REQUEST_TIME, 'custom', $date_format))));
+      $form_state->setErrorByName('publish_on', t("The 'publish on' value does not match the expected format of %time", array('%time' => $date_formatter->format(REQUEST_TIME, 'custom', $date_format))));
     }
     elseif ($publishtime && variable_get('scheduler_publish_past_date_' . $node->getType(), 'error') == 'error' && $publishtime < REQUEST_TIME) {
       $form_state->setErrorByName('publish_on', t("The 'publish on' date must be in the future"));
@@ -350,7 +351,7 @@ function scheduler_node_validate($node, array $form, FormStateInterface $form_st
   if (!empty($node->unpublish_on->value) && !is_numeric($node->unpublish_on->value)) {
     $unpublishtime = $node->unpublish_on->value;
     if ($unpublishtime === FALSE) {
-      $form_state->setErrorByName('unpublish_on', t("The 'unpublish on' value does not match the expected format of %time", array('%time' => format_date(REQUEST_TIME, 'custom', $date_format))));
+      $form_state->setErrorByName('unpublish_on', t("The 'unpublish on' value does not match the expected format of %time", array('%time' => $date_formatter->format(REQUEST_TIME, 'custom', $date_format))));
     }
     elseif ($unpublishtime && $unpublishtime < REQUEST_TIME) {
       $form_state->setErrorByName('unpublish_on', t("The 'unpublish on' date must be in the future"));
@@ -372,6 +373,7 @@ function scheduler_node_validate($node, array $form, FormStateInterface $form_st
  * Implements hook_ENTITY_TYPE_presave() for node entities.
  */
 function scheduler_node_presave(EntityInterface $node) {
+  $date_formatter = \Drupal::service('date.formatter');
   if ($node->publish_on->value > 0) {
     // Check that other modules allow the action on this node.
     $publication_allowed = _scheduler_allow($node, 'publish');
@@ -399,7 +401,7 @@ function scheduler_node_presave(EntityInterface $node) {
       // message themselves explaining why publication is denied.
       if ($publication_allowed) {
         $date_format = \Drupal::config('scheduler.settings')->get('date_format');
-        drupal_set_message(t('This post is unpublished and will be published @publish_time.', array('@publish_time' => format_date($node->publish_on->value, 'custom', $date_format))), 'status', FALSE);
+        drupal_set_message(t('This post is unpublished and will be published @publish_time.', array('@publish_time' => $date_formatter->format($node->publish_on->value, 'custom', $date_format))), 'status', FALSE);
       }
     }
   }
@@ -562,11 +564,12 @@ function scheduler_preprocess_node(&$variables) {
   /* @var $node \Drupal\node\NodeInterface */
   $node = $variables['node'];
   $date_format = \Drupal::config('scheduler.settings')->get('date_format');
+  $date_formatter = \Drupal::service('date.formatter');
   if (!empty($node->publish_on->value) && $node->publish_on->value && is_numeric($node->publish_on->value)) {
-    $variables['publish_on'] = format_date($node->publish_on->value, 'custom', $date_format);
+    $variables['publish_on'] = $date_formatter->format($node->publish_on->value, 'custom', $date_format);
   }
   if (!empty($node->unpublish_on->value) && $node->unpublish_on->value && is_numeric($node->unpublish_on->value)) {
-    $variables['unpublish_on'] = format_date($node->unpublish_on->value, 'custom', $date_format);
+    $variables['unpublish_on'] = $date_formatter->format($node->unpublish_on->value, 'custom', $date_format);
   }
 }
 
diff --git a/scheduler.test b/scheduler.test
index 87f601b..46ac21a 100644
--- a/scheduler.test
+++ b/scheduler.test
@@ -160,6 +160,9 @@ abstract class SchedulerTestBase extends WebTestBase {
  */
 class SchedulerFunctionalTest extends SchedulerTestBase {
 
+  /** @var  $date_formatter \Drupal\Core\Datetime\DateFormatter */
+  protected $date_formatter;
+
   /**
    * {@inheritdoc}
    */
@@ -177,6 +180,9 @@ class SchedulerFunctionalTest extends SchedulerTestBase {
   public function setUp() {
     parent::setUp('scheduler');
 
+    // Setup the date formatter.
+    $this->date_formatter = \Drupal::config('scheduler.settings')->get('date_format');
+
     // Create a 'Basic Page' content type.
     $this->drupalCreateContentType(array('type' => 'page', 'name' => t('Basic page')));
 
@@ -204,7 +210,7 @@ class SchedulerFunctionalTest extends SchedulerTestBase {
     // Create node values. Set time to one hour in the future.
     $edit = array(
       'title' => 'title',
-      'publish_on' => format_date(time() + 3600, 'custom', 'Y-m-d H:i:s'),
+      'publish_on' => $this->date_formatter->format(time() + 3600, 'custom', 'Y-m-d H:i:s'),
       'status' => 1,
       'promote' => 1,
     );
@@ -230,7 +236,7 @@ class SchedulerFunctionalTest extends SchedulerTestBase {
     // enters a publication date that is in the past.
     $edit = array(
       'title' => $this->randomName(),
-      'publish_on' => format_date(strtotime('-1 day'), 'custom', 'Y-m-d H:i:s'),
+      'publish_on' => $this->date_formatter->format(strtotime('-1 day'), 'custom', 'Y-m-d H:i:s'),
     );
     $this->drupalPost('node/' . $node->id() . '/edit', $edit, t('Save'));
     $this->assertRaw(t("The 'publish on' date must be in the future"), 'An error message is shown when the publication date is in the past and the "error" behavior is chosen.');
@@ -258,7 +264,7 @@ class SchedulerFunctionalTest extends SchedulerTestBase {
     $node_storage->resetCache(array($node->id()));
     $node = $node_storage->load($node->id());
     $this->assertFalse($node->isPublished(), 'The node has been unpublished when the publication date is in the past and the "schedule" behavior is chosen.');
-    $this->assertEqual(format_date($node->publish_on->value, 'custom', 'Y-m-d H:i:s'), $edit['publish_on'], 'The node is scheduled for the required date');
+    $this->assertEqual($this->date_formatter->format($node->publish_on->value, 'custom', 'Y-m-d H:i:s'), $edit['publish_on'], 'The node is scheduled for the required date');
 
     // Simulate a cron run and check that the node is published.
     scheduler_cron();
@@ -295,8 +301,8 @@ class SchedulerFunctionalTest extends SchedulerTestBase {
     $node = $this->schedule($node);
     $this->assertRevisionCount($node->id(), 2, 'A new revision was created when revisioning is enabled.');
     $expected_message = t('Node published by Scheduler on @now. Previous creation date was @date.', array(
-      '@now' => format_date(REQUEST_TIME, 'short'),
-      '@date' => format_date($created, 'short'),
+      '@now' => $this->date_formatter->format(REQUEST_TIME, 'short'),
+      '@date' => $this->date_formatter->format($created, 'short'),
     ));
     $this->assertRevisionLogMessage($node->id(), $expected_message, 'The correct message was found in the node revision log after scheduled publishing.');
 
@@ -304,8 +310,8 @@ class SchedulerFunctionalTest extends SchedulerTestBase {
     $node = $this->schedule($node, 'unpublish');
     $this->assertRevisionCount($node->id(), 3, 'A new revision was created when a node was unpublished with revisioning enabled.');
     $expected_message = t('Node unpublished by Scheduler on @now. Previous change date was @date.', array(
-      '@now' => format_date(REQUEST_TIME, 'short'),
-      '@date' => format_date(REQUEST_TIME, 'short'),
+      '@now' => $this->date_formatter->format(REQUEST_TIME, 'short'),
+      '@date' => $this->date_formatter->format(REQUEST_TIME, 'short'),
     ));
     $this->assertRevisionLogMessage($node->id(), $expected_message, 'The correct message was found in the node revision log after scheduled unpublishing.');
   }
@@ -535,7 +541,7 @@ class SchedulerFunctionalTest extends SchedulerTestBase {
       'type' => 'page',
       'status' => FALSE,
       'title' => $this->randomName(),
-    ));
+    );
     $node = $this->drupalCreateNode($settings);
 
     // Set unpublishing to be required.
diff --git a/scheduler.tokens.inc b/scheduler.tokens.inc
index 8ec23bb..f5bc756 100644
--- a/scheduler.tokens.inc
+++ b/scheduler.tokens.inc
@@ -29,6 +29,7 @@ function scheduler_token_info() {
  * Implements hook_tokens().
  */
 function scheduler_tokens($type, $tokens, array $data = array(), array $options = array()) {
+  $date_formatter = \Drupal::config('scheduler.settings')->get('date_format');
   $language_code = isset($options['language']) ? $options['language']->language : NULL;
   $replacements = array();
 
@@ -39,12 +40,12 @@ function scheduler_tokens($type, $tokens, array $data = array(), array $options
       switch ($name) {
         case 'scheduler-publish':
           if (isset($node->publish_on->value)) {
-            $replacements[$original] = format_date($node->publish_on->value, 'medium', '', NULL, $language_code);
+            $replacements[$original] = $date_formatter->format($node->publish_on->value, 'medium', '', NULL, $language_code);
           }
           break;
         case 'scheduler-unpublish':
           if (isset($node->unpublish_on->value)) {
-            $replacements[$original] = format_date($node->unpublish_on->value, 'medium', '', NULL, $language_code);
+            $replacements[$original] = $date_formatter->format($node->unpublish_on->value, 'medium', '', NULL, $language_code);
           }
           break;
       }
diff --git a/src/Form/SchedulerAdminForm.php b/src/Form/SchedulerAdminForm.php
index ce93c31..261197d 100644
--- a/src/Form/SchedulerAdminForm.php
+++ b/src/Form/SchedulerAdminForm.php
@@ -35,7 +35,8 @@ class SchedulerAdminForm extends ConfigFormBase {
    * {@inheritdoc}
    */
   public function buildForm(array $form, FormStateInterface $form_state) {
-    $now = t('Example: %date', ['%date' => format_date(REQUEST_TIME, 'custom', \Drupal::config('scheduler.settings')->get('date_format'))]);
+    $date_formatter = \Drupal::config('scheduler.settings')->get('date_format');
+    $now = t('Example: %date', ['%date' => $date_formatter->format(REQUEST_TIME, 'custom', \Drupal::config('scheduler.settings')->get('date_format'))]);
     $url = Url::fromUri('http://php.net/manual/en/function.date.php');
     $form['date_format'] = [
       '#type' => 'textfield',
@@ -88,6 +89,7 @@ class SchedulerAdminForm extends ConfigFormBase {
    * {@inheritdoc}
    */
   public function validateForm(array &$form, FormStateInterface $form_state) {
+    $date_formatter = \Drupal::config('scheduler.settings')->get('date_format');
     // Replace all contiguous whitespaces (including tabs and newlines) with a
     // single plain space.
     $form_state->setValue(['date_format'], trim(preg_replace('/\s+/', ' ', $form_state->getValue(['date_format']))));
@@ -115,7 +117,7 @@ class SchedulerAdminForm extends ConfigFormBase {
       else {
         // Insert any possibly omitted leading zeroes.
         $unix_time = mktime($default_time['hour'], $default_time['minute'], $default_time['second']);
-        $form_state->setValue(['default_time'], format_date($unix_time, 'custom', 'H:i:s'));
+        $form_state->setValue(['default_time'], $date_formatter->format($unix_time, 'custom', 'H:i:s'));
       }
     }
 
