Skip to content

Commit 0ef5968

Browse files
authored
Merge pull request #31 from sitegeist/bugfix/RFC3339_EXTENDED
BUGFIX: Denormalize RFC3339_EXTENDED the same way as RFC_3339
2 parents e51d885 + 93d1d17 commit 0ef5968

File tree

2 files changed

+68
-14
lines changed

2 files changed

+68
-14
lines changed

Classes/Domain/Schema/SchemaDenormalizer.php

Lines changed: 26 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -114,14 +114,20 @@ private static function convertValueObject(array|int|float|string|bool $value, s
114114
protected static function convertDateTime(array|float|bool|int|string $value, ?\ReflectionParameter $reflectionParameter = null): \DateTime
115115
{
116116
$propertyAttribute = $reflectionParameter ? StringProperty::tryFromReflectionParameter($reflectionParameter) : null;
117-
$format = match ($propertyAttribute?->format) {
118-
StringProperty::FORMAT_DATE => 'Y-m-d',
119-
default => \DateTimeInterface::RFC3339
120-
};
121-
$converted = match (true) {
122-
is_string($value) => \DateTime::createFromFormat($format, $value),
123-
default => false,
117+
$formats = match ($propertyAttribute?->format) {
118+
StringProperty::FORMAT_DATE => ['Y-m-d'],
119+
default => [\DateTimeInterface::RFC3339, \DateTimeInterface::RFC3339_EXTENDED]
124120
};
121+
if (is_string($value)) {
122+
foreach ($formats as $format) {
123+
$converted = \DateTime::createFromFormat($format, $value);
124+
if ($converted instanceof \DateTime) {
125+
break;
126+
}
127+
}
128+
} else {
129+
$converted = false;
130+
}
125131
if ($converted === false) {
126132
throw new \DomainException('Can only denormalize \DateTime from an RFC 3339 string');
127133
}
@@ -137,14 +143,20 @@ protected static function convertDateTime(array|float|bool|int|string $value, ?\
137143
protected static function convertDateTimeImmutable(array|float|bool|int|string $value, ?\ReflectionParameter $reflectionParameter = null): \DateTimeImmutable
138144
{
139145
$propertyAttribute = $reflectionParameter ? StringProperty::tryFromReflectionParameter($reflectionParameter) : null;
140-
$format = match ($propertyAttribute?->format) {
141-
StringProperty::FORMAT_DATE => 'Y-m-d',
142-
default => \DateTimeInterface::RFC3339
143-
};
144-
$converted = match (true) {
145-
is_string($value) => \DateTimeImmutable::createFromFormat($format, $value),
146-
default => false,
146+
$formats = match ($propertyAttribute?->format) {
147+
StringProperty::FORMAT_DATE => ['Y-m-d'],
148+
default => [\DateTimeInterface::RFC3339, \DateTimeInterface::RFC3339_EXTENDED]
147149
};
150+
if (is_string($value)) {
151+
foreach ($formats as $format) {
152+
$converted = \DateTimeImmutable::createFromFormat($format, $value);
153+
if ($converted instanceof \DateTimeImmutable) {
154+
break;
155+
}
156+
}
157+
} else {
158+
$converted = false;
159+
}
148160
if ($converted === false) {
149161
throw new \DomainException('Can only denormalize \DateTimeImmutable from an RFC 3339 string');
150162
}

Tests/Unit/Domain/Schema/SchemaNormalizerTest.php

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44

55
namespace Sitegeist\SchemeOnYou\Tests\Unit\Domain\Schema;
66

7+
use Neos\Flow\Reflection\ParameterReflection;
78
use PHPUnit\Framework\Assert;
89
use PHPUnit\Framework\TestCase;
910
use Sitegeist\SchemeOnYou\Domain\Schema\SchemaDenormalizer;
@@ -241,4 +242,45 @@ public static function valueNormalizationPairs(): iterable
241242
]
242243
];
243244
}
245+
246+
public static function dateNormalizationAndDenormalizationDateProvider(): \Generator
247+
{
248+
yield "default" => [
249+
'2010-01-28T15:00:00+02:00',
250+
'2010-01-28T15:00:00+02:00',
251+
'2010-01-28T15:00:00+02:00'
252+
];
253+
yield "with microseconds" => [
254+
'2025-07-08T09:37:07.937+02:00',
255+
'2025-07-08T09:37:07.937+02:00',
256+
'2025-07-08T09:37:07+02:00'
257+
];
258+
}
259+
260+
/**
261+
* @dataProvider dateNormalizationAndDenormalizationDateProvider
262+
* @test
263+
*/
264+
public function dateTimeImmutableNormalizationAndDenormalization(string $normalized, string $denormalized, string $renormalized): void
265+
{
266+
$expectedDate = new \DateTimeImmutable($denormalized);
267+
$denormalizedDate = SchemaDenormalizer::denormalizeValue($normalized, \DateTimeImmutable::class);
268+
$renormalizedDate = SchemaNormalizer::normalizeValue($denormalizedDate);
269+
Assert::assertEquals($expectedDate, $denormalizedDate);
270+
Assert::assertEquals($renormalized, $renormalizedDate);
271+
}
272+
273+
/**
274+
* @dataProvider dateNormalizationAndDenormalizationDateProvider
275+
* @test
276+
*/
277+
public function dateTimeNormalizationAndDenormalization(string $normalized, string $denormalized, string $renormalized): void
278+
{
279+
280+
$expectedDate = new \DateTime($denormalized);
281+
$denormalizedDate = SchemaDenormalizer::denormalizeValue($normalized, \DateTime::class);
282+
$renormalizedDate = SchemaNormalizer::normalizeValue($denormalizedDate);
283+
Assert::assertEquals($expectedDate, $denormalizedDate);
284+
Assert::assertEquals($renormalized, $renormalizedDate);
285+
}
244286
}

0 commit comments

Comments
 (0)