Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Appearance settings

Commit a48d36a

Browse filesBrowse files
committed
bug #14895 [Form] Support DateTimeImmutable in transform() (c960657)
This PR was merged into the 2.3 branch. Discussion ---------- [Form] Support DateTimeImmutable in transform() | Q | A | ------------- | --- | Bug fix? | yes | New feature? | yes | BC breaks? | no | Deprecations? | no | Tests pass? | yes | Fixed tickets | | License | MIT | Doc PR | When passing a DateTimeImmutable instance to DateTimeToLocalizedStringTransformer::transform($dateTime), it throws an exception, `TransformationFailedException('Expected a \DateTime.')`. The method just converts a date-time object into a string, so there is no reason that it should not support all DateTimeInterface implementations. DateTimeInterface was added in PHP 5.5, so in order to support earlier versions, we need to do instanceof checks for both DateTime and DateTimeInterface. When Symfony requires PHP 5.5 or larger, we can remove the DateTime check and only check for DateTimeInterface. This was originally submitted as a PR against the 2.7 branch in #14676. Commits ------- 17346c5 [Form] Support DateTimeImmutable in transform()
2 parents a39dafa + 17346c5 commit a48d36a
Copy full SHA for a48d36a
Expand file treeCollapse file tree

10 files changed

+111
-34
lines changed

‎src/Symfony/Component/Form/Extension/Core/DataTransformer/DateTimeToArrayTransformer.php

