diff --git a/core/modules/system/lib/Drupal/system/Controller/TimezoneController.php b/core/modules/system/lib/Drupal/system/Controller/TimezoneController.php
new file mode 100644
index 0000000..e58a28c
--- /dev/null
+++ b/core/modules/system/lib/Drupal/system/Controller/TimezoneController.php
@@ -0,0 +1,29 @@
+<?php
+
+/**
+ * @file
+ * Contains \Drupal\system\TimezoneController.
+ */
+
+namespace Drupal\system\Controller;
+
+use Symfony\Component\HttpFoundation\JsonResponse;
+
+/**
+ * Provides a callback for finding out a timezone name.
+ */
+class TimezoneController {
+
+  /**
+   * Retrieve a JSON object containing a time zone name given a timezone abbreviation.
+   *
+   */
+  public function getTimezone($abbreviation = '', $offset = -1, $is_daylight_saving_time = NULL) {
+    // An abbreviation of "0" passed in the callback arguments should be
+    // interpreted as the empty string.
+    $abbreviation = $abbreviation ? $abbreviation : '';
+    $timezone = timezone_name_from_abbr($abbreviation, intval($offset), $is_daylight_saving_time);
+    return new JsonResponse($timezone);
+  }
+
+}
diff --git a/core/modules/system/system.module b/core/modules/system/system.module
index 6190d04..2dc6d4c 100644
--- a/core/modules/system/system.module
+++ b/core/modules/system/system.module
@@ -640,13 +640,6 @@ function system_menu() {
     'file path' => 'core/includes',
     'file' => 'form.inc',
   );
-  $items['system/timezone'] = array(
-    'title' => 'Time zone',
-    'page callback' => 'system_timezone',
-    'access callback' => TRUE,
-    'type' => MENU_CALLBACK,
-    'file' => 'system.admin.inc',
-  );
   $items['admin'] = array(
     'title' => 'Administration',
     'access arguments' => array('access administration pages'),
@@ -3517,17 +3510,6 @@ function system_time_zones($blank = NULL) {
 }
 
 /**
- * Menu callback; Retrieve a JSON object containing a suggested time zone name.
- */
-function system_timezone($abbreviation = '', $offset = -1, $is_daylight_saving_time = NULL) {
-  // An abbreviation of "0" passed in the callback arguments should be
-  // interpreted as the empty string.
-  $abbreviation = $abbreviation ? $abbreviation : '';
-  $timezone = timezone_name_from_abbr($abbreviation, intval($offset), $is_daylight_saving_time);
-  return new JsonResponse($timezone);
-}
-
-/**
  * Returns HTML for the Powered by Drupal text.
  *
  * @ingroup themeable
diff --git a/core/modules/system/system.routing.yml b/core/modules/system/system.routing.yml
index 0ba8674..b938723 100644
--- a/core/modules/system/system.routing.yml
+++ b/core/modules/system/system.routing.yml
@@ -143,3 +143,10 @@ system_admin_index:
     _content: 'Drupal\system\Controller\AdminController::index'
   requirements:
     _permission: 'access administration pages'
+
+system_timezone:
+  pattern: '/system/timezone'
+  defaults:
+    _controller: '\Drupal\system\Controller\TimezoneController::getTimezone'
+  requirements:
+    _access: 'TRUE'
\ No newline at end of file
