Skip to content

DateTime objects are serialized as strings #304

@bpolaszek

Description

@bpolaszek

Currently, datetime objects are serialized as strings, i.e. 2023-11-29T00:00:00+00:00.
This prevents date fields from being filterable (by range).
Aren't they supposed to be serialized as unix timestamp (integers)?

As a workaround I did this:

use Doctrine\ORM\Mapping as ORM;
use Symfony\Component\Serializer\Annotation as Serializer;
use Symfony\Component\Serializer\Normalizer\DateTimeNormalizer;

class MyEntity {
    // ...
    
    #[ORM\Column(type: Types::DATE_IMMUTABLE, nullable: true)]
    #[Serializer\Context([DateTimeNormalizer::FORMAT_KEY => 'U'])]
    public ?DateTimeImmutable $releasedAt = null;
}

It works, except timestamps are rendered as strings, not integers.
To fix this, I created a custom DateTime normalizer:

use DateTimeInterface;
use Symfony\Component\Serializer\Normalizer\DateTimeNormalizer;
use Symfony\Component\Serializer\Normalizer\NormalizerInterface;

final readonly class UnixTimestampNormalizer implements NormalizerInterface
{
    public function __construct(
        private DateTimeNormalizer $normalizer = new DateTimeNormalizer(),
    ) {
    }

    public function normalize(mixed $object, string $format = null, array $context = []): int
    {
        return (int) $this->normalizer->normalize($object, $format, $context);
    }

    public function supportsNormalization(mixed $data, string $format = null, array $context = []): bool
    {
        return $data instanceof DateTimeInterface
            && 'U' === ($context[DateTimeNormalizer::FORMAT_KEY] ?? null);
    }
}

But this is a little tricky, it would be better if proper serializing could be done out of the box.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions