There is a bug that exists between current calendar module and current Date module - essentially the calendar module is calling this "date_time" function to get the current date and then applying some corrections for users local timezone - BUT the date_time module has already done this - so what happens is that you get a "today" date that is twice the timeoffset ahead of time, which for more users probably looks like a day ahead.
from date module
// $Id: date.module,v 1.32.2.40 2007/04/19 20:35:25 karens Exp $
/**
* Implementation of time() adjusted for the current site and user.
*
* @param $offset - optional method to force time to a specific offset
* @return integer timestamp
*/
function date_time($offset = NULL) {
global $user;
if ($offset) {
return (time() - date("Z")) + offset;
}
elseif (variable_get('configurable_timezones', 1) && $user->uid && strlen($user->timezone)) {
return (time() - date("Z")) + $user->timezone;
}
else {
return (time() - date("Z")) + variable_get('date_default_timezone', 0);
}
}
and from calendar_api.module
// $Id: calendar_api.inc,v 1.15.2.16 2007/03/30 16:57:38 karens Exp $
/**
* Returns a local timestamp (as defined by the user or site's timezone) for
* midnight GMT.
* @return integer timestamp
*/
function calendar_user_date($part = 'timestamp') {
global $user;
static $date;
calendar_load_date_api();
if (!$date) {
$now = date_time();
if (variable_get('configurable_timezones', 1) && $user->uid && strlen($user->timezone)) {
$user_offset = $user->timezone;
}
else {
$user_offset = variable_get('date_default_timezone', 0);
}
$now += $user_offset;
$date = date_gmmktime(array(
'mon' => date_gmdate('m', $now),
'mday' => date_gmdate('j', $now),
'year' => date_gmdate('Y', $now),
));
}
so i think that $now += $user_offset; line can disappear from the calendar module?
is anyone mainting calendar module still?
Comment | File | Size | Author |
---|---|---|---|
#1 | date-calender-today.patch | 580 bytes | dgtlmoon |
Comments
Comment #1
dgtlmoon CreditAttribution: dgtlmoon commentedhere is my patch to remove the duplication of this functionality that leads to the extra erroneous time being added to the user offset.
this probably affects every calendar installation where it is required to show the current day?
Comment #2
dgtlmoon CreditAttribution: dgtlmoon commentedmaybe also related to http://drupal.org/node/147392
Comment #3
KarenS CreditAttribution: KarenS commentedGood detective work. Fix made in latest commit. Thanks!
Comment #4
(not verified) CreditAttribution: commentedComment #5
dabro CreditAttribution: dabro commentedI found this thread and it describes the problem I'm having with the current day being ahead. I'm in GMT-5 timezone and I have the site set up for configurable timezones. The events displaying in the calendar are correct and displaying on the right day with the right time. It's just the current day gets ahead in the late evening, I'm not sure but probably at the 5 hour before midnight mark. I tried the latest dev release (Calendar 5.1-dev with the patch?) and the problem still exists. I'm also using Date 5.x-1.6, MySQL ver 5.0.27, PHP ver 5.1.6. Thanks for the great work! Dave
Comment #6
Prodigy CreditAttribution: Prodigy commentedI turned off timezones and still get this problem. Anything you did to fix, please advise.
Comment #7
vortical CreditAttribution: vortical commentedI second what dabro said... I was about to post details, but it would have been a duplication of his post... the latest dev module didn't work for me either.
I am at GMT-5 and it switched on me tonight at 7PM local time, so 'today' seems to be tracking GMT.
Comment #8
vortical CreditAttribution: vortical commentedGot bored and decided to play with the code... turns out that all I had to do was add back the following code to calendar_api.inc (some of what dgtlmoon removed above, and some that must have been removed in the release since then)
I guess what fixed it some number of months ago is what broke it for me today... a related change to the Date module perhaps?
I'm using the latest dev version of the Calendar module and the latest released version (1.6) of the Date module.
I hope that helps... I don't know how to create/use .patch files or I would post one.
Comment #9
dabro CreditAttribution: dabro commentedVortical, can you clarify where your code is placed in calendar_api.inc? I'm not savvy enough to tell where it should go, I'd like to try your fix to see if that corrects my five hours ahead calendar. Thanks for the posting, Dave
Comment #10
sbloewen CreditAttribution: sbloewen commentedIn my investigation of this last week I found that the server timezone adjustment is applied twice. See code from 5.x-1.x-dev calendar_api.inc below:
The
date_time()
function applies both drupal (default or user) and server timezone correction. Thedate_gmmktime()
applies server correction as well, I believe. I changed$now = date_time();
to$now = date_time() + date("Z");
as a quick-n-dirty hack to negate the first correction. My testing indicated things then worked as I would expect them to. (I tried usingdate_mktime()
once instead, but as things worked much worse, I left it like this.) I hope there is a cleaner way of doing this. Ideas?Vortical, you are pretty much doing the same thing I did. You are subtracting 5 hours from the incorrect $now time, which, in your case, is 5 hours ahead. This will only (appear to) work if your website timezone is the same as your server timezone.
By the way, I'm GMT +8 and my server -6.
Comment #11
Prodigy CreditAttribution: Prodigy commentedFantastic discussion, as a lot of people are suffering from the "1 day ahead" problem.
I never made any changes at all to my files, they are all the latest stable releases.
My server is in the Eastern Time Zone, as is my site. What would I need to do to get my CCK Dates to appear in the right Views? Where should the code be placed? Thanks guys! I've been on this for 3 days trying work arounds!
The only thing that work is using hour/minute granularity with timezones, and I only want the year-month-day.
Comment #12
vortical CreditAttribution: vortical commentedOk, well I dove into this a little further and found a few things out...
it seems that
date_time()
was incorrectly calculating the local timedate_gmmktime()
does no date/time alteration, it just returns the time given by the input parameter into a "GMT formatted" time that allowsdate_format_date()
to extract all of the needed information (in the switch statement).I changed the following function in date.inc on line 219 from
to
Calls to
time()
returns the current GMT, so you don't need to offset with- date("Z")
before you offset based on the user's timezone or the default server timezone.@sbloewen (fancy meeting you here ;-) I suspect you know who I am, but look at my profile if you can't figure it out) -- using
mktime()
returns the timezone corrected time... which would have just "corrected" the time once again... so it makes sense that it screwed things up even more.Again, I don't know how to use/make .patch files, so you're on your own to edit date.inc
Cheers!
Comment #13
vortical CreditAttribution: vortical commentedwow the php highlighting tags didn't do what I thought they would.... sbloewen, how did you highlight code within a paragraph like that?
Comment #14
sbloewen CreditAttribution: sbloewen commentedI'm confused. Based on documentation and testing I don't see why this doesn't work. Maybe the problem is elsewhere? I've been using the pink "today" box on the calendar view as my debug tool. If the day is correct, could the reference be off (i.e. is the grid correct)?
I'm going to have to work on this later as I'm pressed for time, have many other issues in other modules, and currently have a workaround. Hopefully you'll find the problem soon.
Vortical, I'm pretty sure time() returns local (server) value, not GMT. I'm very hesitant to change anything in the date api as I don't know what else uses those functions. And yes, I know who you are. That's why I knew your server was in the same timezone as you. Don't use the code tags when you do php (I think that's what you were doing, anyway).
Comment #15
vortical CreditAttribution: vortical commentedSbloewen, you're right... what I did will definitely not work, and the
date_time()
function was correct as it was before I touched it. Calls totime()
definitely return the server local time.After hours of reading the documentation on php.net and testing a whole lot of different functions and such, I have FINALLY narrowed down the real cause of this problem. It does indeed lie in the date_api module, in the date.inc file in fact, but it has nothing to do with the
date_time()
function. The problem lies it thedate_format_date()
function, as explained below:A successful call to
date_format_date()
will in turn calldate_gmdate()
, which will call the php nativegmdate()
function for all current timestamps (not pre-1970). Through testing I have determined that thegmdate()
function takes the timestamp passed into it, and then reverses the local server default timezone offset to derive GMT date information. The issue is, and it is made clear in the original coder's comments above, that the original coder assumed that calls togmdate()
vs. calls todate()
were needed to prevent this timezone offset, however the opposite is actually true (try it yourself or look at the example code forgmdate()
on php.net if you don' t believe me!). There is one gotcha to just fixing this in the date_api module though -->Drupal's problems with dates/timezones are threaded in through hundreds of different places, so messing with the date_api module files is probably not the way to go... in fact, when I 'fixed' this in the date.inc file, it threw off a bunch of other calendar formatting things that were dependent upon date_format_date to be returning GMT date info... but the current date was right :-P So I ended up leaving the date module as it was -- flawed.
So I edited
calendar_user_date()
in the calendar_api.inc file, fromto
This changes the call from
date_format_date()
(and therefore never callsdate_gmdate()
) todate_date()
instead.date_date()
then calls the native phpdate()
function, which is what we want in this case because we want no further timezone corrections when we call for formatting. By doing this, we lose some text formatting thatdate_format_date()
would have done for us if the passed in options were requesting text in return, but none of the calls in ths fuction require such formatting, so we are ok!It feels good to finally get to the bottom of this particular issue, even if it just exposed more issues...
Again, I don't know how to create a .patch file, or use one for that matter, so you're on your own to edit
calendar_user_date()
in calendar_api.incCheers!
Comment #16
dabro CreditAttribution: dabro commentedSounded promising but all I get with this patch code is a white screen of death. Probably an error on my part. Thanks for your efforts, Dave
Comment #17
dabro CreditAttribution: dabro commentedI'd like to report that with a Vorticals' latest patch applied, it did work to correct my day ahead problem. If anyone else is experiencing this symptom, give it a try. Thanks for the help, Dave
Comment #18
jpsalter CreditAttribution: jpsalter commentedDitto - this change worked for me. Thank you very much!
Comment #19
therainmakor CreditAttribution: therainmakor commentedI also found that lines 620 & 621 of calendar.module should be changed to this as well.
Comment #20
KarenS CreditAttribution: KarenS commentedThe original issue was fixed and this was re-opened with a different issue, and the new issue (one day off in calendar) is a duplicate of http://drupal.org/node/99223. There is some interesting research into reasons why in this thread, and I may be able to incorporate some of it.
The 'one day off' issue has been a problem in every Drupal module that does calendars, including the Event module. My ultimate fix is the new Date API which I'm working on in HEAD that will quit using date() and gmmktime() and all those functions in favor of the much more robust date_create(), date_timezone_set(), and date_modify() functions added in PHP 5.
Comment #21
KarenS CreditAttribution: KarenS commentedMeant to change the status...