Skip to content

Commit

Permalink
Merge pull request #908 from yob-yob/nanoseconds
Browse files Browse the repository at this point in the history
Casting DateTimeInterface: Truncate nanoseconds to microseconds (first 6 digits) / with Tests
  • Loading branch information
rubenvanassche authored Jan 17, 2025
2 parents b0e006f + 0a3dd50 commit dd536e0
Show file tree
Hide file tree
Showing 2 changed files with 66 additions and 0 deletions.
5 changes: 5 additions & 0 deletions src/Casts/DateTimeInterfaceCast.php
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,11 @@ protected function castValue(
return Uncastable::create();
}

// Truncate nanoseconds to microseconds (first 6 digits)
// Input: 2024-12-02T16:20:15.969827247Z
$value = preg_replace('/\.(\d{6})\d*Z$/', '.$1Z', $value);
// Output: 2024-12-02T16:20:15.969827Z

/** @var DateTimeInterface|null $datetime */
$datetime = $formats
->map(fn (string $format) => rescue(fn () => $type::createFromFormat(
Expand Down
61 changes: 61 additions & 0 deletions tests/Casts/DateTimeInterfaceCastTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -281,3 +281,64 @@ public function __construct(
->and($data::from(['date' => '2022-05-16 17:00:00']))->toArray()
->toMatchArray(['date' => '2022-05-16T17:00:00+00:00']);
});


it('can cast date times with nanosecond precision by truncating nanoseconds to microseconds', function () {
$caster = new DateTimeInterfaceCast("Y-m-d\TH:i:s.u\Z");

$class = new class () {
public Carbon $carbon;

public CarbonImmutable $carbonImmutable;

public DateTime $dateTime;

public DateTimeImmutable $dateTimeImmutable;
};


expect(
$caster->cast(
FakeDataStructureFactory::property($class, 'carbon'),
'2024-12-02T16:20:15.969827247Z',
[],
CreationContextFactory::createFromConfig($class::class)->get()
)
)->toEqual(new Carbon('2024-12-02T16:20:15.969827247Z'));

expect(
$caster->cast(
FakeDataStructureFactory::property($class, 'carbonImmutable'),
'2024-12-02T16:20:15.969827247Z',
[],
CreationContextFactory::createFromConfig($class::class)->get()
)
)->toEqual(new CarbonImmutable('2024-12-02T16:20:15.969827247Z'));

expect(
$caster->cast(
FakeDataStructureFactory::property($class, 'dateTime'),
'2024-12-02T16:20:15.969827247Z',
[],
CreationContextFactory::createFromConfig($class::class)->get()
)
)->toEqual(new DateTime('2024-12-02T16:20:15.969827247Z'));

expect(
$caster->cast(
FakeDataStructureFactory::property($class, 'dateTimeImmutable'),
'2024-12-02T16:20:15.969827247Z',
[],
CreationContextFactory::createFromConfig($class::class)->get()
)
)->toEqual(new DateTimeImmutable('2024-12-02T16:20:15.969827247Z'));

expect(
$caster->cast(
FakeDataStructureFactory::property($class, 'dateTimeImmutable'),
'2024-12-02T16:20:15.969827247Z',
[],
CreationContextFactory::createFromConfig($class::class)->get()
)
)->toEqual(new DateTimeImmutable('2024-12-02T16:20:15.969827247Z'));
});

0 comments on commit dd536e0

Please sign in to comment.