diff --git a/framework/CHANGELOG.md b/framework/CHANGELOG.md index 776a32b14b..f6e4681e2a 100644 --- a/framework/CHANGELOG.md +++ b/framework/CHANGELOG.md @@ -7,6 +7,7 @@ Yii Framework 2 Change Log - Bug #7305: Logging of Exception objects resulted in failure of the logger i.e. no logs being written (cebe) - Bug #7707: client-side `trim` validator now passes the trimmed value to subsequent validators (nkovacs) - Bug #8322: `yii\behaviors\TimestampBehavior::touch()` now throws an exception if owner is new record (klimov-paul) +- Bug #8451: `yii\i18n\Formatter` did not allow negative unix timestamps as input for date formatting (cebe) - Bug: Fixed string comparison in `BaseActiveRecord::unlink()` which may result in wrong comparison result for hash valued primary keys starting with `0e` (cebe) - Enh #8070: `yii\console\controllers\MessageController` now sorts created messages, even if there is no new one, while saving to PHP file (klimov-paul) - Enh #8286: `yii\console\controllers\MessageController` improved allowing extraction of nested translator calls (klimov-paul) diff --git a/framework/i18n/Formatter.php b/framework/i18n/Formatter.php index ad598ea084..47ae15828f 100644 --- a/framework/i18n/Formatter.php +++ b/framework/i18n/Formatter.php @@ -641,9 +641,9 @@ class Formatter extends Component } try { if (is_numeric($value)) { // process as unix timestamp, which is always in UTC - if (($timestamp = DateTime::createFromFormat('U', $value, new DateTimeZone('UTC'))) === false) { - throw new InvalidParamException("Failed to parse '$value' as a UNIX timestamp."); - } + $timestamp = new DateTime(); + $timestamp->setTimezone(new DateTimeZone('UTC')); + $timestamp->setTimestamp($value); return $checkTimeInfo ? [$timestamp, true] : $timestamp; } elseif (($timestamp = DateTime::createFromFormat('Y-m-d', $value, new DateTimeZone($this->defaultTimeZone))) !== false) { // try Y-m-d format (support invalid dates like 2012-13-01) return $checkTimeInfo ? [$timestamp, false] : $timestamp; diff --git a/tests/framework/i18n/FormatterDateTest.php b/tests/framework/i18n/FormatterDateTest.php index 656d3a3a5c..300e29ff53 100644 --- a/tests/framework/i18n/FormatterDateTest.php +++ b/tests/framework/i18n/FormatterDateTest.php @@ -597,4 +597,30 @@ class FormatterDateTest extends TestCase $this->assertEquals('2015-04-28 12:06:15+0200', $this->formatter->asDateTime($timeStamp, 'yyyy-MM-dd HH:mm:ssZ')); } + + public function testInputUnixTimestamp() + { + $this->formatter->defaultTimeZone = 'UTC'; + $timeStamp = 1431907200; + $this->formatter->timeZone = 'UTC'; + $this->assertEquals('2015-05-18 00:00:00+0000', $this->formatter->asDateTime($timeStamp, 'yyyy-MM-dd HH:mm:ssZ')); + $this->formatter->timeZone = 'Europe/Berlin'; + $this->assertEquals('2015-05-18 02:00:00+0200', $this->formatter->asDateTime($timeStamp, 'yyyy-MM-dd HH:mm:ssZ')); + + $this->formatter->defaultTimeZone = 'Europe/Berlin'; + $timeStamp = 1431907200; + $this->formatter->timeZone = 'UTC'; + $this->assertEquals('2015-05-18 00:00:00+0000', $this->formatter->asDateTime($timeStamp, 'yyyy-MM-dd HH:mm:ssZ')); + $this->formatter->timeZone = 'Europe/Berlin'; + $this->assertEquals('2015-05-18 02:00:00+0200', $this->formatter->asDateTime($timeStamp, 'yyyy-MM-dd HH:mm:ssZ')); + + $this->formatter->defaultTimeZone = 'UTC'; + $timeStamp = -1431907200; + $this->formatter->timeZone = 'UTC'; + $this->assertEquals('1924-08-17 00:00:00+0000', $this->formatter->asDateTime($timeStamp, 'yyyy-MM-dd HH:mm:ssZ')); + $this->formatter->timeZone = 'Europe/Berlin'; + $this->assertEquals('1924-08-17 01:00:00+0100', $this->formatter->asDateTime($timeStamp, 'yyyy-MM-dd HH:mm:ssZ')); + + } + }