Copy file name to clipboardExpand all lines: src/Symfony/Component/Form/Extension/Core/DataTransformer/DateTimeToArrayTransformer.php
+8-5Lines changed: 8 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -51,7 +51,7 @@ public function __construct($inputTimezone = null, $outputTimezone = null, array
5151
/**
5252
* Transforms a normalized date into a localized date.
5353
*
54-
* @param \DateTime $dateTime Normalized date.
54+
* @param \DateTime|\DateTimeInterface $dateTime A DateTime object
5555
*
5656
* @return array Localized date.
5757
*
@@ -72,14 +72,17 @@ public function transform($dateTime)
7272
), array_flip($this->fields));
7373
}
7474

75-
if (!$dateTime instanceof \DateTime) {
76-
throw new TransformationFailedException('Expected a \DateTime.');
75+
if (!$dateTime instanceof \DateTime && !$dateTime instanceof \DateTimeInterface) {
76+
throw new TransformationFailedException('Expected a \DateTime or \DateTimeInterface.');
7777
}
7878

79-
$dateTime = clone $dateTime;
8079
if ($this->inputTimezone !== $this->outputTimezone) {
80+
if (!$dateTime instanceof \DateTimeImmutable) {
81+
$dateTime = clone $dateTime;
82+
}
83+
8184
try {
82-
$dateTime->setTimezone(new \DateTimeZone($this->outputTimezone));
85+
$dateTime = $dateTime->setTimezone(new \DateTimeZone($this->outputTimezone));
8386
} catch (\Exception $e) {
8487
throw new TransformationFailedException($e->getMessage(), $e->getCode(), $e);
8588
}

‎src/Symfony/Component/Form/Extension/Core/DataTransformer/DateTimeToLocalizedStringTransformer.php

Copy file name to clipboardExpand all lines: src/Symfony/Component/Form/Extension/Core/DataTransformer/DateTimeToLocalizedStringTransformer.php
+4-10Lines changed: 4 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -70,7 +70,7 @@ public function __construct($inputTimezone = null, $outputTimezone = null, $date
7070
/**
7171
* Transforms a normalized date into a localized date string/array.
7272
*
73-
* @param \DateTime $dateTime Normalized date.
73+
* @param \DateTime|\DateTimeInterface $dateTime A DateTime object
7474
*
7575
* @return string|array Localized date string/array.
7676
*
@@ -84,17 +84,11 @@ public function transform($dateTime)
8484
return '';
8585
}
8686

87-
if (!$dateTime instanceof \DateTime) {
88-
throw new TransformationFailedException('Expected a \DateTime.');
87+
if (!$dateTime instanceof \DateTime && !$dateTime instanceof \DateTimeInterface) {
88+
throw new TransformationFailedException('Expected a \DateTime or \DateTimeInterface.');
8989
}
9090

91-
// convert time to UTC before passing it to the formatter
92-
$dateTime = clone $dateTime;
93-
if ('UTC' !== $this->inputTimezone) {
94-
$dateTime->setTimezone(new \DateTimeZone('UTC'));
95-
}
96-
97-
$value = $this->getIntlDateFormatter()->format((int) $dateTime->format('U'));
91+
$value = $this->getIntlDateFormatter()->format($dateTime->getTimestamp());
9892

9993
if (intl_get_error_code() != 0) {
10094
throw new TransformationFailedException(intl_get_error_message());

‎src/Symfony/Component/Form/Extension/Core/DataTransformer/DateTimeToRfc3339Transformer.php

Copy file name to clipboardExpand all lines: src/Symfony/Component/Form/Extension/Core/DataTransformer/DateTimeToRfc3339Transformer.php
+3-3Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -27,13 +27,13 @@ public function transform($dateTime)
2727
return '';
2828
}
2929

30-
if (!$dateTime instanceof \DateTime) {
31-
throw new TransformationFailedException('Expected a \DateTime.');
30+
if (!$dateTime instanceof \DateTime && !$dateTime instanceof \DateTimeInterface) {
31+
throw new TransformationFailedException('Expected a \DateTime or \DateTimeInterface.');
3232
}
3333

3434
if ($this->inputTimezone !== $this->outputTimezone) {
3535
$dateTime = clone $dateTime;
36-
$dateTime->setTimezone(new \DateTimeZone($this->outputTimezone));
36+
$dateTime = $dateTime->setTimezone(new \DateTimeZone($this->outputTimezone));
3737
}
3838

3939
return preg_replace('/\+00:00$/', 'Z', $dateTime->format('c'));

‎src/Symfony/Component/Form/Extension/Core/DataTransformer/DateTimeToStringTransformer.php

Copy file name to clipboardExpand all lines: src/Symfony/Component/Form/Extension/Core/DataTransformer/DateTimeToStringTransformer.php
+8-5Lines changed: 8 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -90,7 +90,7 @@ public function __construct($inputTimezone = null, $outputTimezone = null, $form
9090
* Transforms a DateTime object into a date string with the configured format
9191
* and timezone.
9292
*
93-
* @param \DateTime $value A DateTime object
93+
* @param \DateTime|\DateTimeInterface $dateTime A DateTime object
9494
*
9595
* @return string A value as produced by PHP's date() function
9696
*
@@ -104,13 +104,16 @@ public function transform($value)
104104
return '';
105105
}
106106

107-
if (!$value instanceof \DateTime) {
108-
throw new TransformationFailedException('Expected a \DateTime.');
107+
if (!$value instanceof \DateTime && !$value instanceof \DateTimeInterface) {
108+
throw new TransformationFailedException('Expected a \DateTime or \DateTimeInterface.');
109+
}
110+
111+
if (!$value instanceof \DateTimeImmutable) {
112+
$value = clone $value;
109113
}
110114

111-
$value = clone $value;
112115
try {
113-
$value->setTimezone(new \DateTimeZone($this->outputTimezone));
116+
$value = $value->setTimezone(new \DateTimeZone($this->outputTimezone));
114117
} catch (\Exception $e) {
115118
throw new TransformationFailedException($e->getMessage(), $e->getCode(), $e);
116119
}

‎src/Symfony/Component/Form/Extension/Core/DataTransformer/DateTimeToTimestampTransformer.php

Copy file name to clipboardExpand all lines: src/Symfony/Component/Form/Extension/Core/DataTransformer/DateTimeToTimestampTransformer.php
+4-11Lines changed: 4 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@ class DateTimeToTimestampTransformer extends BaseDateTimeTransformer
2424
/**
2525
* Transforms a DateTime object into a timestamp in the configured timezone.
2626
*
27-
* @param \DateTime $value A \DateTime object
27+
* @param \DateTime|\DateTimeInterface $dateTime A DateTime object
2828
*
2929
* @return int A timestamp
3030
*
@@ -38,18 +38,11 @@ public function transform($value)
3838
return;
3939
}
4040

41-
if (!$value instanceof \DateTime) {
42-
throw new TransformationFailedException('Expected a \DateTime.');
41+
if (!$value instanceof \DateTime && !$value instanceof \DateTimeInterface) {
42+
throw new TransformationFailedException('Expected a \DateTime or \DateTimeInterface.');
4343
}
4444

45-
$value = clone $value;
46-
try {
47-
$value->setTimezone(new \DateTimeZone($this->outputTimezone));
48-
} catch (\Exception $e) {
49-
throw new TransformationFailedException($e->getMessage(), $e->getCode(), $e);
50-
}
51-
52-
return (int) $value->format('U');
45+
return $value->getTimestamp();
5346
}
5447

5548
/**

‎src/Symfony/Component/Form/Tests/Extension/Core/DataTransformer/DateTimeToArrayTransformerTest.php

Copy file name to clipboardExpand all lines: src/Symfony/Component/Form/Tests/Extension/Core/DataTransformer/DateTimeToArrayTransformerTest.php
+24Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -116,6 +116,30 @@ public function testTransformDifferentTimezones()
116116
$this->assertSame($output, $transformer->transform($input));
117117
}
118118

119+
public function testTransformDateTimeImmutable()
120+
{
121+
if (PHP_VERSION_ID < 50500) {
122+
$this->markTestSkipped('DateTimeImmutable was introduced in PHP 5.5.0');
123+
}
124+
125+
$transformer = new DateTimeToArrayTransformer('America/New_York', 'Asia/Hong_Kong');
126+
127+
$input = new \DateTimeImmutable('2010-02-03 04:05:06 America/New_York');
128+
129+
$dateTime = new \DateTimeImmutable('2010-02-03 04:05:06 America/New_York');
130+
$dateTime = $dateTime->setTimezone(new \DateTimeZone('Asia/Hong_Kong'));
131+
$output = array(
132+
'year' => (string) (int) $dateTime->format('Y'),
133+
'month' => (string) (int) $dateTime->format('m'),
134+
'day' => (string) (int) $dateTime->format('d'),
135+
'hour' => (string) (int) $dateTime->format('H'),
136+
'minute' => (string) (int) $dateTime->format('i'),
137+
'second' => (string) (int) $dateTime->format('s'),
138+
);
139+
140+
$this->assertSame($output, $transformer->transform($input));
141+
}
142+
119143
/**
120144
* @expectedException \Symfony\Component\Form\Exception\TransformationFailedException
121145
*/

‎src/Symfony/Component/Form/Tests/Extension/Core/DataTransformer/DateTimeToLocalizedStringTransformerTest.php

Copy file name to clipboardExpand all lines: src/Symfony/Component/Form/Tests/Extension/Core/DataTransformer/DateTimeToLocalizedStringTransformerTest.php
+16Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -141,6 +141,22 @@ public function testTransformWithDifferentPatterns()
141141
$this->assertEquals('02*2010*03 04|05|06', $transformer->transform($this->dateTime));
142142
}
143143

