?
avatar pdoolz
pdoolz
21 Jan 2016

Steps to reproduce the issue

I was trying to find which of the queries in my component are slowing my site down. So I echoed out some time checkpoints and look what happens:
Line 64 Debug point 1: 08:41:19
Line 92 Debug point 2: 08:41:19
Line 118 Debug point 3: 08:41:19
Line 122 Debug point 4: 12:41:19
Line 126 Debug point 5: 12:41:19

It did not take 4 hours to run from point 3 to point 4. This is the code:
118 echo "

Line ".LINE." Debug point ".$tz++.": ".date("H:i:s")."

";
119 $db->setQuery($query1);
120 //$db->execute();
121 $cats = $db->loadAssocList();
122 echo "

Line ".LINE." Debug point ".$tz++.": ".date("H:i:s")."

";

To reproduce the issue:

  1. Set a timezone other than whatever your server default is (I can't change my host's timezone)
    date_default_timezone_set('Pacific/Auckland');

  2. run some kind of query using jdatabase
    $db = JFactory::getDbo(); // Get a db connection.
    echo "

    Line ".LINE." Debug point ".$tz++.": ".date("H:i:s")."

    "; //Time in your TimeZone
    $db->setQuery("select * from table limit 1");
    $cats = $db->loadAssocList();
    echo "

    Line ".LINE." Debug point ".$tz++.": ".date("H:i:s")."

    "; // Time in Server TimeZone

Expected result

Line 64 Debug point 1: 08:41:19
Line 92 Debug point 2: 08:41:19
Line 118 Debug point 3: 08:41:19
Line 122 Debug point 4: 08:41:19
Line 126 Debug point 5: 08:41:19

Actual result

Line 64 Debug point 1: 08:41:19
Line 92 Debug point 2: 08:41:19
Line 118 Debug point 3: 08:41:19
Line 122 Debug point 4: 12:41:19
Line 126 Debug point 5: 12:41:19

System information (as much as possible)

Latest Joomla version
Running on LAMP on GoDaddy hosted service

Additional comments

This code runs in the component's root php file
defined('_JEXEC') or die;
date_default_timezone_set('Pacific/Auckland');
$controller = JControllerLegacy::getInstance('DStore');
$controller->execute(JFactory::getApplication()->input->get('task'));
$controller->redirect();

Also the Timezone set in Joomla Configuration is
public $offset = 'Pacific/Auckland';

avatar pdoolz pdoolz - open - 21 Jan 2016
avatar fruppel
fruppel - comment - 27 Jan 2016
    echo date("H:i:s"); echo "<br />";
    date_default_timezone_set('Pacific/Auckland');
    echo date("H:i:s"); echo "<br />";
    $db = JFactory::getDbo();
    echo date("H:i:s"); echo "<br />";
    $db->setQuery("select * from #__content limit 1");
    $cats = $db->loadAssocList();
    echo date("H:i:s"); echo "<br />";

Result:

20:22:23
08:22:23
08:22:23
08:22:23

Can't confirm that JDatabase changes timezone

avatar brianteeman
brianteeman - comment - 28 Jan 2016

@pdoolz can you test the code above from @fruppel please - do you still have an issue


This comment was created with the J!Tracker Application at issues.joomla.org/joomla-cms/8958.

avatar brianteeman brianteeman - change - 28 Jan 2016
Status New Information Required
avatar musinik
musinik - comment - 30 Jan 2016

I have the same problems.
I also tried to change the date directly in MySQL, what actually doesn't work also.

It looks like Joomla resets the timezone each query.

$db->execute( "SET time_zone = 'Europe/Moscow';"); // server normally accepts this. Checked in MySQL server directly. Time changes.
$db->setQuery("SELECT @@global.time_zone, @@session.time_zone;");
$db->execute();
$rows=$db->loadAssocList();
echo json_encode($rows);

Result:
[{"@@global.time_zone":"SYSTEM","@@session.time_zone":"SYSTEM"}]

Notes: SYSTEM timezone is other than 'Europe/Moscow'.

Joomla! 3.4.5 Stable [ Ember ] 22-October-2015 21:30 GMT


This comment was created with the J!Tracker Application at issues.joomla.org/joomla-cms/8958.

avatar Fedik
Fedik - comment - 30 Jan 2016

I think it is caused by JDate::getInstance() behavior, JDate::getInstance() caches the date objects (by date key), and if at some point of time was requested cached date, but with different timezone, then cached object changes to requested timezone, and you get result exactly as you described

it not a :bug: it is feature :smile:

avatar mbabker
mbabker - comment - 30 Jan 2016

JDate itself isn't caching anything. JFactory::getDate() does cache by the
time string plus timezone and always returns a clone.

On Saturday, January 30, 2016, Fedir Zinchuk notifications@github.com
wrote:

I think it is caused by JDate behavior, JDate caches the date objects (by
date key), and if at some point of time was requested cached date, but with
different timezone, then cached object changes to requested timezone, and
you get result exactly as you described


