timestamp plugin displays incorrectly

jcc

Member
So, I'm working on a post to describe issues with the date plugin (http://fabrikar.com/forums/showthread.php?p=150145&posted=1#post150145) and I decided to try changing my element to a timestamp to see if that would work-around my issue. Please refer to the linked post for background and a description of the last_update_datetime shown below, if necessary.

An element hidden_update_datetime using the timestamp plug-in the following property settings:

Code:
Plug-in: timestamp
GMT or Local Server Time: Local
Update on edit: Yes
List format: Y-m-d h:m:s

Updating a row (@ 2012-08-30 09:52:45 EDT) shows in the back-end list as:

Code:
last_update_datetime:   2012-08-30 09:52:00
hidden_update_datetime: 2012-08-30 05:08:47 <-- What?!?

Changing hidden_update_datetime to GMT:

Code:
GMT or Local Server Time: GMT
Updating (@ 2012-08-30 09:56:07 EDT) results are the bizarre:

Code:
last_update_datetime:   2012-08-30 09:56:00
hidden_update_datetime: 2012-08-30 05:08:09 <-- Time going backwards?!?

So, I decide to look at the data stored in the database. The values there are exactly what I would expect...the current timestamp (as of the time the record was saved) in the correct timezone. Looking again at the back-end list shows these bizarre values, so it seems to be a formatting problem for displaying the data.
 
Ooops:

List format: Y-m-d h:m:s

Yeah, using the month instead of minutes won't help. Have changed the default to Y-m-d H:i:s.

Also think I've fixed the TZ thing in list display.

Fixes in github.

Haven't tested. ;)

-- hugh
 
LOL. OK, my bad. Should have actually looked at the default format it gave me. Thanks!
 
Maybe not quite...

I have just applied github Fabrik-fabrik-3.0.6.1-64-g6118aa8. I changed the hidden_update_datetime:

Code:
GMT or Local Server Time: Local
List format: Y-m-d H:i:s
Updating a record @ 2012-08-30 11:36:13 EDT, results in:

Code:
last_update_datetime:   2012-08-30 11:36:00
hidden_update_datetime: 2012-08-30 07:36:19 <-- UTC+8?

EDIT: Changing "GMT or Local Server Time:" to GMT, makes no difference.

The database value for hidden_update_datetime is 2012-08-30 11:36:19. It looks like the database timestamp is assumed to be GMT and applying the timezone before displaying.
 
Is that the list display, or the form display?

I tweaked the list display code, as we weren't taking the GMT vs local setting in to account. I may have tweaked it the wrong way. Try editing the code for timestamp.php, around line 96 and 97, where I set up $tz_offest. Try comparing the param with '1' instead of '0', see if that makes a difference.

-- hugh
 
It is the back-end list (timestamp doesn't display on the form.)

Changing that to "== '1';" doesn't seem to have made any difference.
 
JHTML date function

OK. I'm looking at the code and I think that the problem is the how the JHTML function is called. The timestamp.php code to which you pointed me is:

Code:
$tz_offset = $params->get('gmt_or_local', '0') == '0';
$data = JHTML::_('date', $data, JText::_($params->get('timestamp_format', 'DATE_FORMAT_LC2')), $tz_offset);
...the GMT or local setting switching between the boolean of true or false, but the JHTML date function in libraries/joomla/html/html.php describes the timezone parameter setting the input UTC date to be the user timezone ($tz=true) or the server timezone ($tz=false). Since the input date is not actually a UTC date, but rather already timezone shifted to the local date, either of the settings will shift it further.

At the moment, both the server time zone and all of the user timezone settings are, in fact, EDT (GMT-4) which makes both variants do the same thing, but neither of them are GMT.

When I change the code to:

Code:
$data = JHTML::_('date', $data, JText::_($params->get('timestamp_format', 'DATE_FORMAT_LC2')), null);
I get the value that was returned from the database which is correct for my needs; my local timezone.

To make the gmt_or_local parameter to work as described, 2 things must happen.

1) date needs to be stored in UTC
2) change the code to set $tz_offset=null for GMT or $tz_offset=true for the user local timezone.

NEW:

The timestamp plugin sets the column to be automatically set to the SQL builtin CURRENT_TIMESTAMP, which uses the timezone that is set for the database. So, the Fabrik timezone conversion for GMT or Local, needs to understand the timezone of the database. This can be obtained by the query:

Code:
mysql> select timediff(now(),convert_tz(now(),@@session.time_zone,'+00:00'));
+----------------------------------------------------------------+
| timediff(now(),convert_tz(now(),@@session.time_zone,'+00:00')) |
+----------------------------------------------------------------+
| -04:00:00                                                      |
+----------------------------------------------------------------+
From my naive point-of-view, perhaps the most expeditious way of solving this problem is to change the way that the database queries timestamp columns to use the convert_tz function to provide the data in UTC format.

