Commit 6e7dc26b by Carsten Brandt

added support for DateTimeImmutable to Formatter

fixes #5503
parent 6570c42d
......@@ -58,6 +58,7 @@ Yii Framework 2 Change Log
- Enh #5223: Query builder now supports selecting sub-queries as columns (qiangxue)
- Enh #5367: Added `yii\grid\DataColumn::encodeLabel` (SDKiller)
- Enh #5480: Added defensive code to `yii\web\User::getIdentity()` to avoid potential infinite recursion (qiangxue)
- Enh #5503: Added support for `DateTimeImmutable` to Formatter (olegtsvetkov, cebe)
- Enh #5587: `json_encode` is now used with `JSON_UNESCAPED_SLASHES | JSON_UNESCAPED_UNICODE` where it makes sense, also
it is now default for `Json::encode()` (samdark)
- Enh #5600: Allow configuring debug panels in `yii\debug\Module::panels` as panel class name strings (qiangxue)
......
......@@ -561,6 +561,10 @@ class Formatter extends Component
if ($formatter === null) {
throw new InvalidConfigException(intl_get_error_message());
}
// make IntlDateFormatter work with DateTimeImmutable
if ($timestamp instanceof \DateTimeImmutable) {
$timestamp = new DateTime($timestamp->format(DateTime::ISO8601), $timestamp->getTimezone());
}
return $formatter->format($timestamp);
} else {
if (strncmp($format, 'php:', 4) === 0) {
......@@ -569,7 +573,11 @@ class Formatter extends Component
$format = FormatConverter::convertDateIcuToPhp($format, $type, $this->locale);
}
if ($timeZone != null) {
$timestamp->setTimezone(new DateTimeZone($timeZone));
if ($timestamp instanceof \DateTimeImmutable) {
$timestamp = $timestamp->setTimezone(new DateTimeZone($timeZone));
} else {
$timestamp->setTimezone(new DateTimeZone($timeZone));
}
}
return $timestamp->format($format);
}
......
......@@ -70,6 +70,15 @@ class FormatterDateTest extends TestCase
$this->assertSame(date('n/j/y', $value->getTimestamp()), $this->formatter->asDate($value, 'short'));
$this->assertSame(date('F j, Y', $value->getTimestamp()), $this->formatter->asDate($value, 'long'));
if (version_compare(PHP_VERSION, '5.5.0', '>=')) {
$value = new \DateTimeImmutable();
$this->assertSame(date('M j, Y', $value->getTimestamp()), $this->formatter->asDate($value));
$this->assertSame(date('Y/m/d', $value->getTimestamp()), $this->formatter->asDate($value, 'php:Y/m/d'));
$this->assertSame(date('m/d/Y', $value->getTimestamp()), $this->formatter->asDate($value, 'MM/dd/yyyy'));
$this->assertSame(date('n/j/y', $value->getTimestamp()), $this->formatter->asDate($value, 'short'));
$this->assertSame(date('F j, Y', $value->getTimestamp()), $this->formatter->asDate($value, 'long'));
}
// empty input
$this->assertSame('Jan 1, 1970', $this->formatter->asDate(''));
$this->assertSame('Jan 1, 1970', $this->formatter->asDate(0));
......@@ -100,6 +109,12 @@ class FormatterDateTest extends TestCase
$this->assertSame(date('g:i:s A', $value->getTimestamp()), $this->formatter->asTime($value));
$this->assertSame(date('h:i:s A', $value->getTimestamp()), $this->formatter->asTime($value, 'php:h:i:s A'));
if (version_compare(PHP_VERSION, '5.5.0', '>=')) {
$value = new \DateTimeImmutable();
$this->assertSame(date('g:i:s A', $value->getTimestamp()), $this->formatter->asTime($value));
$this->assertSame(date('h:i:s A', $value->getTimestamp()), $this->formatter->asTime($value, 'php:h:i:s A'));
}
// empty input
$this->assertSame('12:00:00 AM', $this->formatter->asTime(''));
$this->assertSame('12:00:00 AM', $this->formatter->asTime(0));
......@@ -129,6 +144,12 @@ class FormatterDateTest extends TestCase
$this->assertSame(date('M j, Y g:i:s A', $value->getTimestamp()), $this->formatter->asDatetime($value));
$this->assertSame(date('Y/m/d h:i:s A', $value->getTimestamp()), $this->formatter->asDatetime($value, 'php:Y/m/d h:i:s A'));
if (version_compare(PHP_VERSION, '5.5.0', '>=')) {
$value = new \DateTimeImmutable();
$this->assertSame(date('M j, Y g:i:s A', $value->getTimestamp()), $this->formatter->asDatetime($value));
$this->assertSame(date('Y/m/d h:i:s A', $value->getTimestamp()), $this->formatter->asDatetime($value, 'php:Y/m/d h:i:s A'));
}
// empty input
$this->assertSame('Jan 1, 1970 12:00:00 AM', $this->formatter->asDatetime(''));
$this->assertSame('Jan 1, 1970 12:00:00 AM', $this->formatter->asDatetime(0));
......@@ -338,7 +359,6 @@ class FormatterDateTest extends TestCase
public function dateInputs()
{
return [
// ['2015-01-01 00:00:00', '2014-13-01'], // TODO evals to current time on that date
['2015-01-01 00:00:00', '2014-13-01 00:00:00'],
[false, 'asdfg', 'yii\base\InvalidParamException'],
// [(string)strtotime('now'), 'now'], // fails randomly
......@@ -381,6 +401,8 @@ class FormatterDateTest extends TestCase
*/
public function provideTimesAndTz()
{
$utc = new \DateTimeZone('UTC');
$berlin = new \DateTimeZone('Europe/Berlin');
$result = [];
foreach($this->provideTimezones() as $tz) {
$result[] = [$tz[0], 1407674460, 1388580060];
......@@ -393,6 +415,12 @@ class FormatterDateTest extends TestCase
$result[] = [$tz[0], '2014-08-10 14:41:00 +0200', '2014-01-01 13:41:00 +0100'];
$result[] = [$tz[0], '2014-08-10 14:41:00 +02:00', '2014-01-01 13:41:00 +01:00'];
$result[] = [$tz[0], '2014-08-10T14:41:00+02:00', '2014-01-01T13:41:00+01:00']; // ISO 8601
$result[] = [$tz[0], new DateTime('2014-08-10 12:41:00', $utc), new DateTime('2014-01-01 12:41:00', $utc)];
$result[] = [$tz[0], new DateTime('2014-08-10 14:41:00', $berlin), new DateTime('2014-01-01 13:41:00', $berlin)];
if (version_compare(PHP_VERSION, '5.5.0', '>=')) {
$result[] = [$tz[0], new \DateTimeImmutable('2014-08-10 12:41:00', $utc), new \DateTimeImmutable('2014-01-01 12:41:00', $utc)];
$result[] = [$tz[0], new \DateTimeImmutable('2014-08-10 14:41:00', $berlin), new \DateTimeImmutable('2014-01-01 13:41:00', $berlin)];
}
}
return $result;
}
......@@ -442,7 +470,7 @@ class FormatterDateTest extends TestCase
$this->assertSame('1388580060', $this->formatter->asTimestamp($inputTimeNonDst));
// tests for relative time
if ($inputTimeDst !== 1407674460) {
if ($inputTimeDst !== 1407674460 && !is_object($inputTimeDst)) {
$this->assertSame('3 hours ago', $this->formatter->asRelativeTime($inputTimeDst, $relativeTime = str_replace(['14:41', '12:41'], ['17:41', '15:41'], $inputTimeDst)));
$this->assertSame('in 3 hours', $this->formatter->asRelativeTime($relativeTime, $inputTimeDst));
$this->assertSame('3 hours ago', $this->formatter->asRelativeTime($inputTimeNonDst, $relativeTime = str_replace(['13:41', '12:41'], ['16:41', '15:41'], $inputTimeNonDst)));
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment