Currently when using any field handled by Views' views_handler_field_date, any time of future dates in winter time are shown with one hour ahead when displayed during summer time (and vice versa) because views_handler_field_date uses Drupal's format_date() function, which uses offsets instead of timezones.

I suggest that the date_api module, which introduces timezones for Drupal 6, replaces views_handler_field_date by its own field handler which uses the timezone-aware functions of date_api (date_make_date() and date_format_date()).

In date_api.views.inc:

/**
 * Implementation of hook_views_handlers() to register all of the basic handlers
 * views uses.
 */
function date_api_views_handlers() {
  return array(
    'info' => array(
      'path' => drupal_get_path('module', 'date_api') .'/includes',
      ),
    'handlers' => array(
      'date_api_argument_handler' => array(
        'parent' => 'views_handler_argument_date',
      ),
      'date_api_filter_handler' => array(
        'parent' => 'views_handler_filter_numeric',
      ),
      'date_api_field_handler' => array(
        'parent' => 'views_handler_field_date',
      ),
    ),
  );
}

/**
 * Replace handler 'views_handler_field_date' by 'date_api_field_handler' 
 */
function date_api_views_data_alter(&$data) {
  foreach ($data as $table => $config) {
    foreach ($config as $item => $item_config) {
      if (isset($item_config['field']) && $item_config['field']['handler'] == 'views_handler_field_date') {
        $data[$table][$item]['field']['handler'] = 'date_api_field_handler';
      }
    }
  }
}

In the new date_api_field_handler.inc:

<?php

/**
 * Replacement for views_handler_field_date, which takes into account real timezones instead of offsets,
 * which causes time of days in daylight saving time to be displayed wrongly on days in non-daylight saving time,
 * and vice versa.
 */
class date_api_field_handler extends views_handler_field_date {

  function render($values) {
    $value = $values->{$this->field_alias};
    $format = $this->options['date_format'];
    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 {
      $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':
          return format_interval($time_diff, is_numeric($custom_format) ? $custom_format : 2);
        case 'time ago':
          return t('%time ago', array('%time' => format_interval($time_diff, is_numeric($custom_format) ? $custom_format : 2)));
        case 'raw time span':
          return ($time_diff < 0 ? '-' : '') . format_interval(abs($time_diff), is_numeric($custom_format) ? $custom_format : 2);
        case 'time span':
          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':
          $date = date_make_date($value, date_default_timezone(), DATE_UNIX);
          return date_format_date($date, $format, $custom_format);
        default:
          $date = date_make_date($value, date_default_timezone(), DATE_UNIX);
          return date_format_date($date, $format);
      }
    }
  }
}
CommentFileSizeAuthor
#2 views_date_field-6.x-1.0-beta1.tgz1.32 KBcyberwolf

Comments

imclean’s picture

http://drupal.org/patch/create

Also see earlier issue #864394: Problem with Timezones in custom module!.

That said, it sounds like an interesting approach.

cyberwolf’s picture

StatusFileSize
new1.32 KB

To get on with our project I implemented this successfully in a module, which I attach here.

imclean’s picture

Works well, thanks Cyberwolf.

cyberwolf’s picture

What is the preferred way of adding this to the date project? As an additional module or as a patch?

IMHO a separate module would be the best choice, as it can be easily enabled/disabled then.

imclean’s picture

Status: Active » Needs review

If it's within the date project it could be enabled through the admin settings.

I've updated the status so we can hopefully get some attention to this issue.

naringas’s picture

subscribe
looks like I could use this patch/module... and probably the Views project as well?

cyberwolf’s picture

Still any interest for this, then I'll try to spend some time on making a patch? We are not building any new websites anymore on Drupal 6, and timezone handling is now properly implemented in Drupal 7.

damienmckenna’s picture

Status: Needs review » Closed (won't fix)

Unfortunately the D6 version of this module is no longer supported, but we appreciate the time you put into this. If this problem is relevant for D7 too, please reopen the issue. Thanks.