mirror of
https://github.com/Combodo/iTop.git
synced 2026-04-22 01:58:47 +02:00
✅ N°5143 Fix FunctionExpression for DATE_FORMAT and formats %j, %k and %l
This commit is contained in:
@@ -2762,25 +2762,96 @@ class FunctionExpression extends Expression
|
||||
return $iRet;
|
||||
|
||||
case 'DATE_FORMAT':
|
||||
if (count($this->m_aArgs) != 2)
|
||||
{
|
||||
if (count($this->m_aArgs) != 2) {
|
||||
throw new \Exception("Function {$this->m_sVerb} requires 2 arguments");
|
||||
}
|
||||
$oDate = new DateTime($this->m_aArgs[0]->Evaluate($aArgs));
|
||||
$sFormat = $this->m_aArgs[1]->Evaluate($aArgs);
|
||||
$sFormat = str_replace(
|
||||
array('%y', '%x', '%w', '%W', '%v', '%T', '%S', '%r', '%p', '%M', '%l', '%k', '%I', '%h', '%b', '%a', '%D', '%c', '%e', '%Y', '%d', '%m', '%H', '%i', '%s'),
|
||||
array('y', 'o', 'w', 'l', 'W', 'H:i:s', 's', 'h:i:s A', 'A', 'F', 'g', 'H', 'h', 'h','M', 'D', 'jS', 'n', 'j', 'Y', 'd', 'm', 'H', 'i', 's'),
|
||||
$sFormat);
|
||||
if (preg_match('/%j/', $sFormat))
|
||||
{
|
||||
$sFormat = str_replace('%j', date_format($oDate, 'z') + 1, $sFormat);
|
||||
}
|
||||
if (preg_match('/%[fUuVX]/', $sFormat))
|
||||
{
|
||||
$sFormatForMysqlDateFormat = $this->m_aArgs[1]->Evaluate($aArgs);
|
||||
|
||||
if (preg_match('/%[fUuVX]/', $sFormatForMysqlDateFormat)) {
|
||||
throw new NotYetEvaluatedExpression("Expression ".$this->RenderExpression().' cannot be evaluated (known limitation)');
|
||||
}
|
||||
$sRet = date_format($oDate, $sFormat);
|
||||
|
||||
if (preg_match('/%j/', $sFormatForMysqlDateFormat)) {
|
||||
$sFormatForMysqlDateFormat = str_replace('%j', 'z', $sFormatForMysqlDateFormat);
|
||||
$sRet = date_format($oDate, $sFormatForMysqlDateFormat);
|
||||
$sRet++;
|
||||
/** @noinspection PhpUnnecessaryLocalVariableInspection */
|
||||
$sRet = str_pad($sRet, 3, '0', STR_PAD_LEFT);
|
||||
|
||||
return $sRet;
|
||||
}
|
||||
|
||||
/**
|
||||
* @var string[] $aFormatsForMysqlDateFormat
|
||||
* @link https://dev.mysql.com/doc/refman/5.7/en/date-and-time-functions.html#function_date-format
|
||||
*/
|
||||
//@formatter:off we want to keep every single item on its own line to ease comp between MySQL and PHP formats !
|
||||
$aFormatsForMysqlDateFormat = [
|
||||
'%y',
|
||||
'%x',
|
||||
'%w',
|
||||
'%W',
|
||||
'%v',
|
||||
'%T',
|
||||
'%S',
|
||||
'%r',
|
||||
'%p',
|
||||
'%M',
|
||||
'%l',
|
||||
'%k',
|
||||
'%I',
|
||||
'%h',
|
||||
'%b',
|
||||
'%a',
|
||||
'%D',
|
||||
'%c',
|
||||
'%e',
|
||||
'%Y',
|
||||
'%d',
|
||||
'%m',
|
||||
'%H',
|
||||
'%i',
|
||||
'%s'
|
||||
];
|
||||
//@formatter:on
|
||||
/**
|
||||
* @var string[] $aFormatsForPhpDateFormat
|
||||
* @link https://www.php.net/manual/en/datetime.format.php
|
||||
*/
|
||||
//@formatter:off we want to keep every single item on its own line to ease comp between MySQL and PHP formats !
|
||||
$aFormatsForPhpDateFormat = [
|
||||
'y',
|
||||
'o',
|
||||
'w',
|
||||
'l',
|
||||
'W',
|
||||
'H:i:s',
|
||||
's',
|
||||
'h:i:s A',
|
||||
'A',
|
||||
'F',
|
||||
'g',
|
||||
'G',
|
||||
'h',
|
||||
'h',
|
||||
'M',
|
||||
'D',
|
||||
'jS',
|
||||
'n',
|
||||
'j',
|
||||
'Y',
|
||||
'd',
|
||||
'm',
|
||||
'H',
|
||||
'i',
|
||||
's'
|
||||
];
|
||||
//@formatter:on
|
||||
$sFormatForPhpDateFormat = str_replace($aFormatsForMysqlDateFormat, $aFormatsForPhpDateFormat, $sFormatForMysqlDateFormat);
|
||||
/** @noinspection PhpUnnecessaryLocalVariableInspection */
|
||||
$sRet = date_format($oDate, $sFormatForPhpDateFormat);
|
||||
|
||||
return $sRet;
|
||||
|
||||
case 'TO_DAYS':
|
||||
|
||||
@@ -455,7 +455,11 @@ class ExpressionEvaluateTest extends iTopDataTestCase
|
||||
}
|
||||
|
||||
/**
|
||||
* Systematically check all supported format specs, for a given date
|
||||
* For a given date,
|
||||
* for all different formats (1st array element returned by {@see static::TimeFormatsProvider}),
|
||||
* compare value returned by :
|
||||
* * DATE_FORMAT() SQL function,
|
||||
* * FunctionExpression('DATE_FORMAT', ...) result
|
||||
*
|
||||
* @covers FunctionExpression::Evaluate()
|
||||
* @dataProvider EveryTimeFormatProvider
|
||||
@@ -481,7 +485,8 @@ class ExpressionEvaluateTest extends iTopDataTestCase
|
||||
}
|
||||
$sSelects = "SELECT ".implode(', ', $aSelects);
|
||||
$aRes = CMDBSource::QueryToArray($sSelects);
|
||||
$aRow = $aRes[0];
|
||||
/** @var array $aMysqlDateFormatRsultsForAllFormats format as key, MySQL evaluated result as value */
|
||||
$aMysqlDateFormatRsultsForAllFormats = $aRes[0];
|
||||
foreach ($aFormats as $sFormatDesc => $aFormatSpec)
|
||||
{
|
||||
$sFormat = $aFormatSpec[0];
|
||||
@@ -489,13 +494,8 @@ class ExpressionEvaluateTest extends iTopDataTestCase
|
||||
if ($bProcessed)
|
||||
{
|
||||
$oExpression = new FunctionExpression('DATE_FORMAT', array(new ScalarExpression($sDate), new ScalarExpression("%$sFormat")));
|
||||
$res = $oExpression->Evaluate(array());
|
||||
if (is_numeric($res)) {
|
||||
// N°3091 after PHPUnit upgrade from 6 to 8.5 some errors were thrown here
|
||||
// example : assertEquals was returning false for expected=8 and actual=08
|
||||
$res = (float) $res;
|
||||
}
|
||||
static::assertEquals($aRow[$sFormat], $res, "Format %$sFormat not matching MySQL for '$sDate'");
|
||||
$itopExpressionResult = $oExpression->Evaluate(array());
|
||||
static::assertSame($aMysqlDateFormatRsultsForAllFormats[$sFormat], $itopExpressionResult, "Format %$sFormat not matching MySQL for '$sDate'");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user