diff --git a/htdocs/core/lib/functions.lib.php b/htdocs/core/lib/functions.lib.php index 8714b0aa765..31d6de721b2 100644 --- a/htdocs/core/lib/functions.lib.php +++ b/htdocs/core/lib/functions.lib.php @@ -2045,13 +2045,12 @@ function dol_print_date($time, $format = '', $tzoutput = 'tzserver', $outputlang /** * Return an array with locale date info. - * PHP getdate is restricted to the years 1901-2038 on Unix and 1970-2038 on Windows - * WARNING: This function always use PHP server timezone to return locale informations !!! - * Usage must be avoid. - * FIXME: Replace content of this function with PHP date functions and a parameter $gm + * WARNING: This function use PHP server timezone by default to return locale informations. + * Be aware to add the third parameter to "UTC" if you need to work on UTC. * * @param int $timestamp Timestamp - * @param boolean $fast Fast mode + * @param boolean $fast Fast mode. deprecated. + * @param string $forcetimezone '' to use the PHP server timezone. Or use a form like 'Europe/Paris' or '+0200' to force timezone. * @return array Array of informations * If no fast mode: * 'seconds' => $secs, @@ -2061,34 +2060,40 @@ function dol_print_date($time, $format = '', $tzoutput = 'tzserver', $outputlang * 'wday' => $dow, 0=sunday, 6=saturday * 'mon' => $month, * 'year' => $year, - * 'yday' => floor($secsInYear/$_day_power), - * 'weekday' => gmdate('l',$_day_power*(3+$dow)), - * 'month' => gmdate('F',mktime(0,0,0,$month,2,1971)), - * If fast mode: - * 'seconds' => $secs, - * 'minutes' => $min, - * 'hours' => $hour, - * 'mday' => $day, - * 'mon' => $month, - * 'year' => $year, - * 'yday' => floor($secsInYear/$_day_power), - * 'leap' => $leaf, - * 'ndays' => $ndays + * 'yday' => floor($secsInYear/$_day_power) * @see dol_print_date(), dol_stringtotime(), dol_mktime() */ -function dol_getdate($timestamp, $fast = false) +function dol_getdate($timestamp, $fast = false, $forcetimezone = '') { global $conf; - $usealternatemethod = false; - if ($timestamp <= 0) $usealternatemethod = true; // <= 1970 - if ($timestamp >= 2145913200) $usealternatemethod = true; // >= 2038 - - if ($usealternatemethod) - { - $arrayinfo = adodb_getdate($timestamp, $fast); + if (empty($conf->global->MAIN_USE_OLD_FUNCTIONS_FOR_GETDATE)) { + //$datetimeobj = new DateTime('@'.$timestamp); + $datetimeobj = new DateTime(); + $datetimeobj->setTimestamp($timestamp); // Use local PHP server timezone + if ($forcetimezone) $datetimeobj->setTimezone(new DateTimeZone($forcetimezone)); // (add timezone relative to the date entered) + $arrayinfo = array( + 'year'=>((int) date_format($datetimeobj, 'Y')), + 'mon'=>((int) date_format($datetimeobj, 'm')), + 'mday'=>((int) date_format($datetimeobj, 'd')), + 'wday'=>((int) date_format($datetimeobj, 'w')), + 'yday'=>((int) date_format($datetimeobj, 'z')), + 'hours'=>((int) date_format($datetimeobj, 'H')), + 'minutes'=>((int) date_format($datetimeobj, 'i')), + 'seconds'=>((int) date_format($datetimeobj, 's')) + ); } else { - $arrayinfo = getdate($timestamp); + // PHP getdate is restricted to the years 1901-2038 on Unix and 1970-2038 on Windows + $usealternatemethod = false; + if ($timestamp <= 0) $usealternatemethod = true; // <= 1970 + if ($timestamp >= 2145913200) $usealternatemethod = true; // >= 2038 + + if ($usealternatemethod) + { + $arrayinfo = adodb_getdate($timestamp, $fast); + } else { + $arrayinfo = getdate($timestamp); + } } return $arrayinfo; diff --git a/test/phpunit/FunctionsLibTest.php b/test/phpunit/FunctionsLibTest.php index d113cde8035..2cb4d98610c 100644 --- a/test/phpunit/FunctionsLibTest.php +++ b/test/phpunit/FunctionsLibTest.php @@ -1257,9 +1257,6 @@ class FunctionsLibTest extends PHPUnit\Framework\TestCase $conf->global->MAIN_START_WEEK = 0; - $tmp=dol_getdate(1); // 1/1/1970 and 1 second = thirday - $this->assertEquals(4, $tmp['wday']); - $tmp=dol_getdate(24*60*60+1); // 2/1/1970 and 1 second = friday $this->assertEquals(5, $tmp['wday']); @@ -1271,12 +1268,77 @@ class FunctionsLibTest extends PHPUnit\Framework\TestCase $tmp=dol_getdate(24*60*60+1); // 2/1/1970 and 1 second = friday $this->assertEquals(5, $tmp['wday']); + $tmp=dol_getdate(1, false, "Europe/Paris"); // 1/1/1970 and 1 second = thirday + $this->assertEquals(1970, $tmp['year']); + $this->assertEquals(1, $tmp['mon']); + $this->assertEquals(1, $tmp['mday']); + $this->assertEquals(4, $tmp['wday']); + $this->assertEquals(0, $tmp['yday']); + $this->assertEquals(1, $tmp['hours']); // We are winter, so we are GMT+1 even during summer + $this->assertEquals(0, $tmp['minutes']); + $this->assertEquals(1, $tmp['seconds']); + + $tmp=dol_getdate(15638401, false, "Europe/Paris"); // 1/7/1970 and 1 second = wednesday + $this->assertEquals(1970, $tmp['year']); + $this->assertEquals(7, $tmp['mon']); + $this->assertEquals(1, $tmp['mday']); + $this->assertEquals(3, $tmp['wday']); + $this->assertEquals(181, $tmp['yday']); + $this->assertEquals(1, $tmp['hours']); // There is no daylight in 1970, so we are GMT+1 even during summer + $this->assertEquals(0, $tmp['minutes']); + $this->assertEquals(1, $tmp['seconds']); + + $tmp=dol_getdate(1593561601, false, "Europe/Paris"); // 1/7/2020 and 1 second = wednesday + $this->assertEquals(2020, $tmp['year']); + $this->assertEquals(7, $tmp['mon']); + $this->assertEquals(1, $tmp['mday']); + $this->assertEquals(3, $tmp['wday']); + $this->assertEquals(182, $tmp['yday']); // 182 and not 181, due to the 29th february + $this->assertEquals(2, $tmp['hours']); // There is a daylight, so we are GMT+2 + $this->assertEquals(0, $tmp['minutes']); + $this->assertEquals(1, $tmp['seconds']); + + $conf->global->MAIN_USE_OLD_FUNCTIONS_FOR_GETDATE = 1; + + $tmp=dol_getdate(1); // 1/1/1970 and 1 second = thirday + $this->assertEquals(1970, $tmp['year']); + $this->assertEquals(1, $tmp['mon']); + $this->assertEquals(1, $tmp['mday']); + $this->assertEquals(4, $tmp['wday']); + $this->assertEquals(0, $tmp['yday']); + // We must disable this because on CI, timezone is may be UTC or something else + //$this->assertEquals(1, $tmp['hours']); // We are winter, so we are GMT+1 even during summer + $this->assertEquals(0, $tmp['minutes']); + $this->assertEquals(1, $tmp['seconds']); + + $tmp=dol_getdate(15638401); // 1/7/1970 and 1 second = wednesday + $this->assertEquals(1970, $tmp['year']); + $this->assertEquals(7, $tmp['mon']); + $this->assertEquals(1, $tmp['mday']); + $this->assertEquals(3, $tmp['wday']); + $this->assertEquals(181, $tmp['yday']); + // We must disable this because on CI, timezone is may be UTC or something else + //$this->assertEquals(1, $tmp['hours']); // There is no daylight in 1970, so we are GMT+1 even during summer + $this->assertEquals(0, $tmp['minutes']); + $this->assertEquals(1, $tmp['seconds']); + + $tmp=dol_getdate(1593561601); // 1/7/2020 and 1 second = wednesday + $this->assertEquals(2020, $tmp['year']); + $this->assertEquals(7, $tmp['mon']); + $this->assertEquals(1, $tmp['mday']); + $this->assertEquals(3, $tmp['wday']); + $this->assertEquals(182, $tmp['yday']); // 182 and not 181, due to the 29th february + // We must disable this because on CI, timezone is may be UTC or something else + //$this->assertEquals(2, $tmp['hours']); // There is a daylight, so we are GMT+2 + $this->assertEquals(0, $tmp['minutes']); + $this->assertEquals(1, $tmp['seconds']); + return true; } /** - * testDolGetDate + * testMakeSubstitutions * * @return boolean */