From a5adf1c52ca54ca3f69205b48e0188544a52fc05 Mon Sep 17 00:00:00 2001
From: "tim.plunkett" <tim.plunkett@241634.no-reply.drupal.org>
Date: Mon, 6 Aug 2012 15:36:17 +0200
Subject: [PATCH] Issue #1273946 by Dmitriy.trt, tim.plunkett | ralf.strobel:
 Added Option to override user time zone in date handlers.

---
 handlers/views_handler_field_date.inc         | 20 ++++++--
 .../views/Tests/Handler/FieldDateTest.php     | 47 ++++++++++++++-----
 2 files changed, 53 insertions(+), 14 deletions(-)

diff --git a/handlers/views_handler_field_date.inc b/handlers/views_handler_field_date.inc
index 2eecd8699754..520fa53e5b16 100644
--- a/handlers/views_handler_field_date.inc
+++ b/handlers/views_handler_field_date.inc
@@ -16,6 +16,7 @@ function option_definition() {
 
     $options['date_format'] = array('default' => 'small');
     $options['custom_date_format'] = array('default' => '');
+    $options['timezone'] = array('default' => '');
 
     return $options;
   }
@@ -55,6 +56,18 @@ function options_form(&$form, &$form_state) {
         ':input[name="options[date_format]"]' => array('value' => $custom_date_possible),
       );
     }
+    $form['timezone'] = array(
+      '#type' => 'select',
+      '#title' => t('Timezone'),
+      '#description' => t('Timezone to be used for date output.'),
+      '#options' => array('' => t('- Default site/user timezone -')) + system_time_zones(FALSE),
+      '#default_value' => $this->options['timezone'],
+    );
+    foreach (array_merge(array('custom'), array_keys($date_formats)) as $timezone_date_formats) {
+      $form['timezone']['#states']['visible'][] = array(
+        ':input[name="options[date_format]"]' => array('value' => $timezone_date_formats),
+      );
+    }
 
     parent::options_form($form, $form_state);
   }
@@ -67,6 +80,7 @@ function render($values) {
     }
 
     if ($value) {
+      $timezone = !empty($this->options['timezone']) ? $this->options['timezone'] : NULL;
       $time_diff = REQUEST_TIME - $value; // will be positive for a datetime in the past (ago), and negative for a datetime in the future (hence)
       switch ($format) {
         case 'raw time ago':
@@ -85,11 +99,11 @@ function render($values) {
           return t(($time_diff < 0 ? '%time hence' : '%time ago'), array('%time' => format_interval(abs($time_diff), is_numeric($custom_format) ? $custom_format : 2)));
         case 'custom':
           if ($custom_format == 'r') {
-            return format_date($value, $format, $custom_format, null, 'en');
+            return format_date($value, $format, $custom_format, $timezone, 'en');
           }
-          return format_date($value, $format, $custom_format);
+          return format_date($value, $format, $custom_format, $timezone);
         default:
-          return format_date($value, $format);
+          return format_date($value, $format, '', $timezone);
       }
     }
   }
diff --git a/lib/Drupal/views/Tests/Handler/FieldDateTest.php b/lib/Drupal/views/Tests/Handler/FieldDateTest.php
index eff9ae611906..86c1e85ca890 100644
--- a/lib/Drupal/views/Tests/Handler/FieldDateTest.php
+++ b/lib/Drupal/views/Tests/Handler/FieldDateTest.php
@@ -42,25 +42,50 @@ public function testFieldDate() {
     ));
     $time = gmmktime(0, 0, 0, 1, 1, 2000);
 
-    $maps = array(
-      'small' => format_date($time, 'small'),
-      'medium' => format_date($time, 'medium'),
-      'large' => format_date($time, 'large'),
-      'custom' => format_date($time, 'custom', 'c'),
+    $this->executeView($view);
+
+    $timezones = array(
+      NULL,
+      'UTC',
+      'America/New_York',
+    );
+    foreach ($timezones as $timezone) {
+      $dates = array(
+        'small' => format_date($time, 'small', '', $timezone),
+        'medium' => format_date($time, 'medium', '', $timezone),
+        'large' => format_date($time, 'large', '', $timezone),
+        'custom' => format_date($time, 'custom', 'c', $timezone),
+      );
+      $this->assertRenderedDatesEqual($view, $dates, $timezone);
+    }
+
+    $intervals = array(
       'raw time ago' => format_interval(REQUEST_TIME - $time, 2),
       'time ago' => t('%time ago', array('%time' => format_interval(REQUEST_TIME - $time, 2))),
       // TODO write tests for them
 //       'raw time span' => format_interval(REQUEST_TIME - $time, 2),
 //       'time span' => t('%time hence', array('%time' => format_interval(REQUEST_TIME - $time, 2))),
     );
+    $this->assertRenderedDatesEqual($view, $intervals);
+  }
 
-    $this->executeView($view);
-
-    foreach ($maps as $date_format => $expected_result) {
+  protected function assertRenderedDatesEqual($view, $map, $timezone = NULL) {
+    foreach ($map as $date_format => $expected_result) {
       $view->field['created']->options['date_format'] = $date_format;
-      $this->assertEqual($expected_result, $view->field['created']->advanced_render($view->result[0]));
-      debug($view->field['created']->advanced_render($view->result[0]));
+      $t_args = array(
+        '%value' => $expected_result,
+        '%format' => $date_format,
+      );
+      if (isset($timezone)) {
+        $t_args['%timezone'] = $timezone;
+        $message = t('Value %value in %format format for timezone %timezone matches.', $t_args);
+        $view->field['created']->options['timezone'] = $timezone;
+      }
+      else {
+        $message = t('Value %value in %format format matches.', $t_args);
+      }
+      $actual_result = $view->field['created']->advanced_render($view->result[0]);
+      $this->assertEqual($expected_result, $actual_result, $message);
     }
-    debug($view->result);
   }
 }
-- 
GitLab