144+
public function testTransformDateTimeImmutableTimezones()
145+
{
146+
if (PHP_VERSION_ID < 50500) {
147+
$this->markTestSkipped('DateTimeImmutable was introduced in PHP 5.5.0');
148+
}
149+
150+
$transformer = new DateTimeToLocalizedStringTransformer('America/New_York', 'Asia/Hong_Kong');
151+
152+
$input = new \DateTimeImmutable('2010-02-03 04:05:06 America/New_York');
153+
154+
$dateTime = clone $input;
155+
$dateTime = $dateTime->setTimezone(new \DateTimeZone('Asia/Hong_Kong'));
156+
157+
$this->assertEquals($dateTime->format('d.m.Y H:i'), $transformer->transform($input));
158+
}
159+
144160
/**
145161
* @expectedException \Symfony\Component\Form\Exception\TransformationFailedException
146162
*/

‎src/Symfony/Component/Form/Tests/Extension/Core/DataTransformer/DateTimeToRfc3339TransformerTest.php

Copy file name to clipboardExpand all lines: src/Symfony/Component/Form/Tests/Extension/Core/DataTransformer/DateTimeToRfc3339TransformerTest.php
+14Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -79,6 +79,20 @@ public function testTransform($fromTz, $toTz, $from, $to)
7979
$this->assertSame($to, $transformer->transform(null !== $from ? new \DateTime($from) : null));
8080
}
8181

