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);
}
}
}
}
Comments
Comment #1
imclean commentedhttp://drupal.org/patch/create
Also see earlier issue #864394: Problem with Timezones in custom module!.
That said, it sounds like an interesting approach.
Comment #2
cyberwolf commentedTo get on with our project I implemented this successfully in a module, which I attach here.
Comment #3
imclean commentedWorks well, thanks Cyberwolf.
Comment #4
cyberwolf commentedWhat 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.
Comment #5
imclean commentedIf 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.
Comment #6
naringas commentedsubscribe
looks like I could use this patch/module... and probably the Views project as well?
Comment #7
cyberwolf commentedStill 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.
Comment #8
damienmckennaUnfortunately 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.