We are using the function format_date to display date/times. Here in Montreal Canada, we will soon change our daylight savings time to Eastern Standard Time (1 hour behind actual time).
All dates after the new time changes shows the wrong hour, since the timezones value are different.

You can see this by running this code :

// This code will print 2 different dates
$curdate= strtotime('2009-11-03 19:00'); // Specify a date in a different timezone than your actual one
print date('D, j M Y - H:i', $curdate);
print format_date($curdate, 'custom', 'D, j M Y - H:i');

// This code will print identical dates
$curdate= strtotime('2009-10-30 19:00'); // Specify a date in a same timezone is OK 
print date('D, j M Y - H:i', $curdate);
print format_date($curdate, 'custom', 'D, j M Y - H:i');

It would be nice to have format_date() return the same datetime as date().
We use format_date for translations.

Thank you.

Comments

anrikun’s picture

Subscribing +1

traviscarden’s picture

Title: format_date wrongly ajust timezone for dates » format_date wrongly adjusts dates for timezones
Version: 6.14 » 6.15

I think I'm observing the same problem:

print format_date(strtotime('2009-09-27 00:00:00'), 'custom', 'l, F d, Y'); // Erroneously prints "Saturday, September 26, 2009", but...
print date('l, F d, Y', strtotime('2009-09-27 00:00:00')); // Correctly prints "Sunday, September 27, 2009"

If I add two hours to the time (2009-09-27 02:00:00) format_date() returns the correct day.

cheshireinatree’s picture

Just to clarify.

What is being seen, or at least my attempt at reproducing the error, is a daylight savings issue. Whether this is a bug or just improper usage by the user, I'm not sure. During the part of the year with daylight savings, drupal's format_date() function returns a datetime one hour behind the php date() function. Below is an example. If anyone has any more insight into what is happening, I'd be interested in a more technical explanation.

print format_date(strtotime('2009-11-27 00:00:00'), 'custom', 'D, d M Y H:i:s') . '<br />'; // Fri, 27 Nov 2009 00:00:00
print date('D, d M Y H:i:s', strtotime('2009-11-27 00:00:00')) . '<br />'; // Fri, 27 Nov 2009 00:00:00

print format_date(strtotime('2009-09-27 00:00:00'), 'custom', 'D, d M Y H:i:s') . '<br />'; // Sat, 26 Sep 2009 23:00:00 (daylight savings)
print date('D, d M Y H:i:s', strtotime('2009-09-27 00:00:00')) . '<br />'; // Sun, 27 Sep 2009 00:00:00 (daylight savings)
sapark’s picture

I don't know what's going on but when I enter
$node->created = mktime(0, 0, 0, 10, 1, $year); // 10-01-2008 midnight
I get 2008-10-01 01:00:00 -0400 in node/edit, it shows up as midnight in RSS, and 1:00 AM in Outlook.

But, if I do the same for Jan 1 of any year, I get the same thing except it shows 12:00 AM in Outlook.

benCorpo’s picture

I think I get the problem. I will do more digging but here's my finding:
the function format_date() adjusts the timestamp with the timezone and then uses the function gmdate() to build the date string.

But the function gmdate() automatically readjust the time when daylight is applicable or not.
This can be seen by running this:

print gmdate('D, d M Y H:i', strtotime('2009-09-27 00:00:00')); // Sun, 27 Sep 2009 04:00
print date('D, d M Y H:i', strtotime('2009-09-27 00:00:00')); //Sun, 27 Sep 2009 00:00

print gmdate('D, d M Y H:i', strtotime('2009-11-27 00:00:00')); // Fri, 27 Nov 2009 05:00
print date('D, d M Y H:i', strtotime('2009-11-27 00:00:00')); Fri, 27 Nov 2009 00:00

format_date() should check if the date being processed has the same timezone difference and adjust if not the case.

pierpaolo.bortone’s picture

Hi benCorpo,
we have patched in a dirty way the format_date() function like follow:

....
$timestamp += $timezone;

##################### PATCH - start #####################################
if(date("I", $timestamp))
$timestamp += 3600;
##################### PATCH - end #####################################

switch ($type) {
case 'small':
....

Now all works fine.
PS: thanks to Massimo

damien tournoud’s picture

Category: bug » feature
Status: Active » Closed (won't fix)

Drupal 6 doesn't support daylight saving and display all the dates in the specified timezone offset (GMT+- something). Drupal 7 introduced proper daylight saving.

damien tournoud’s picture

You can use the date module that should provide a solution for this in Drupal 6.

benCorpo’s picture

In order to bypass this bug, we already had been using the date module functions instead, but it does not seem to be able to translate the format, months and days according to current user's language and locale. At least the date and times are correct, just having english words, not a big deal. :)

Thanks Damien.

hanno’s picture

Thanx for the report, helped me as well. Had a site showing the dates in the theme one day earlier as expected. Just added +3600 to the timestamp value.

Arnold Schw.’s picture

Title: format_date wrongly adjusts dates for timezones » format_date wrongly adjusts dates for timezones - solved

See this link:
http://api.drupal.org/api/drupal/includes--common.inc/function/format_date/
See the comment of NoCoolNamesRemain.
Adding a 0 for timezone does the trick !!!!

shyamala’s picture

Drupal Version: 6.19

We are creating multiple nodes and each node has a validity date range. The date range could be a future, current or past date ranges. When the dates fall with in the Day light saving time the format date function does not return the right value.

This problem of date happens only in places where we use format date to render the timestamp, seems to work well in the edit forms, where we use date field.

We have built a custom function where we check if the day light saving time is applicable to a particular date and add 1 hour to the timestamp before displaying the same.

function custom_format_date($timestamp, $datetime = 'DATE' , $dateformat) {
  $dls_start = strtotime("Second Sunday March ". date('Y', $timestamp));
  $dls_end = strtotime("First Sunday November ". date('Y', $timestamp));
  switch($datetime) {
    case 'DATE':
      if($timestamp > $dls_start && $timestamp < $dls_end) {
        $value = format_date($timestamp + 3600, 'custom', $dateformat);
      } else {
        $value = format_date($timestamp, 'custom', $dateformat);        
      }
      break;
    case 'TIME':
      if($timestamp > $dls_start && $timestamp < $dls_end) {
        $value = format_date($timestamp + 3600, 'custom', $dateformat);
      } else {
        $value = format_date($timestamp, 'custom', $dateformat);        
      }
      break;    
  }
  return $value;
}
japicoder’s picture

#6 worked for me. Simple and usefull. Thanks!

hanno’s picture

Title: format_date wrongly adjusts dates for timezones - solved » format_date wrongly adjusts dates for timezones

Deleting solved in the issue title, as this issue isn't solved but is a won't fix. It is solved only in Drupal 7 afaik (http://drupal.org/node/605730#comment-3512864). For Drupal 6 there are some workarounds as listed above.