diff --git a/core/modules/node/lib/Drupal/node/Plugin/views/argument/CreatedDay.php b/core/modules/node/lib/Drupal/node/Plugin/views/argument/CreatedDay.php
index ba037cdd99335f2f0e04e4779f3baee1a016201d..fd7ebe542dcd0432659d679da6f916d111730a84 100644
--- a/core/modules/node/lib/Drupal/node/Plugin/views/argument/CreatedDay.php
+++ b/core/modules/node/lib/Drupal/node/Plugin/views/argument/CreatedDay.php
@@ -22,14 +22,6 @@
  */
 class CreatedDay extends Date {
 
-  /**
-   * Overrides Drupal\views\Plugin\views\argument\Formula::get_formula().
-   */
-  function get_formula() {
-    $this->formula = $this->extractSQL('DAY');
-    return parent::get_formula();
-  }
-
   /**
    * Provide a link to the next level of the view
    */
diff --git a/core/modules/node/lib/Drupal/node/Plugin/views/argument/CreatedFullDate.php b/core/modules/node/lib/Drupal/node/Plugin/views/argument/CreatedFullDate.php
index 1f128c62fec0d0eea58ee9712b9c385df4af3bc8..0b098cff08d98155ede42a80a324dc48d3a1057b 100644
--- a/core/modules/node/lib/Drupal/node/Plugin/views/argument/CreatedFullDate.php
+++ b/core/modules/node/lib/Drupal/node/Plugin/views/argument/CreatedFullDate.php
@@ -22,14 +22,6 @@
  */
 class CreatedFullDate extends Date {
 
-  /**
-   * Overrides Drupal\views\Plugin\views\argument\Formula::get_formula().
-   */
-  function get_formula() {
-    $this->formula = $this->getSQLFormat($this->definition['arg_format']);
-    return parent::get_formula();
-  }
-
   /**
    * Provide a link to the next level of the view
    */
diff --git a/core/modules/node/lib/Drupal/node/Plugin/views/argument/CreatedMonth.php b/core/modules/node/lib/Drupal/node/Plugin/views/argument/CreatedMonth.php
index e85b6fa47a338ca315bd4118875bb60ffc0a8662..a156a7bbb0fbb7b624ef3a0861157963bfcb0645 100644
--- a/core/modules/node/lib/Drupal/node/Plugin/views/argument/CreatedMonth.php
+++ b/core/modules/node/lib/Drupal/node/Plugin/views/argument/CreatedMonth.php
@@ -22,14 +22,6 @@
  */
 class CreatedMonth extends Date {
 
-  /**
-   * Overrides Drupal\views\Plugin\views\argument\Formula::get_formula().
-   */
-  function get_formula() {
-    $this->formula = $this->extractSQL('MONTH');
-    return parent::get_formula();
-  }
-
   /**
    * Provide a link to the next level of the view
    */
diff --git a/core/modules/node/lib/Drupal/node/Plugin/views/argument/CreatedWeek.php b/core/modules/node/lib/Drupal/node/Plugin/views/argument/CreatedWeek.php
index 867d0acb2fc032ff5d1b1898a533eda5aaee2365..e6174b1fdba65124d775c8e1a9379bfdb63604e0 100644
--- a/core/modules/node/lib/Drupal/node/Plugin/views/argument/CreatedWeek.php
+++ b/core/modules/node/lib/Drupal/node/Plugin/views/argument/CreatedWeek.php
@@ -15,20 +15,12 @@
  *
  * @Plugin(
  *   id = "node_created_week",
- *   arg_format = "w",
+ *   arg_format = "W",
  *   module = "node"
  * )
  */
 class CreatedWeek extends Date {
 
-  /**
-   * Overrides Drupal\views\Plugin\views\argument\Formula::get_formula().
-   */
-  function get_formula() {
-    $this->formula = $this->extractSQL('WEEK');
-    return parent::get_formula();
-  }
-
   /**
    * Provide a link to the next level of the view
    */
diff --git a/core/modules/node/lib/Drupal/node/Plugin/views/argument/CreatedYear.php b/core/modules/node/lib/Drupal/node/Plugin/views/argument/CreatedYear.php
index f4a832ca4662f1bfa61be248f55cc7810b4bab74..68bab3018acf6dc1ab61b38afb4a2ba3e0936bd4 100644
--- a/core/modules/node/lib/Drupal/node/Plugin/views/argument/CreatedYear.php
+++ b/core/modules/node/lib/Drupal/node/Plugin/views/argument/CreatedYear.php
@@ -21,12 +21,4 @@
  */
 class CreatedYear extends Date {
 
-  /**
-   * Overrides Drupal\views\Plugin\views\argument\Formula::get_formula().
-   */
-  function get_formula() {
-    $this->formula = $this->extractSQL('YEAR');
-    return parent::get_formula();
-  }
-
 }
diff --git a/core/modules/node/lib/Drupal/node/Plugin/views/argument/CreatedYearMonth.php b/core/modules/node/lib/Drupal/node/Plugin/views/argument/CreatedYearMonth.php
index 598512c10c69a19a6560e814c9bce30195fe2b51..26f268d37ca02dfce2c8f0e3ffee0b588c42789c 100644
--- a/core/modules/node/lib/Drupal/node/Plugin/views/argument/CreatedYearMonth.php
+++ b/core/modules/node/lib/Drupal/node/Plugin/views/argument/CreatedYearMonth.php
@@ -22,14 +22,6 @@
  */
 class CreatedYearMonth extends Date {
 
-  /**
-   * Overrides Drupal\views\Plugin\views\argument\Formula::get_formula().
-   */
-  function get_formula() {
-    $this->formula = $this->getSQLFormat($this->definition['arg_format']);
-    return parent::get_formula();
-  }
-
   /**
    * Provide a link to the next level of the view
    */
diff --git a/core/modules/views/lib/Drupal/views/Plugin/views/HandlerBase.php b/core/modules/views/lib/Drupal/views/Plugin/views/HandlerBase.php
index a0fad3684a7894daff6a3d4aba4431e2d2cca9b3..94b4a3be93fb5fb5873cc22ebe881d6b8fa16f16 100644
--- a/core/modules/views/lib/Drupal/views/Plugin/views/HandlerBase.php
+++ b/core/modules/views/lib/Drupal/views/Plugin/views/HandlerBase.php
@@ -620,74 +620,8 @@ public function broken() { }
    * @return string
    *   An appropriate SQL string for the DB type and field type.
    */
-  public function getSQLFormat($format) {
-    $db_type = Database::getConnection()->databaseType();
-    $field = $this->getSQLDateField();
-    switch ($db_type) {
-      case 'mysql':
-        $replace = array(
-          'Y' => '%Y',
-          'y' => '%y',
-          'M' => '%b',
-          'm' => '%m',
-          'n' => '%c',
-          'F' => '%M',
-          'D' => '%a',
-          'd' => '%d',
-          'l' => '%W',
-          'j' => '%e',
-          'W' => '%v',
-          'H' => '%H',
-          'h' => '%h',
-          'i' => '%i',
-          's' => '%s',
-          'A' => '%p',
-          );
-        $format = strtr($format, $replace);
-        return "DATE_FORMAT($field, '$format')";
-      case 'pgsql':
-        $replace = array(
-          'Y' => 'YYYY',
-          'y' => 'YY',
-          'M' => 'Mon',
-          'm' => 'MM',
-          'n' => 'MM', // no format for Numeric representation of a month, without leading zeros
-          'F' => 'Month',
-          'D' => 'Dy',
-          'd' => 'DD',
-          'l' => 'Day',
-          'j' => 'DD', // no format for Day of the month without leading zeros
-          'W' => 'WW',
-          'H' => 'HH24',
-          'h' => 'HH12',
-          'i' => 'MI',
-          's' => 'SS',
-          'A' => 'AM',
-          );
-        $format = strtr($format, $replace);
-        return "TO_CHAR($field, '$format')";
-      case 'sqlite':
-        $replace = array(
-          'Y' => '%Y', // 4 digit year number
-          'y' => '%Y', // no format for 2 digit year number
-          'M' => '%m', // no format for 3 letter month name
-          'm' => '%m', // month number with leading zeros
-          'n' => '%m', // no format for month number without leading zeros
-          'F' => '%m', // no format for full month name
-          'D' => '%d', // no format for 3 letter day name
-          'd' => '%d', // day of month number with leading zeros
-          'l' => '%d', // no format for full day name
-          'j' => '%d', // no format for day of month number without leading zeros
-          'W' => '%W', // ISO week number
-          'H' => '%H', // 24 hour hour with leading zeros
-          'h' => '%H', // no format for 12 hour hour with leading zeros
-          'i' => '%M', // minutes with leading zeros
-          's' => '%S', // seconds with leading zeros
-          'A' => '', // no format for  AM/PM
-        );
-        $format = strtr($format, $replace);
-        return "strftime('$format', $field, 'unixepoch')";
-    }
+  public function getDateFormat($format) {
+    return $this->query->getDateFormat($this->getDateField(), $format);
   }
 
   /**
@@ -696,61 +630,8 @@ public function getSQLFormat($format) {
    * @return string
    *   An appropriate SQL string for the db type and field type.
    */
-  public function getSQLDateField() {
-    $field = "$this->tableAlias.$this->realField";
-    $db_type = Database::getConnection()->databaseType();
-    $offset = $this->getTimezone();
-    if (isset($offset) && !is_numeric($offset)) {
-      $dtz = new \DateTimeZone($offset);
-      $dt = new \DateTime('now', $dtz);
-      $offset_seconds = $dtz->getOffset($dt);
-    }
-
-    switch ($db_type) {
-      case 'mysql':
-        $field = "DATE_ADD('19700101', INTERVAL $field SECOND)";
-        if (!empty($offset)) {
-          $field = "($field + INTERVAL $offset_seconds SECOND)";
-        }
-        return $field;
-      case 'pgsql':
-        $field = "TO_TIMESTAMP($field)";
-        if (!empty($offset)) {
-          $field = "($field + INTERVAL '$offset_seconds SECONDS')";
-        }
-        return $field;
-      case 'sqlite':
-        if (!empty($offset)) {
-          $field = "($field + '$offset_seconds')";
-        }
-        return $field;
-    }
-  }
-
-  /**
-   * Figure out what timezone we're in; needed for some date manipulations.
-   */
-  public static function getTimezone() {
-    $timezone = drupal_get_user_timezone();
-
-    // set up the database timezone
-    $db_type = Database::getConnection()->databaseType();
-    if (in_array($db_type, array('mysql', 'pgsql'))) {
-      $offset = '+00:00';
-      static $already_set = FALSE;
-      if (!$already_set) {
-        if ($db_type == 'pgsql') {
-          db_query("SET TIME ZONE INTERVAL '$offset' HOUR TO MINUTE");
-        }
-        elseif ($db_type == 'mysql') {
-          db_query("SET @@session.time_zone = '$offset'");
-        }
-
-        $already_set = TRUE;
-      }
-    }
-
-    return $timezone;
+  public function getDateField() {
+    return $this->query->getDateField("$this->tableAlias.$this->realField");
   }
 
   /**
diff --git a/core/modules/views/lib/Drupal/views/Plugin/views/argument/Date.php b/core/modules/views/lib/Drupal/views/Plugin/views/argument/Date.php
index 54d0d73c840710b8d7da2617a870b5e1c7933c22..57638f9bef5dd48c287e27d3841c0b62852ae80f 100644
--- a/core/modules/views/lib/Drupal/views/Plugin/views/argument/Date.php
+++ b/core/modules/views/lib/Drupal/views/Plugin/views/argument/Date.php
@@ -14,27 +14,25 @@
  *
  * Adds an option to set a default argument based on the current date.
  *
- * @param $arg_format
- *   The format string to use on the current time when
- *   creating a default date argument.
- *
  * Definitions terms:
  * - many to one: If true, the "many to one" helper will be used.
  * - invalid input: A string to give to the user for obviously invalid input.
  *                  This is deprecated in favor of argument validators.
+ * - arg_format: The format string to use on the current time when dealing with
+ *     date values.
  *
  * @see Drupal\views\ManyTonOneHelper
  *
  * @ingroup views_argument_handlers
  *
  * @Plugin(
- *   id = "date"
+ *   id = "date",
+ *   arg_format = "Y-m-d"
  * )
  */
 class Date extends Formula {
 
   var $option_name = 'default_argument_date';
-  var $arg_format = 'Y-m-d';
 
   /**
    * Add an option to set the default value to the current date.
@@ -84,62 +82,11 @@ function get_sort_name() {
   }
 
   /**
-   * Creates cross-database SQL date extraction.
-   *
-   * @param string $extract_type
-   *   The type of value to extract from the date, like 'MONTH'.
-   *
-   * @return string
-   *   An appropriate SQL string for the DB type and field type.
+   * Overrides \Drupal\views\Plugin\views\argument\Formula::get_formula().
    */
-  public function extractSQL($extract_type) {
-    $db_type = Database::getConnection()->databaseType();
-    $field = $this->getSQLDateField();
-
-    // Note there is no space after FROM to avoid db_rewrite problems
-    // see http://drupal.org/node/79904.
-    switch ($extract_type) {
-      case 'DATE':
-        return $field;
-      case 'YEAR':
-        return "EXTRACT(YEAR FROM($field))";
-      case 'MONTH':
-        return "EXTRACT(MONTH FROM($field))";
-      case 'DAY':
-        return "EXTRACT(DAY FROM($field))";
-      case 'HOUR':
-        return "EXTRACT(HOUR FROM($field))";
-      case 'MINUTE':
-        return "EXTRACT(MINUTE FROM($field))";
-      case 'SECOND':
-        return "EXTRACT(SECOND FROM($field))";
-      // ISO week number for date
-      case 'WEEK':
-        switch ($db_type) {
-          case 'mysql':
-            // WEEK using arg 3 in mysql should return the same value as postgres
-            // EXTRACT.
-            return "WEEK($field, 3)";
-          case 'pgsql':
-            return "EXTRACT(WEEK FROM($field))";
-        }
-      case 'DOW':
-        switch ($db_type) {
-          case 'mysql':
-            // mysql returns 1 for Sunday through 7 for Saturday php date
-            // functions and postgres use 0 for Sunday and 6 for Saturday.
-            return "INTEGER(DAYOFWEEK($field) - 1)";
-          case 'pgsql':
-            return "EXTRACT(DOW FROM($field))";
-        }
-      case 'DOY':
-        switch ($db_type) {
-          case 'mysql':
-            return "DAYOFYEAR($field)";
-          case 'pgsql':
-            return "EXTRACT(DOY FROM($field))";
-        }
-    }
+  function get_formula() {
+    $this->formula = $this->getDateFormat($this->definition['arg_format']);
+    return parent::get_formula();
   }
 
 }
diff --git a/core/modules/views/lib/Drupal/views/Plugin/views/query/QueryPluginBase.php b/core/modules/views/lib/Drupal/views/Plugin/views/query/QueryPluginBase.php
index d5506896f7c9d5ec916ed2d5bf2645efa1b6e592..e78516d88eff5ca50cb3bb5cd4b4805ebdc3bae5 100644
--- a/core/modules/views/lib/Drupal/views/Plugin/views/query/QueryPluginBase.php
+++ b/core/modules/views/lib/Drupal/views/Plugin/views/query/QueryPluginBase.php
@@ -169,4 +169,43 @@ function set_group_operator($type = 'AND') {
    */
   function load_entities(&$results) {}
 
+  /**
+   * Returns a Unix timestamp to database native timestamp expression.
+   *
+   * @param string $field
+   *   The query field that will be used in the expression.
+   *
+   * @return string
+   *   An expression representing a timestamp with time zone.
+   */
+  public function getDateField($field) {
+    return $field;
+  }
+
+  /**
+   * Set the database to the current user timezone,
+   *
+   * @return string
+   *   The current timezone as returned by drupal_get_user_timezone().
+   */
+  public function setupTimezone() {
+    return drupal_get_user_timezone();
+  }
+
+  /**
+   * Creates cross-database date formatting.
+   *
+   * @param string $field
+   *   An appropriate query expression pointing to the date field.
+   * @param string $format
+   *   A format string for the result, like 'Y-m-d H:i:s'.
+   *
+   * @return string
+   *   A string representing the field formatted as a date in the format
+   *   specified by $format.
+   */
+  public function getDateFormat($field, $format) {
+    return $field;
+  }
+
 }
diff --git a/core/modules/views/lib/Drupal/views/Plugin/views/query/Sql.php b/core/modules/views/lib/Drupal/views/Plugin/views/query/Sql.php
index 2e8a5c791c4e860f7ca2cc3ec41a6f812c7c5046..8f50431afa655a91fd7450f81b6b2c8b88fd2d8f 100644
--- a/core/modules/views/lib/Drupal/views/Plugin/views/query/Sql.php
+++ b/core/modules/views/lib/Drupal/views/Plugin/views/query/Sql.php
@@ -1739,4 +1739,149 @@ function aggregation_method_distinct($group_type, $field) {
     return strtoupper($group_type) . '(DISTINCT ' . $field . ')';
   }
 
+  /**
+   * Overrides \Drupal\views\Plugin\views\query\QueryPluginBase::getDateField().
+   */
+  public function getDateField($field) {
+    $db_type = Database::getConnection()->databaseType();
+    $offset = $this->setupTimezone();
+    if (isset($offset) && !is_numeric($offset)) {
+      $dtz = new \DateTimeZone($offset);
+      $dt = new \DateTime('now', $dtz);
+      $offset_seconds = $dtz->getOffset($dt);
+    }
+
+    switch ($db_type) {
+      case 'mysql':
+        $field = "DATE_ADD('19700101', INTERVAL $field SECOND)";
+        if (!empty($offset)) {
+          $field = "($field + INTERVAL $offset_seconds SECOND)";
+        }
+        break;
+      case 'pgsql':
+        $field = "TO_TIMESTAMP($field)";
+        if (!empty($offset)) {
+          $field = "($field + INTERVAL '$offset_seconds SECONDS')";
+        }
+        break;
+      case 'sqlite':
+        if (!empty($offset)) {
+          $field = "($field + '$offset_seconds')";
+        }
+        break;
+    }
+
+    return $field;
+  }
+
+  /**
+   * Overrides \Drupal\views\Plugin\views\query\QueryPluginBase::setupTimezone().
+   */
+  public function setupTimezone() {
+    $timezone = drupal_get_user_timezone();
+
+    // set up the database timezone
+    $db_type = Database::getConnection()->databaseType();
+    if (in_array($db_type, array('mysql', 'pgsql'))) {
+      $offset = '+00:00';
+      static $already_set = FALSE;
+      if (!$already_set) {
+        if ($db_type == 'pgsql') {
+          Database::getConnection()->query("SET TIME ZONE INTERVAL '$offset' HOUR TO MINUTE");
+        }
+        elseif ($db_type == 'mysql') {
+          Database::getConnection()->query("SET @@session.time_zone = '$offset'");
+        }
+
+        $already_set = TRUE;
+      }
+    }
+
+    return $timezone;
+  }
+
+  /**
+   * Overrides \Drupal\views\Plugin\views\query\QueryPluginBase::getDateFormat().
+   */
+  public function getDateFormat($field, $format) {
+    $db_type = Database::getConnection()->databaseType();
+    switch ($db_type) {
+      case 'mysql':
+        $replace = array(
+          'Y' => '%Y',
+          'y' => '%y',
+          'M' => '%b',
+          'm' => '%m',
+          'n' => '%c',
+          'F' => '%M',
+          'D' => '%a',
+          'd' => '%d',
+          'l' => '%W',
+          'j' => '%e',
+          'W' => '%v',
+          'H' => '%H',
+          'h' => '%h',
+          'i' => '%i',
+          's' => '%s',
+          'A' => '%p',
+        );
+        $format = strtr($format, $replace);
+        return "DATE_FORMAT($field, '$format')";
+      case 'pgsql':
+        $replace = array(
+          'Y' => 'YYYY',
+          'y' => 'YY',
+          'M' => 'Mon',
+          'm' => 'MM',
+          // No format for Numeric representation of a month, without leading
+          // zeros.
+          'n' => 'MM',
+          'F' => 'Month',
+          'D' => 'Dy',
+          'd' => 'DD',
+          'l' => 'Day',
+          // No format for Day of the month without leading zeros.
+          'j' => 'DD',
+          'W' => 'WW',
+          'H' => 'HH24',
+          'h' => 'HH12',
+          'i' => 'MI',
+          's' => 'SS',
+          'A' => 'AM',
+        );
+        $format = strtr($format, $replace);
+        return "TO_CHAR($field, '$format')";
+      case 'sqlite':
+        $replace = array(
+          'Y' => '%Y',
+          // No format for 2 digit year number.
+          'y' => '%Y',
+          // No format for 3 letter month name.
+          'M' => '%m',
+          'm' => '%m',
+          // No format for month number without leading zeros.
+          'n' => '%m',
+          // No format for full month name.
+          'F' => '%m',
+          // No format for 3 letter day name.
+          'D' => '%d',
+          'd' => '%d',
+          // No format for full day name.
+          'l' => '%d',
+          // no format for day of month number without leading zeros.
+          'j' => '%d',
+          'W' => '%W',
+          'H' => '%H',
+          // No format for 12 hour hour with leading zeros.
+          'h' => '%H',
+          'i' => '%M',
+          's' => '%S',
+          // No format for AM/PM.
+          'A' => '',
+        );
+        $format = strtr($format, $replace);
+        return "strftime('$format', $field, 'unixepoch')";
+    }
+  }
+
 }
diff --git a/core/modules/views/lib/Drupal/views/Plugin/views/sort/Date.php b/core/modules/views/lib/Drupal/views/Plugin/views/sort/Date.php
index 072aea67ae8780f8a3542f6d89c3abb8a31c16d0..6ccd5fe71aa7765cf4cbffb671fc1ebf0a2cf23a 100644
--- a/core/modules/views/lib/Drupal/views/Plugin/views/sort/Date.php
+++ b/core/modules/views/lib/Drupal/views/Plugin/views/sort/Date.php
@@ -59,19 +59,19 @@ public function query() {
         $this->query->add_orderby($this->tableAlias, $this->realField, $this->options['order']);
         return;
       case 'minute':
-        $formula = $this->getSQLFormat('YmdHi');
+        $formula = $this->getDateFormat('YmdHi');
         break;
       case 'hour':
-        $formula = $this->getSQLFormat('YmdH');
+        $formula = $this->getDateFormat('YmdH');
         break;
       case 'day':
-        $formula = $this->getSQLFormat('Ymd');
+        $formula = $this->getDateFormat('Ymd');
         break;
       case 'month':
-        $formula = $this->getSQLFormat('Ym');
+        $formula = $this->getDateFormat('Ym');
         break;
       case 'year':
-        $formula = $this->getSQLFormat('Y');
+        $formula = $this->getDateFormat('Y');
         break;
     }