8000 [Form] fix populating single widget time view data with different tim… · symfony/symfony@430f7c4 · GitHub
[go: up one dir, main page]

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 430f7c4

Browse files
xabbuhnicolas-grekas
authored andcommitted
[Form] fix populating single widget time view data with different timezones
1 parent 01a8e72 commit 430f7c4

File tree

3 files changed

+78
-4
lines changed

3 files changed

+78
-4
lines changed

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

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -47,12 +47,14 @@ class DateTimeToStringTransformer extends BaseDateTimeTransformer
4747
* @param string|null $inputTimezone The name of the input timezone
4848
* @param string|null $outputTimezone The name of the output timezone
4949
* @param string $format The date format
50+
* @param string|null $parseFormat The parse format when different from $format
5051
*/
51-
public function __construct(string $inputTimezone = null, string $outputTimezone = null, string $format = 'Y-m-d H:i:s')
52+
public function __construct(string $inputTimezone = null, string $outputTimezone = null, string $format = 'Y-m-d H:i:s', string $parseFormat = null)
5253
{
5354
parent::__construct($inputTimezone, $outputTimezone);
5455

55-
$this->generateFormat = $this->parseFormat = $format;
56+
$this->generateFormat = $format;
57+
$this->parseFormat = $parseFormat ?? $format;
5658

5759
// See https://php.net/datetime.createfromformat
5860
// The character "|" in the format makes sure that the parts of a date

src/Symfony/Component/Form/Extension/Core/Type/TimeType.php

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -73,8 +73,10 @@ public function buildForm(FormBuilderInterface $builder, array $options)
7373
}
7474
});
7575

76+
$parseFormat = null;
77+
7678
if (null !== $options['reference_date']) {
77-
$format = 'Y-m-d '.$format;
79+
$parseFormat = 'Y-m-d '.$format;
7880

7981
$builder->addEventListener(FormEvents::PRE_SUBMIT, function (FormEvent $event) use ($options) {
8082
$data = $event->getData();
@@ -85,7 +87,7 @@ public function buildForm(FormBuilderInterface $builder, array $options)
8587
});
8688
}
8789

88-
$builder->addViewTransformer(new DateTimeToStringTransformer($options['model_timezone'], $options['view_timezone'], $format));
90+
$builder->addViewTransformer(new DateTimeToStringTransformer($options['model_timezone'], $options['view_timezone'], $format, $parseFormat));
8991
} else {
9092
$hourOptions = $minuteOptions = $secondOptions = [
9193
'error_bubbling' => true,

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

Lines changed: 70 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -279,6 +279,76 @@ public function testSubmitWithSecondsAndBrowserOmissionSeconds()
279279
$this->assertEquals('03:04:00', $form->getViewData());
280280
}
281281

282+
public function testPreSetDataDifferentTimezones()
283+
{
284+
$form = $this->factory->create(static::TESTED_TYPE, null, [
285+
'model_timezone' => 'UTC',
286+
'view_timezone' => 'Europe/Berlin',
287+
'input' => 'datetime',
288+
'with_seconds' => true,
289+
'reference_date' => new \DateTimeImmutable('2019-01-01', new \DateTimeZone('UTC')),
290+
]);
291+
$form->setData(new \DateTime('2022-01-01 15:09:10', new \DateTimeZone('UTC')));
292+
293+
$this->assertSame('15:09:10', $form->getData()->format('H:i:s'));
294+
$this->assertSame([
295+
'hour' => '16',
296+
'minute' => '9',
297+
'second' => '10',
298+
], $form->getViewData());
299+
}
300+
301+
public function testPreSetDataDifferentTimezonesDuringDaylightSavingTime()
302+
{
303+
$form = $this->factory->create(static::TESTED_TYPE, null, [
304+
'model_timezone' => 'UTC',
305+
'view_timezone' => 'Europe/Berlin',
306+
'input' => 'datetime',
307+
'with_seconds' => true,
308+
'reference_date' => new \DateTimeImmutable('2019-07-12', new \DateTimeZone('UTC')),
309+
]);
310+
$form->setData(new \DateTime('2022-04-29 15:09:10', new \DateTimeZone('UTC')));
311+
312+
$this->assertSame('15:09:10', $form->getData()->format('H:i:s'));
313+
$this->assertSame([
314+
'hour' => '17',
315+
'minute' => '9',
316+
'second' => '10',
317+
], $form->getViewData());
318+
}
319+
320+
public function testPreSetDataDifferentTimezonesUsingSingleTextWidget()
321+
{
322+
$form = $this->factory->create(static::TESTED_TYPE, null, [
323+
'model_timezone' => 'UTC',
324+
'view_timezone' => 'Europe/Berlin',
325+
'input' => 'datetime',
326+
'with_seconds' => true,
327+
'reference_date' => new \DateTimeImmutable('2019-01-01', new \DateTimeZone('UTC')),
328+
'widget' => 'single_text',
329+
]);
330+
$form->setData(new \DateTime('2022-01-01 15:09:10', new \DateTimeZone('UTC')));
331+
332+
$this->assertSame('15:09:10', $form->getData()->format('H:i:s'));
333+
$this->assertSame('16:09:10', $form->getViewData());
334+
}
335+
336+
public function testPreSetDataDifferentTimezonesDuringDaylightSavingTimeUsingSingleTextWidget()
337+
{
338+
$form = $this->factory->create(static::TESTED_TYPE, null, [
339+
'model_timezone' => 'UTC',
340+
'view_timezone' => 'Europe/Berlin',
341+
'input' => 'datetime',
342+
'with_seconds' => true,
343+
'reference_date' => new \DateTimeImmutable('2019-07-12', new \DateTimeZone('UTC')),
344+
'widget' => 'single_text',
345+
]);
346+
$form->setData(new \DateTime('2022-04-29 15:09:10', new \DateTimeZone('UTC')));
347+
348+
$this->assertSame('15:09:10', $form->getData()->format('H:i:s'));
349+
$this->assertSame('17:09:10', $form->getViewData());
350+
}
351+
282352
public function testSubmitDifferentTimezones()
283353
{
284354
$form = $this->factory->create(static::TESTED_TYPE, null, [

0 commit comments

Comments
 (0)
0