diff --git a/src/Symfony/Component/Form/Extension/Core/DataTransformer/DateTimeToArrayTransformer.php b/src/Symfony/Component/Form/Extension/Core/DataTransformer/DateTimeToArrayTransformer.php index b3f4dbdd63..afbfc1041e 100644 --- a/src/Symfony/Component/Form/Extension/Core/DataTransformer/DateTimeToArrayTransformer.php +++ b/src/Symfony/Component/Form/Extension/Core/DataTransformer/DateTimeToArrayTransformer.php @@ -51,7 +51,7 @@ class DateTimeToArrayTransformer extends BaseDateTimeTransformer /** * Transforms a normalized date into a localized date. * - * @param \DateTime $dateTime Normalized date. + * @param \DateTime|\DateTimeInterface $dateTime A DateTime object * * @return array Localized date. * @@ -72,14 +72,17 @@ class DateTimeToArrayTransformer extends BaseDateTimeTransformer ), array_flip($this->fields)); } - if (!$dateTime instanceof \DateTime) { - throw new TransformationFailedException('Expected a \DateTime.'); + if (!$dateTime instanceof \DateTime && !$dateTime instanceof \DateTimeInterface) { + throw new TransformationFailedException('Expected a \DateTime or \DateTimeInterface.'); } - $dateTime = clone $dateTime; if ($this->inputTimezone !== $this->outputTimezone) { + if (!$dateTime instanceof \DateTimeImmutable) { + $dateTime = clone $dateTime; + } + try { - $dateTime->setTimezone(new \DateTimeZone($this->outputTimezone)); + $dateTime = $dateTime->setTimezone(new \DateTimeZone($this->outputTimezone)); } catch (\Exception $e) { throw new TransformationFailedException($e->getMessage(), $e->getCode(), $e); } diff --git a/src/Symfony/Component/Form/Extension/Core/DataTransformer/DateTimeToLocalizedStringTransformer.php b/src/Symfony/Component/Form/Extension/Core/DataTransformer/DateTimeToLocalizedStringTransformer.php index e7ebcabc7a..b38680a1bb 100644 --- a/src/Symfony/Component/Form/Extension/Core/DataTransformer/DateTimeToLocalizedStringTransformer.php +++ b/src/Symfony/Component/Form/Extension/Core/DataTransformer/DateTimeToLocalizedStringTransformer.php @@ -70,7 +70,7 @@ class DateTimeToLocalizedStringTransformer extends BaseDateTimeTransformer /** * Transforms a normalized date into a localized date string/array. * - * @param \DateTime $dateTime Normalized date. + * @param \DateTime|\DateTimeInterface $dateTime A DateTime object * * @return string|array Localized date string/array. * @@ -84,17 +84,11 @@ class DateTimeToLocalizedStringTransformer extends BaseDateTimeTransformer return ''; } - if (!$dateTime instanceof \DateTime) { - throw new TransformationFailedException('Expected a \DateTime.'); + if (!$dateTime instanceof \DateTime && !$dateTime instanceof \DateTimeInterface) { + throw new TransformationFailedException('Expected a \DateTime or \DateTimeInterface.'); } - // convert time to UTC before passing it to the formatter - $dateTime = clone $dateTime; - if ('UTC' !== $this->inputTimezone) { - $dateTime->setTimezone(new \DateTimeZone('UTC')); - } - - $value = $this->getIntlDateFormatter()->format((int) $dateTime->format('U')); + $value = $this->getIntlDateFormatter()->format($dateTime->getTimestamp()); if (intl_get_error_code() != 0) { throw new TransformationFailedException(intl_get_error_message()); diff --git a/src/Symfony/Component/Form/Extension/Core/DataTransformer/DateTimeToRfc3339Transformer.php b/src/Symfony/Component/Form/Extension/Core/DataTransformer/DateTimeToRfc3339Transformer.php index e3297ffef3..c78d80401a 100644 --- a/src/Symfony/Component/Form/Extension/Core/DataTransformer/DateTimeToRfc3339Transformer.php +++ b/src/Symfony/Component/Form/Extension/Core/DataTransformer/DateTimeToRfc3339Transformer.php @@ -27,13 +27,13 @@ class DateTimeToRfc3339Transformer extends BaseDateTimeTransformer return ''; } - if (!$dateTime instanceof \DateTime) { - throw new TransformationFailedException('Expected a \DateTime.'); + if (!$dateTime instanceof \DateTime && !$dateTime instanceof \DateTimeInterface) { + throw new TransformationFailedException('Expected a \DateTime or \DateTimeInterface.'); } if ($this->inputTimezone !== $this->outputTimezone) { $dateTime = clone $dateTime; - $dateTime->setTimezone(new \DateTimeZone($this->outputTimezone)); + $dateTime = $dateTime->setTimezone(new \DateTimeZone($this->outputTimezone)); } return preg_replace('/\+00:00$/', 'Z', $dateTime->format('c')); diff --git a/src/Symfony/Component/Form/Extension/Core/DataTransformer/DateTimeToStringTransformer.php b/src/Symfony/Component/Form/Extension/Core/DataTransformer/DateTimeToStringTransformer.php index 8fa1622a36..fdcfeee8ec 100644 --- a/src/Symfony/Component/Form/Extension/Core/DataTransformer/DateTimeToStringTransformer.php +++ b/src/Symfony/Component/Form/Extension/Core/DataTransformer/DateTimeToStringTransformer.php @@ -90,7 +90,7 @@ class DateTimeToStringTransformer extends BaseDateTimeTransformer * Transforms a DateTime object into a date string with the configured format * and timezone. * - * @param \DateTime $value A DateTime object + * @param \DateTime|\DateTimeInterface $dateTime A DateTime object * * @return string A value as produced by PHP's date() function * @@ -104,13 +104,16 @@ class DateTimeToStringTransformer extends BaseDateTimeTransformer return ''; } - if (!$value instanceof \DateTime) { - throw new TransformationFailedException('Expected a \DateTime.'); + if (!$value instanceof \DateTime && !$value instanceof \DateTimeInterface) { + throw new TransformationFailedException('Expected a \DateTime or \DateTimeInterface.'); + } + + if (!$value instanceof \DateTimeImmutable) { + $value = clone $value; } - $value = clone $value; try { - $value->setTimezone(new \DateTimeZone($this->outputTimezone)); + $value = $value->setTimezone(new \DateTimeZone($this->outputTimezone)); } catch (\Exception $e) { throw new TransformationFailedException($e->getMessage(), $e->getCode(), $e); } diff --git a/src/Symfony/Component/Form/Extension/Core/DataTransformer/DateTimeToTimestampTransformer.php b/src/Symfony/Component/Form/Extension/Core/DataTransformer/DateTimeToTimestampTransformer.php index bd51ea4195..b8f5f381a5 100644 --- a/src/Symfony/Component/Form/Extension/Core/DataTransformer/DateTimeToTimestampTransformer.php +++ b/src/Symfony/Component/Form/Extension/Core/DataTransformer/DateTimeToTimestampTransformer.php @@ -24,7 +24,7 @@ class DateTimeToTimestampTransformer extends BaseDateTimeTransformer /** * Transforms a DateTime object into a timestamp in the configured timezone. * - * @param \DateTime $value A \DateTime object + * @param \DateTime|\DateTimeInterface $dateTime A DateTime object * * @return int A timestamp * @@ -38,18 +38,11 @@ class DateTimeToTimestampTransformer extends BaseDateTimeTransformer return; } - if (!$value instanceof \DateTime) { - throw new TransformationFailedException('Expected a \DateTime.'); + if (!$value instanceof \DateTime && !$value instanceof \DateTimeInterface) { + throw new TransformationFailedException('Expected a \DateTime or \DateTimeInterface.'); } - $value = clone $value; - try { - $value->setTimezone(new \DateTimeZone($this->outputTimezone)); - } catch (\Exception $e) { - throw new TransformationFailedException($e->getMessage(), $e->getCode(), $e); - } - - return (int) $value->format('U'); + return $value->getTimestamp(); } /** diff --git a/src/Symfony/Component/Form/Tests/Extension/Core/DataTransformer/DateTimeToArrayTransformerTest.php b/src/Symfony/Component/Form/Tests/Extension/Core/DataTransformer/DateTimeToArrayTransformerTest.php index db5f2b1638..3042eea5a4 100644 --- a/src/Symfony/Component/Form/Tests/Extension/Core/DataTransformer/DateTimeToArrayTransformerTest.php +++ b/src/Symfony/Component/Form/Tests/Extension/Core/DataTransformer/DateTimeToArrayTransformerTest.php @@ -116,6 +116,30 @@ class DateTimeToArrayTransformerTest extends DateTimeTestCase $this->assertSame($output, $transformer->transform($input)); } + public function testTransformDateTimeImmutable() + { + if (PHP_VERSION_ID < 50500) { + $this->markTestSkipped('DateTimeImmutable was introduced in PHP 5.5.0'); + } + + $transformer = new DateTimeToArrayTransformer('America/New_York', 'Asia/Hong_Kong'); + + $input = new \DateTimeImmutable('2010-02-03 04:05:06 America/New_York'); + + $dateTime = new \DateTimeImmutable('2010-02-03 04:05:06 America/New_York'); + $dateTime = $dateTime->setTimezone(new \DateTimeZone('Asia/Hong_Kong')); + $output = array( + 'year' => (string) (int) $dateTime->format('Y'), + 'month' => (string) (int) $dateTime->format('m'), + 'day' => (string) (int) $dateTime->format('d'), + 'hour' => (string) (int) $dateTime->format('H'), + 'minute' => (string) (int) $dateTime->format('i'), + 'second' => (string) (int) $dateTime->format('s'), + ); + + $this->assertSame($output, $transformer->transform($input)); + } + /** * @expectedException \Symfony\Component\Form\Exception\TransformationFailedException */ diff --git a/src/Symfony/Component/Form/Tests/Extension/Core/DataTransformer/DateTimeToLocalizedStringTransformerTest.php b/src/Symfony/Component/Form/Tests/Extension/Core/DataTransformer/DateTimeToLocalizedStringTransformerTest.php index cb50fc3669..d6964d395a 100644 --- a/src/Symfony/Component/Form/Tests/Extension/Core/DataTransformer/DateTimeToLocalizedStringTransformerTest.php +++ b/src/Symfony/Component/Form/Tests/Extension/Core/DataTransformer/DateTimeToLocalizedStringTransformerTest.php @@ -141,6 +141,22 @@ class DateTimeToLocalizedStringTransformerTest extends DateTimeTestCase $this->assertEquals('02*2010*03 04|05|06', $transformer->transform($this->dateTime)); } + public function testTransformDateTimeImmutableTimezones() + { + if (PHP_VERSION_ID < 50500) { + $this->markTestSkipped('DateTimeImmutable was introduced in PHP 5.5.0'); + } + + $transformer = new DateTimeToLocalizedStringTransformer('America/New_York', 'Asia/Hong_Kong'); + + $input = new \DateTimeImmutable('2010-02-03 04:05:06 America/New_York'); + + $dateTime = clone $input; + $dateTime = $dateTime->setTimezone(new \DateTimeZone('Asia/Hong_Kong')); + + $this->assertEquals($dateTime->format('d.m.Y H:i'), $transformer->transform($input)); + } + /** * @expectedException \Symfony\Component\Form\Exception\TransformationFailedException */ diff --git a/src/Symfony/Component/Form/Tests/Extension/Core/DataTransformer/DateTimeToRfc3339TransformerTest.php b/src/Symfony/Component/Form/Tests/Extension/Core/DataTransformer/DateTimeToRfc3339TransformerTest.php index a39f53aa70..be3827cc74 100644 --- a/src/Symfony/Component/Form/Tests/Extension/Core/DataTransformer/DateTimeToRfc3339TransformerTest.php +++ b/src/Symfony/Component/Form/Tests/Extension/Core/DataTransformer/DateTimeToRfc3339TransformerTest.php @@ -79,6 +79,20 @@ class DateTimeToRfc3339TransformerTest extends DateTimeTestCase $this->assertSame($to, $transformer->transform(null !== $from ? new \DateTime($from) : null)); } + /** + * @dataProvider transformProvider + */ + public function testTransformDateTimeImmutable($fromTz, $toTz, $from, $to) + { + if (PHP_VERSION_ID < 50500) { + $this->markTestSkipped('DateTimeImmutable was introduced in PHP 5.5.0'); + } + + $transformer = new DateTimeToRfc3339Transformer($fromTz, $toTz); + + $this->assertSame($to, $transformer->transform(null !== $from ? new \DateTimeImmutable($from) : null)); + } + /** * @expectedException \Symfony\Component\Form\Exception\TransformationFailedException */ diff --git a/src/Symfony/Component/Form/Tests/Extension/Core/DataTransformer/DateTimeToStringTransformerTest.php b/src/Symfony/Component/Form/Tests/Extension/Core/DataTransformer/DateTimeToStringTransformerTest.php index a0aede7c85..e1099d9b35 100644 --- a/src/Symfony/Component/Form/Tests/Extension/Core/DataTransformer/DateTimeToStringTransformerTest.php +++ b/src/Symfony/Component/Form/Tests/Extension/Core/DataTransformer/DateTimeToStringTransformerTest.php @@ -97,6 +97,21 @@ class DateTimeToStringTransformerTest extends DateTimeTestCase $this->assertEquals($output, $transformer->transform($input)); } + public function testTransformDateTimeImmutable() + { + if (PHP_VERSION_ID < 50500) { + $this->markTestSkipped('DateTimeImmutable was introduced in PHP 5.5.0'); + } + + $transformer = new DateTimeToStringTransformer('Asia/Hong_Kong', 'America/New_York', 'Y-m-d H:i:s'); + + $input = new \DateTimeImmutable('2010-02-03 12:05:06 America/New_York'); + $output = $input->format('Y-m-d H:i:s'); + $input = $input->setTimezone(new \DateTimeZone('Asia/Hong_Kong')); + + $this->assertEquals($output, $transformer->transform($input)); + } + public function testTransformExpectsDateTime() { $transformer = new DateTimeToStringTransformer(); diff --git a/src/Symfony/Component/Form/Tests/Extension/Core/DataTransformer/DateTimeToTimestampTransformerTest.php b/src/Symfony/Component/Form/Tests/Extension/Core/DataTransformer/DateTimeToTimestampTransformerTest.php index b54f0c4c50..451451d09d 100644 --- a/src/Symfony/Component/Form/Tests/Extension/Core/DataTransformer/DateTimeToTimestampTransformerTest.php +++ b/src/Symfony/Component/Form/Tests/Extension/Core/DataTransformer/DateTimeToTimestampTransformerTest.php @@ -56,6 +56,21 @@ class DateTimeToTimestampTransformerTest extends DateTimeTestCase $this->assertEquals($output, $transformer->transform($input)); } + public function testTransformDateTimeImmutable() + { + if (PHP_VERSION_ID < 50500) { + $this->markTestSkipped('DateTimeImmutable was introduced in PHP 5.5.0'); + } + + $transformer = new DateTimeToTimestampTransformer('Asia/Hong_Kong', 'America/New_York'); + + $input = new \DateTimeImmutable('2010-02-03 04:05:06 America/New_York'); + $output = $input->format('U'); + $input = $input->setTimezone(new \DateTimeZone('Asia/Hong_Kong')); + + $this->assertEquals($output, $transformer->transform($input)); + } + public function testTransformExpectsDateTime() { $transformer = new DateTimeToTimestampTransformer();