Calendar Feed Block Start date Today
Submitted Aiwa, Apr 20 2012 09:04 AM | Last updated Apr 20 2012 09:04 AM
If you specify the filter start date as 'today' it doesn't factor in the users or server timezone when querying what to display. So 'today' will only display events while it is still that date in GMT or before.
admin/applications_addon/ips/calendar/extensions/content/feed_block/calendar.php
Example: Event occurs at 8:00PM CST (-6) today. It will show on the feed block until 6 PM CST (-6) then it will roll off as it is no longer 'today' in GMT.
admin/applications_addon/ips/calendar/extensions/content/feed_block/calendar.php
if( $config['filters']['filter_start'] OR $config['filters']['filter_end'] )
{
$timenow = $config['filters']['filter_start'] ? @strtotime( $config['filters']['filter_start'] ) : 0;
$timethen = $config['filters']['filter_end'] ? @strtotime( $config['filters']['filter_end'] ) : 0;
Example: Event occurs at 8:00PM CST (-6) today. It will show on the feed block until 6 PM CST (-6) then it will roll off as it is no longer 'today' in GMT.
| Status: | Fixed |
| Version: | 2.3.1 |
| Fixed In: | 2.3.2 |











22 Comments
if( $timenow ) { if( $this->memberData['member_id'] AND $this->memberData['time_offset'] ) { $timenow = $timenow - ( $this->memberData['time_offset'] * 3600 ); } else if( !$this->memberData['member_id'] AND $this->settings['time_offset'] ) { $timenow = $timenow - ( $this->settings['time_offset'] * 3600 ); } }Trying to echo $this->memberData['time_offset'] in the feed block for me echo's '0' when in the DB it is -6... This may be an IP.Board cache issue...
Can you give this change a shot? Basically adding the offset to the strtotime calls.
Here is where you apply the offset to the filter date.... Shouldn't that be $timenow + offset?
if( $timenow ) { if( $this->memberData['member_id'] AND $this->memberData['time_offset'] ) { $timenow = $timenow - ( $this->memberData['time_offset'] * 3600 ); } else if( !$this->memberData['member_id'] AND $this->settings['time_offset'] ) { $timenow = $timenow - ( $this->settings['time_offset'] * 3600 ); } }Further down you apply the offset to the event start date.. Already a +
$_startTime = strtotime( $r['event_start_date'] ); if( !$r['event_all_day'] ) { if( $this->memberData['member_id'] AND $this->memberData['time_offset'] ) { $_startTime = $_startTime + ( $this->memberData['time_offset'] * 3600 ); } else if( !$this->memberData['member_id'] AND $this->settings['time_offset'] ) { $_startTime = $_startTime + ( $this->settings['time_offset'] * 3600 ); }Yes, you're right, it is already trying to account for the offset. Shouldn't need to be done twice obviously. Taking a closer look.
The filter date is having the offset applied, then that time w/ offset is being used as is to query the DB which stores the event time in GMT...
I think there in lies the problem when the event date in GMT crosses a day mark.
You can't do that kind of logic in the SQL query to adjust the date being pulled from the DB.. You almost need to add a day to $timenow and then add further logic when building $events
I'm thinking this should work - care to test?
$timenow = $config['filters']['filter_start'] ? @strtotime( $config['filters']['filter_start'] ) : 0; $timethen = $config['filters']['filter_end'] ? @strtotime( $config['filters']['filter_end'] ) : 0; if( $timenow ) { $timenow += $this->registry->class_localization->getTimeOffset(); } if( $timethen ) { $timethen += $this->registry->class_localization->getTimeOffset(); }That certainly simplifies the if statements a bit... After testing, thought, it should be a minus... You are shifting GMT the opposite direction so that 00:00 of 'today' in the users timezone would match the date you are querying in the DB that is stored in GMT... using getTimeOffset() puts in DST, which is not observed in GMT.. So it throws off the normalized date by an hour...
Code below works, which is basically the same thing you had before...... I'm going to scratch a hole in my head... I'm beginning to wonder if the issue I saw was a server issue... The clock went FUBAR or something. Because manually adjusting the offset below I can make the events appear and disappear when they are supposed to...
if( $timenow ) { if( $this->memberData['member_id'] AND $this->memberData['time_offset'] ) { $timenow -= ( $this->memberData['time_offset'] * 3600 ); } else if( !$this->memberData['member_id'] AND $this->settings['time_offset'] ) { $timenow -= ( $this->settings['time_offset'] * 3600 ); } } if( $timethen ) { if( $this->memberData['member_id'] AND $this->memberData['time_offset'] ) { $timethen -= ( $this->memberData['time_offset'] * 3600 ); } else if( !$this->memberData['member_id'] AND $this->settings['time_offset'] ) { $timethen -= ( $this->settings['time_offset'] * 3600 ); } }I think the reason I was getting 0 for time_offset was because of this..... I was calling it from inside the block template, though.
$backup = $this->memberData['time_offset']; $backup1 = $this->memberData['dst_in_use']; $backup2 = $this->registry->class_localization->offset; $this->memberData['time_offset'] = 0; $this->memberData['dst_in_use'] = 0; $this->registry->class_localization->offset = 0; ob_start(); $return = $this->registry->output->getTemplate('ccs')->$templateBit( $block['block_name'], $events ); ob_end_clean(); $this->memberData['time_offset'] = $backup; $this->memberData['dst_in_use'] = $backup1; $this->registry->class_localization->offset = $backup2;It 'appears' to be working fine for me now, but I'll do more testing tonight when it's tomorrow GMT and see if I can duplicate it again.
I'll do more testing tonight.
I have event set up for 'today @ 7:00 PM CST... I have my start filter set for 'today'... The event is NOT showing in the feed block...
If I set the filter to '6 hours ago', the event shows up...If it's anything less than 6.. say 5,4,3,2, or 1.. The event does NOT show up.
Let me keep digging through the code to wrap my head around this now that it's reproduceable...
strtotime('today') currently returns 4/21 00:00.. $timenow is being normalized relative to GMT to 4/21 06:00... So 'today' isn't really 'today'... It is off by 24 hours.. My day today started at 4/20 06:00
The event that is today for me is 4/21 01:00 (GMT).. So it wouldn't get pulled by the DB query as the date occurs before 4/21 06:00 .
Same would hold true for GMT + when they crossed into tomorrow and GMT was yesterday... their use of 'today' would actually be 'yesterday'. So events would hold in the block longer than they are supposed to.
Since I ate so much of your time earlier... Here's how I have fixed it on my board... Code is self explanatory, but basically I'm comparing the dates... If the date in GMT is different than the date in the users/guests timezone, we need to add or remove 24 hours so 'today' is relative.
if( $config['filters']['filter_start'] OR $config['filters']['filter_end'] ) { $timenow = $config['filters']['filter_start'] ? @strtotime( $config['filters']['filter_start'] ) : 0; $timethen = $config['filters']['filter_end'] ? @strtotime( $config['filters']['filter_end'] ) : 0; if( $timenow ) { $date1 = gmstrftime( "%Y-%m-%d", $timenow ); $date2 = gmstrftime( "%Y-%m-%d", ($timenow + $this->registry->class_localization->getTimeOffset() ) ); if( $date1 > $date2 ) { $timenow -= 86400; } if( $date1 < $date2 ) { $timenow += 86400; } if( $this->memberData['member_id'] AND $this->memberData['time_offset'] ) { $timenow = $timenow - ( $this->memberData['time_offset'] * 3600 ); } else if( !$this->memberData['member_id'] AND $this->settings['time_offset'] ) { $timenow = $timenow - ( $this->settings['time_offset'] * 3600 ); } } if( $timethen ) { $date1 = gmstrftime( "%Y-%m-%d", $timethen ); $date2 = gmstrftime( "%Y-%m-%d", ($timethen + $this->registry->class_localization->getTimeOffset() ) ); if( $date1 > $date2 ) { $timethen -= 86400; } if( $date1 < $date2 ) { $timethen += 86400; } if( $this->memberData['member_id'] AND $this->memberData['time_offset'] ) { $timethen = $timethen - ( $this->memberData['time_offset'] * 3600 ); } else if( !$this->memberData['member_id'] AND $this->settings['time_offset'] ) { $timethen = $timethen - ( $this->settings['time_offset'] * 3600 ); } }int strtotime ( string $time [, int $now = time() ] )
$now = The timestamp which is used as a base for the calculation of relative dates.
Give $now the date with the correct offset and it might pull the correct date from the get go... I'm not all that familiar with that particular function..
The only other thing we need to watch out for is that this doesn't adversely affect non "today", "yesterday", etc. types of strings.
If it is relative, 6 hours ago, it wouldn't work.
This can be duplicated after 6 pm CST on any event that occurs after 6 pm CST of the current day and as long as your time zone and GMT have separate dates, ie it is tomorrow in GMT. That, unfortunately, doesn't provide a whole hell of a lot of time to poke around with tests.. I'll mess with it tonight to see if I can come up with a solution that will work for all cases.
Ok. So all that code I put in there.... Can be replaced by using the $now var...
Using your original code, change the $timenow and $timethen to the below.
This gives you the time relative to the users timezone... Which is great for 'today', 'yesterday', 'tomorrow', 'tomorrow noon'... But as soon as you throw in '6 hours ago', the time used to query the DB will be off relative to the offset that is used as the second param of the strtotime call.
Short of doing the below (which would be wrong exactly one second every hour) I don't see how to account for both static and relative dates and still normalize the data to GMT for the DB query...
if( !gmstrftime( "%M", $timenow) AND !gmstrftime( "%S", $timenow) ) { $timenow -= $this->registry->class_localization->getTimeOffset();if( gmstrftime( "%M", $timenow) OR gmstrftime( "%S", $timenow) ) { $timenow -= $this->registry->class_localization->getTimeOffset(); }$timenow = $config['filters']['filter_start'] ? @strtotime( $config['filters']['filter_start'], @time() + $this->registry->class_localization->getTimeOffset() ) : 0; $timethen = $config['filters']['filter_end'] ? @strtotime( $config['filters']['filter_end'], @time() + $this->registry->class_localization->getTimeOffset() ) : 0; if( $timenow ) { if( $this->memberData['member_id'] AND $this->memberData['time_offset'] ) { $timenow = $timenow - ( $this->memberData['time_offset'] * 3600 ); } else if( !$this->memberData['member_id'] AND $this->settings['time_offset'] ) { $timenow = $timenow - ( $this->settings['time_offset'] * 3600 ); } } if( $timethen ) { if( $this->memberData['member_id'] AND $this->memberData['time_offset'] ) { $timethen = $timethen - ( $this->memberData['time_offset'] * 3600 ); } else if( !$this->memberData['member_id'] AND $this->settings['time_offset'] ) { $timethen = $timethen - ( $this->settings['time_offset'] * 3600 ); } }