Code:
mysql> select last_update_datetime2,convert_tz(last_update_datetime2,@@session.time_zone,'+00:00') from tom_test;
+-----------------------+----------------------------------------------------------------+
| last_update_datetime2 | convert_tz(last_update_datetime2,@@session.time_zone,'+00:00') |
+-----------------------+----------------------------------------------------------------+
|                  NULL | NULL                                                           |
|                  NULL | NULL                                                           |
|                  NULL | NULL                                                           |
|   2012-08-28 19:43:00 | 2012-08-28 23:43:00                                            |
|   2012-08-30 13:00:50 | 2012-08-30 17:00:50                                            |
|   2012-08-28 23:52:48 | 2012-08-29 03:52:48                                            |
|   2012-08-29 00:08:53 | 2012-08-29 04:08:53                                            |
|   2012-08-30 13:20:20 | 2012-08-30 17:20:20                                            |
|   2012-08-30 11:19:55 | 2012-08-30 15:19:55                                            |
|   2012-08-30 13:56:50 | 2012-08-30 17:56:50                                            |
+-----------------------+----------------------------------------------------------------+
10 rows in set (0.00 sec)
NEW 2:

This code seems to work for my circumstances. WARNING: it assumes that the Joomla! TZ is set the same as the database timezone.

Code:
        public function renderListData($data, &$thisRow)
        {
                $params = $this->getParams();
                $config = JFactory::getConfig();
                $date = JFactory::getDate($data);                 // incomming date in local TZ
                $tz = new DateTimeZone($config->get('offset'));   // get server TZ
                $localdate = new DateTime($date,$tz);             // create local date w/server TZ
                $localdate->setTimezone(new DateTimeZone('UTC')); // change local date to UTC
                $data = $localdate->format(JText::_($params->get('timestamp_format', 'DATE_FORMAT_LC2')));
                $tz_offset = $params->get('gmt_or_local', '0') == '1' ? true : null;
                $data = JHTML::_('date', $data, JText::_($params->get('timestamp_format', 'DATE_FORMAT_LC2')), $tz_offset);
                return parent::renderListData($data, $thisRow);
        }
 
friendly bump - I just updated to Fabrik-fabrik-3.0.6.3-31-g385d22c and the code has not yet made it into the master branch...

I have re-applied this change on my system.
 
hi
So all I need to do is step 2, updating the method renderListData?

However, I'm wondering if the store local/gmt setting is really a good idea here. There are bound to be people who don't have their database timezone set to the same timezone as joomla.
I remember very very vaguely now when I first wrote the plugin looking at the timezone issue, and realizing it was set by the db, but obviously that realization was lost over time and this setting was subsequently added.

What do people think about removing the option all together?

-Rob
 
Hi Rob,

"New 2" certainly works for the situations where the database and system and users timezones are all the same. It works for my situation, but certainly not all.

Hugh and I were talking about getting the TZ offset from the database, which is what the query under "New" does, but we were still discussing where that sort of query belonged...probably at some sort of global level and stored in params?

I have since had another idea as I stumbled across the SQL function UTC_TIMESTAMP which is what the implementation was really expecting, but I think that has other problems as well. I have not looked at the function to even determine in what version of mySQL it was introduced.

That said, I don't have any problems with just throwing-out the whole concept of the timezone shift for a column that is maintained by the CURRENT_TIMESTAMP function, since that is what I was going for in the first place. That would reduce the code needed in renderListData to just formatting the data.

Any of these work for me.

Tom
 
We'll probably have to pick this up when I'm back in the saddle next week. I fly home tomorrow, but it's a brutal day of travel, and I'll need the weekend to recover.

-- hugh
 
@Hugh - I'm not surprised. I've done that trip a number of times before. I'll bump on Monday.

BTW - I'm going to get a development environment going on my PC with an IDE so I can make debugging and changes faster/easier and submit my code directly to github. Most importantly, I want an interactive debugger so I can reduce (eliminate?) my dependence on var_dump. Current plan is:

  • WAMP
  • Eclipse
  • Egit
Do you have any recommendations?


Thnx -- Tom
 
I'll let hugh reply to that then :)
He uses xdebug for debugging from within eclipse.
I never mange to get it installed and running, so keep a map of the code in a contact lens I place over my eyes whilst I sleep, I find it does wonders for my subliminal knowledge of the code ;)
 
Yes, that's exactly what I run. Eclipse with Egit, using WAMP for my Windows test site, although I do most of my dev work against a separate Centos box, and only use WAMP when I'm on the road (hence running everything self contained on a single laptop) or if I need to do some Windows specific testing. And of course the standard xdebug extension from xdebug.org.

BTW, when setting up Eclipse on Windows, you'll also need to install the standard git client (which you probably have already), and configured as per the update in my original post on this Google+ thread:

https://plus.google.com/114419664855330371780/posts/LJrCrfabskA

-- hugh
 
We are in need of some funding.
More details.

Thank you.

Members online

No members online now.
Back
Top