? views-383994.patch
? views_handler_field_date.inc.patch
Index: handlers/views_handler_field_date.inc
===================================================================
RCS file: /cvs/drupal-contrib/contributions/modules/views/handlers/views_handler_field_date.inc,v
retrieving revision 1.3
diff -u -p -r1.3 views_handler_field_date.inc
--- handlers/views_handler_field_date.inc	2 Jun 2009 18:20:18 -0000	1.3
+++ handlers/views_handler_field_date.inc	12 Jan 2010 21:38:02 -0000
@@ -9,6 +9,8 @@ class views_handler_field_date extends v
   function option_definition() {
     $options = parent::option_definition();
 
+    $options['source_date_type'] = array('default' => 'timestamp');
+    $options['custom_source_date_type'] = array('default' => '');
     $options['date_format'] = array('default' => 'small');
     $options['custom_date_format'] = array('default' => '');
 
@@ -18,7 +20,37 @@ class views_handler_field_date extends v
   function options_form(&$form, &$form_state) {
     parent::options_form($form, $form_state);
     $time = time();
+    $timezone_offset = array();
+    $hours = -23;
 
+    while ($hours < 24):
+      $timezone_offset[$hours] = t('@hours hours', array('@hours' => $hours));
+      $hours++;
+    endwhile;
+
+    $form['source_date_type'] = array(
+      '#type' => 'select',
+      '#title' => t('Source Date Type'),
+      '#description' => t("If your data source is sending date values instead of UNIX timestamp values, specify the date type. These values will then be converted for formatting below."),
+      '#options' => array(
+        'custom' => t('Custom'),
+        'date' => date('Y-m-d'),
+        'datetime' => date('Y-m-d H:i:s'),
+        'datetime_with_timezone' => date('Y-m-d H:i:sO'),
+        'ical' => date('Ymd\THis'),
+        'ical_date' => date('Ymd'),
+        'iso' => date('Y-m-d\TH:i:s'),
+        'timestamp' => $time,
+      ),
+      '#default_value' => isset($this->options['source_date_type']) ? $this->options['source_date_type'] : 'timestamp',
+    );
+    $form['source_offset'] = array(
+      '#type' => 'select',
+      '#title' => t('Source Timezone Offset'),
+      '#description' => t("If your data source is sending dates in a local timezone, you can offset that time to match your web server's timezone"),
+      '#options' => $timezone_offset,
+      '#default_value' => isset($this->options['source_offset']) ? $this->options['source_offset'] : 0,
+    );
     $form['date_format'] = array(
       '#type' => 'select',
       '#title' => t('Date format'),
@@ -46,15 +78,69 @@ class views_handler_field_date extends v
 
   function render($values) {
     $value = $values->{$this->field_alias};
+    $source_type = $this->options['source_date_type'];
+    $source_offset = $this->options['source_offset'];
     $format = $this->options['date_format'];
+    if (in_array($source_type, array('custom'))) {
+      $custom_pattern = $this->options['custom_source_date_type'];
+    }
     if (in_array($format, array('custom', 'raw time ago', 'time ago', 'raw time span', 'time span'))) {
       $custom_format = $this->options['custom_date_format'];
     }
-    
+
     if (!$value) {
       return theme('views_nodate');
     }
     else {
+      // handle non-timestamp formats like date and datetime
+      switch ($source_type) { // convert $value to a timestamp when it's in a date format
+        case 'custom':
+          if(strtotime($value)) {
+            $value = strtotime($value);
+          }
+        case 'date':
+          if (preg_match('/^(\d\d\d\d)-(\d\d)-(\d\d)$/', $value)) {
+            if(strtotime($value)) {
+              $value = strtotime($value);
+            }
+          }
+        case 'datetime':
+          if (preg_match('/^(\d\d\d\d)-(\d\d)-(\d\d) (\d\d:\d\d:\d\d)$/', $value)) {
+            if(strtotime($value)) {
+              $value = strtotime($value);
+            }
+          }
+        case 'datetime_with_timezone':
+          if (preg_match('/^(\d\d\d\d)-(\d\d)-(\d\d) (\d\d:\d\d:\d\d)[-+](\d\d)(:)*(\d\d)*$/', $value)) {
+            if(strtotime($value)) {
+              $value = strtotime($value);
+            }
+          }
+        case 'ical': // TODO - Assuming timezone is 1-3 chars
+          if (preg_match('/^(\d\d\d\d)(\d\d)(\d\d)[A-Z]{1,3}(\d\d)(\d\d)(\d\d)(Z)*$/', $value)) {
+            if(strtotime($value)) {
+              $value = strtotime($value);
+            }
+          }
+        case 'ical_date':
+          if (preg_match('/^(\d\d\d\d)(\d\d)(\d\d)$/', $value)) {
+            if(strtotime($value)) {
+              $value = strtotime($value);
+            }
+          }
+        case 'iso': // TODO - Assuming timezone is 1-3 chars
+          if (preg_match('/^(\d\d\d\d)-(\d\d)-(\d\d)[A-Z]{1,3}(\d\d):(\d\d):(\d\d)(Z)*$/', $value)) {
+            if(strtotime($value)) {
+              $value = strtotime($value);
+            }
+          }
+      }
+
+      // adjust $value to data source's timezone offset
+      if ($source_offset !== 0) {
+        $value = $value + ($source_offset * 3600);
+      }
+
       $time_diff = 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':