Reply to this email directly or view it on GitHub
#8958 (comment).

avatar Fedik
Fedik - comment - 31 Jan 2016

sorry, ignore whole my message,
@mbabker is right.

but, cloning JDate seems does not clone $tz property of JDate, so if TimeZone object in use somewhere, and changes at some point of time, it still can cause such issue.

avatar Fedik
Fedik - comment - 31 Jan 2016

in theory, for fix it, need to add __clone() to the JDate:

function __clone()
{
  $tz = clone $this->tz;
  $this->setTimezone($tz);
}
avatar musinik
musinik - comment - 31 Jan 2016

Just in case, a workaround I used by now is taking the timezone from user
(or config) and bussing it as a variable to the stored procedure which
executes set time zone and makes a select.

воскресенье, 31 января 2016 г. пользователь Fedir Zinchuk написал:

in theory, for fix it, need to add __clone() to the JDate:

function __clone(){ $tz = clone $this->tz; $this->setTimezone($tz);}


Reply to this email directly or view it on GitHub
#8958 (comment).

С уважением, Ключко Никита

avatar Devportobello
Devportobello - comment - 8 Feb 2016

Just tested something and dunno if this is related.
Maybe i'm missing something but both constructor(JDate and Datetime) dont return same result with a timezone given;

To demonstrate, use this:

$d1 = new JDate('2016/08/02 16:30:00',new DateTimeZone('Europe/Paris'));
$d2 = new DateTime('2016/08/02 16:30:00',new DateTimeZone('Europe/Paris'));
echo '<pre>'.$d1->format('d/m/Y H:i:s (e)').'</pre><pre>'.$d2->format('d/m/Y H:i:s (e)').'</pre>';
02/08/2016 14:30:00 (GMT)
02/08/2016 16:30:00 (Europe/Paris)
avatar mbabker
mbabker - comment - 8 May 2016

JDate is a quirky beast and the format() method default signature goes against the parent DateTime object. By default it formats dates to GMT and you have to pass a second parameter to get the date converted to the "local" timezone (so $d1->format('d/m/Y H:i:s (e)', true); should give you the date in the right timezone).

avatar Devportobello
Devportobello - comment - 9 May 2016

Thx for explanation @mbabker , i missed this param...

avatar brianteeman
brianteeman - comment - 9 May 2016

Can we close this?

avatar mbabker
mbabker - comment - 9 May 2016

I'd say yes as it's expected behavior (debatable whether it's correct depending on who you ask). The JDate constructor changes the system timezone to UTC and it is recommended to use the JDate class for date/time operations in the CMS environment instead of the procedural date functions or the DateTime class (the main thing JDate offers is a standardized timezone for date/time values and translatability of the strings that come with it).

avatar brianteeman brianteeman - change - 9 May 2016
Status Information Required Expected Behaviour
Closed_Date 0000-00-00 00:00:00 2016-05-09 14:41:16
Closed_By brianteeman
avatar brianteeman
brianteeman - comment - 9 May 2016

Closed as expected behaviour


This comment was created with the J!Tracker Application at issues.joomla.org/joomla-cms/8958.

avatar brianteeman brianteeman - close - 9 May 2016
avatar brianteeman brianteeman - close - 9 May 2016
avatar max-payne-7
max-payne-7 - comment - 29 Nov 2016

Hi,

Could somebody please test the code below and let me know why the dates returned are different ?

`
$mainframe = \JFactory::getApplication();
date_default_timezone_set($mainframe->getCfg('offset'));

print_r(date('Y-m-d H:i:s'));
\JDatabase::getInstance();
print_r(date('Y-m-d H:i:s'));
`
Joomla config server timezone is set to UTC, server timezone using print_r(date_default_timezone_get()); is Europe/Berlin, what JDatabase does is that it reverts the new set timezone which is the one in Joomla config (UTC) to the server's default.

Thanks!

avatar mbabker
mbabker - comment - 29 Nov 2016
  1. No part of the database API touches the system timezone (either read or write), so if the date is getting changed then there is something else not part of Joomla core making the change.

  2. All places in Joomla core which do change the system timezone immediately reset that value. The changes are done to standardize time operations to UTC (or a user configured timezone when converting values). So at the worst the timezone has changed for 3 or 4 lines of code which don't even have an integration point to hook into.

  3. The database API does log statements. When the logger API creates a JLogEntry object, it creates a new JDate object. As explained earlier, the JDate constructor does change the system timezone to create an object standardized on the UTC timezone. But also immediately resets the timezone. It does this by creating a DateTimeZone object based on the default system timezone via date_default_timezone_get(), however, this function call also has error suppression in front of it. So if the date_default_timezone_get() call fails, the system timezone won't be known and the time can't be correctly reset. This is indicative of a PHP configuration error on your local platform.

Add a Comment

Login with GitHub to post a comment