@tsteur opened this Issue on October 30th 2022 Member

see details below

Error: {"message":"date_timezone_set(): Argument #1 ($object) must be of type DateTime, bool given","file":"\/core\/Date.php","line":434,"request_id":"cee8f","backtrace":" on \/core\/Date.php(434)\n#0 \/core\/Date.php(434): date_timezone_set(false, Object(DateTimeZone))\n#1 \/core\/Date.php(451): Piwik\Date->getTimestamp()\n#2 \/plugins\/Live\/Model.php(653): Piwik\Date->isLater(Object(Piwik\Date))\n#3 \/plugins\/Live\/Model.php(66): Piwik\Plugins\Live\Model->getStartAndEndDate(Array, 'range', '1999-01-01,9999...')\n#4 \/plugins\/Live\/API.php(368): Piwik\Plugins\Live\Model->queryLogVisits(Array, 'range', '1999-01-01,9999...', false, 0, 10001, false, false, '', true)\n#5 \/plugins\/Live\/API.php(179): Piwik\Plugins\Live\API->loadLastVisitsDetailsFromDatabase(Array, 'range', '1999-01-01,9999...', false, 0, 10000, false, '', false)\n#6 [internal function]: Piwik\Plugins\Live\API->getLastVisitsDetails('5,11', 'range', '1999-01-01,9999...', false, false, false, false, false, false)\n#7 \/core\/API\/Proxy.php(244): call_user_func_array(Array, Array)\n#8 \/core\/Context.php(28): Piwik\API\Proxy->Piwik\API\{closure}()\n#9 \/core\/API\/Proxy.php(335): Piwik\Context::executeWithQueryParameters(Array, Object(Closure))\n#10 \/core\/API\/Request.php(267): Piwik\API\Proxy->call('\\Piwik\\Plugins\\...', 'getLastVisitsDe...', Array)\n#11 \/plugins\/API\/Controller.php(45): Piwik\API\Request->process()\n#12 [internal function]: Piwik\Plugins\API\Controller->index()\n#13 \/core\/FrontController.php(631): call_user_func_array(Array, Array)\n#14 \/core\/FrontController.php(169): Piwik\FrontController->doDispatch('API', false, Array)\n#15 \/core\/dispatch.php(32): Piwik\FrontController->dispatch()\n#16 \/index.php(25): require_once('\/c...')\n#17 {main}","safemode_backtrace":"#0 [internal function]: Piwik\Plugins\Cloud\Controller->safemode(Array)\n#1 \/core\/FrontController.php(631): call_user_func_array(Array, Array)\n#2 \/core\/FrontController.php(169): Piwik\FrontController->doDispatch('Cloud', 'safemode', Array)\n#3 \/core\/FrontController.php(100): Piwik\FrontController->dispatch('CorePluginsAdmi...', 'safemode', Array)\n#4 \/core\/FrontController.php(140): Piwik\FrontController::(Array)\n#5 \/core\/FrontController.php(190): Piwik\FrontController::(Object(TypeError))\n#6 \/core\/dispatch.php(32): Piwik\FrontController->dispatch()\n#7 \/index.php(25): require_once('\/c...')\n#8 {main}"}

URL: /index.php?module=API&method=Live.getLastVisitsDetails&idSite=5,11&date=1999-01-01,9999-12-31&period=range&format=json&filter_limit=10000&token_auth=XYZANONYMIZED&showColumns=lastActionDateTime,firstActionTimestamp,dimension1,userId,visitDuration,actions,visitCount,nb_visits,daysSinceFirstVisit,daysSinceLastVisit,visitDuration,country,visitorType,visitorId,siteID

GET: {"module":"API","method":"Live.getLastVisitsDetails","idSite":"5,11","date":"1999-01-01,9999-12-31","period":"range","format":"json","filter_limit":"10000","token_auth":"XYZANONYMIZED","showColumns":"lastActionDateTime,firstActionTimestamp,dimension1,userId,visitDuration,actions,visitCount,nb_visits,daysSinceFirstVisit,daysSinceLastVisit,visitDuration,country,visitorType,visitorId,siteID"}

@bx80 commented on October 30th 2022 Contributor

@tsteur I haven't look at this in much detail, but having 9999-12-31 at the end of a period range is going to have 23:59:59 appended to it, so we're starting with 9999-12-31 23:59:59 and then applying timezones for various calculations which could cause the date to roll over to `10000-01-01'.

Something like this will create the same error (albeit cheating by adding a second to the date)

$date = '9999-12-31 23:59:59';
$ts = date_create($date)->getTimestamp();
$ts += 1;
$time = date('r', $ts);
$dtime  = date_create($time);  
date_timezone_set($dtime, 'UTC');

If people are going to use 9999-12-31 as a range end date then maybe we can add a check to see if the supplied date / timestamp is at the max value for four digit years and prevent it being rolled over. Not sure timezone accuracy matters for period end dates 7977 years into the future.

$date = '9999-12-31 23:59:59';
$ts = date_create($date)->getTimestamp();
$ts += 1;
$time = date('r', $ts);
$dtime  = date_create($time);  

// check for possible yr9999 rollover and ignore timezone
if ($dtime === false && substr($date, 0, 10) === '9999-12-31') {
    $dtime = $dtime  = date_create($date); 
}

date_timezone_set($dtime, 'UTC');

Does that sound like an acceptable workaround?

@tsteur commented on October 31st 2022 Member

@bx80 I don't have any particular thoughts on this. I suppose as a user it be great to maybe get an error like "invalid date provided" or something. Like similar to https://github.com/matomo-org/matomo/blob/4.12.3/core/Date.php#L159-L167 where we throw an exception when the date is too old. Not sure where exactly the problem is in the code. Like if timestamp of year 3000 is > $timestamp then throw exception. Just a thought.

Powered by GitHub Issue Mirror