Skip to content

Commit ea9afa2

Browse files
authored
Merge pull request #98 from oddevan/deserialize-datetimeinterface
Use DateTimeImmutable if type is DateTimeInterface
2 parents 5895ade + 6a48277 commit ea9afa2

File tree

5 files changed

+42
-1
lines changed

5 files changed

+42
-1
lines changed

CHANGELOG.md

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,23 @@ All notable changes to `Serde` will be documented in this file.
44

55
Updates should follow the [Keep a CHANGELOG](http://keepachangelog.com/) principles.
66

7+
## Unreleased
8+
9+
### Added
10+
- Nothing
11+
12+
### Deprecated
13+
- Nothing
14+
15+
### Fixed
16+
- A PHP type hint of `DateTimeInterface` will now deserialize to a `DateTimeImmutable` object instead of throwing an error.
17+
18+
### Removed
19+
- Nothing
20+
21+
### Security
22+
- Nothing
23+
724
## 1.5.0 - 2025-07-15
825

926
### Added

README.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -566,6 +566,8 @@ Will serialize to this JSON:
566566
}
567567
```
568568

569+
Note that a type of `DateTimeInterface` will deserialize to a `DateTimeImmutable` object.
570+
569571
#### `timezone`
570572

571573
The `timezone` argument may be any timezone string legal in PHP, such as `America/Chicago` or `UTC`. If specified, the value will be cast to this timezone first before it is serialized. If not specified, the value will be left in whatever timezone it is in before being serialized. Whether that makes a difference to the output depends on the `format`.

src/PropertyHandler/DateTimeExporter.php

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -68,7 +68,10 @@ public function importValue(Deserializer $deserializer, Field $field, mixed $sou
6868
// an opt-in/out flag to restrict the format on import should be added
6969
// to DateField to get used here. Until then, this will do.
7070

71-
return new ($field->phpType)($string);
71+
// If the PHP type is a DateTimeInterface, fulfill that with a DateTimeImmutable.
72+
$type = ($field->phpType === \DateTimeInterface::class) ? \DateTimeImmutable::class : $field->phpType;
73+
74+
return new ($type)($string);
7275
}
7376

7477
public function canImport(Field $field, string $format): bool
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
namespace Crell\Serde\Records;
6+
7+
use DateTimeInterface;
8+
9+
class DateTimeInterfaceExample {
10+
public function __construct(
11+
public DateTimeInterface $interfaceProperty,
12+
) {}
13+
}

tests/SerdeTestCases.php

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@
2626
use Crell\Serde\Records\ClassWithReducibleProperty;
2727
use Crell\Serde\Records\CompoundTypes;
2828
use Crell\Serde\Records\DateTimeExample;
29+
use Crell\Serde\Records\DateTimeInterfaceExample;
2930
use Crell\Serde\Records\DictionaryKeyTypes;
3031
use Crell\Serde\Records\Drupal\EmailItem;
3132
use Crell\Serde\Records\Drupal\FieldItemList;
@@ -339,6 +340,11 @@ public static function round_trip_examples(): iterable
339340
arrayMap: ['a' => [1, 2, 3]],
340341
),
341342
];
343+
yield 'datetimeinterface_type' => [
344+
'data' => new DateTimeInterfaceExample(
345+
interfaceProperty: new \DateTimeImmutable('2025-12-25 12:34:56.789'),
346+
),
347+
];
342348
}
343349

344350
public static function value_object_flatten_examples(): \Generator

0 commit comments

Comments
 (0)