Skip to content

Commit cfcc9a7

Browse files
committed
properly parse dates before the Gregorian calendar
1 parent fb4d928 commit cfcc9a7

File tree

2 files changed

+21
-2
lines changed

2 files changed

+21
-2
lines changed

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

+10-2
Original file line numberDiff line numberDiff line change
@@ -85,7 +85,8 @@ public function transform($dateTime)
8585
throw new TransformationFailedException('Expected a \DateTimeInterface.');
8686
}
8787

88-
$value = $this->getIntlDateFormatter()->format($dateTime->getTimestamp());
88+
$timestamp = $this->getCalendarConvertingFormatter()->parse($dateTime->format('Y-m-d H:i:s'));
89+
$value = $this->getIntlDateFormatter()->format($timestamp);
8990

9091
if (0 != intl_get_error_code()) {
9192
throw new TransformationFailedException(intl_get_error_message());
@@ -130,7 +131,7 @@ public function reverseTransform($value)
130131
try {
131132
if ($dateOnly) {
132133
// we only care about year-month-date, which has been delivered as a timestamp pointing to UTC midnight
133-
$dateTime = new \DateTime(gmdate('Y-m-d', $timestamp), new \DateTimeZone($this->outputTimezone));
134+
$dateTime = new \DateTime($this->getCalendarConvertingFormatter()->format($timestamp), new \DateTimeZone($this->outputTimezone));
134135
} else {
135136
// read timestamp into DateTime object - the formatter delivers a timestamp
136137
$dateTime = new \DateTime(sprintf('@%s', $timestamp));
@@ -199,4 +200,11 @@ protected function isPatternDateOnly()
199200
// check for the absence of time-related placeholders
200201
return 0 === preg_match('#[ahHkKmsSAzZOvVxX]#', $pattern);
201202
}
203+
204+
private function getCalendarConvertingFormatter()
205+
{
206+
$timezone = $this->isPatternDateOnly() ? 'UTC' : $this->inputTimezone;
207+
208+
return new \IntlDateFormatter(\Locale::getDefault(), \IntlDateFormatter::MEDIUM, \IntlDateFormatter::NONE, new \DateTimeZone($timezone), \IntlDateFormatter::GREGORIAN, 'yyyy-MM-dd HH:mm:ss');
209+
}
202210
}

src/Symfony/Component/Form/Tests/Extension/Core/Type/DateTypeTest.php

+11
Original file line numberDiff line numberDiff line change
@@ -1015,4 +1015,15 @@ public function provideEmptyData()
10151015
'Compound choice fields' => ['choice', ['year' => '2018', 'month' => '11', 'day' => '11'], $expectedData],
10161016
];
10171017
}
1018+
1019+
public function testSubmitDateBeforeBeginningOfGregorianCalendar()
1020+
{
1021+
$form = $this->factory->create(static::TESTED_TYPE, null, [
1022+
'widget' => 'single_text',
1023+
]);
1024+
$form->submit('950-12-19');
1025+
1026+
$this->assertSame('0950-12-19', $form->getData()->format('Y-m-d'));
1027+
$this->assertSame('0950-12-19', $form->getViewData());
1028+
}
10181029
}

0 commit comments

Comments
 (0)