82+
/**
83+
* @dataProvider transformProvider
84+
*/
85+
public function testTransformDateTimeImmutable($fromTz, $toTz, $from, $to)
86+
{
87+
if (PHP_VERSION_ID < 50500) {
88+
$this->markTestSkipped('DateTimeImmutable was introduced in PHP 5.5.0');
89+
}
90+
91+
$transformer = new DateTimeToRfc3339Transformer($fromTz, $toTz);
92+
93+
$this->assertSame($to, $transformer->transform(null !== $from ? new \DateTimeImmutable($from) : null));
94+
}
95+
8296
/**
8397
* @expectedException \Symfony\Component\Form\Exception\TransformationFailedException
8498
*/

‎src/Symfony/Component/Form/Tests/Extension/Core/DataTransformer/DateTimeToStringTransformerTest.php

Copy file name to clipboardExpand all lines: src/Symfony/Component/Form/Tests/Extension/Core/DataTransformer/DateTimeToStringTransformerTest.php
+15Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -97,6 +97,21 @@ public function testTransformWithDifferentTimezones()
9797
$this->assertEquals($output, $transformer->transform($input));
9898
}
9999

100+
public function testTransformDateTimeImmutable()
101+
{
102+
if (PHP_VERSION_ID < 50500) {
103+
$this->markTestSkipped('DateTimeImmutable was introduced in PHP 5.5.0');
104+
}
105+
106+
$transformer = new DateTimeToStringTransformer('Asia/Hong_Kong', 'America/New_York', 'Y-m-d H:i:s');
107+
108+
$input = new \DateTimeImmutable('2010-02-03 12:05:06 America/New_York');
109+
$output = $input->format('Y-m-d H:i:s');
110+
$input = $input->setTimezone(new \DateTimeZone('Asia/Hong_Kong'));
111+
112+
$this->assertEquals($output, $transformer->transform($input));
113+
}
114+
100115
public function testTransformExpectsDateTime()
101116
{
102117
$transformer = new DateTimeToStringTransformer();

‎src/Symfony/Component/Form/Tests/Extension/Core/DataTransformer/DateTimeToTimestampTransformerTest.php

Copy file name to clipboardExpand all lines: src/Symfony/Component/Form/Tests/Extension/Core/DataTransformer/DateTimeToTimestampTransformerTest.php
+15Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -56,6 +56,21 @@ public function testTransformFromDifferentTimezone()
5656
$this->assertEquals($output, $transformer->transform($input));
5757
}
5858

59+
public function testTransformDateTimeImmutable()
60+
{
61+
if (PHP_VERSION_ID < 50500) {
62+
$this->markTestSkipped('DateTimeImmutable was introduced in PHP 5.5.0');
63+
}
64+
65+
$transformer = new DateTimeToTimestampTransformer('Asia/Hong_Kong', 'America/New_York');
66+
67+
$input = new \DateTimeImmutable('2010-02-03 04:05:06 America/New_York');
68+
$output = $input->format('U');
69+
$input = $input->setTimezone(new \DateTimeZone('Asia/Hong_Kong'));
70+
71+
$this->assertEquals($output, $transformer->transform($input));
72+
}
73+
5974
public function testTransformExpectsDateTime()
6075
{
6176
$transformer = new DateTimeToTimestampTransformer();

0 commit comments

Comments
0 (0)
Morty Proxy This is a proxified and sanitized view of the page, visit original site.