Created
March 21, 2019 15:17
-
-
Save romaricdrigon/2b2345d5d1bbced5d1332fe110738532 to your computer and use it in GitHub Desktop.
Exemple de type Doctrine pour stocker des dates avec timezone sous MySQL
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| <?php | |
| namespace App\Type; | |
| use Doctrine\DBAL\Platforms\AbstractPlatform; | |
| use Doctrine\DBAL\Types\ConversionException; | |
| use Doctrine\DBAL\Types\Type; | |
| class DateTimeImmutableUtcType extends Type | |
| { | |
| public function getSQLDeclaration(array $fieldDeclaration, AbstractPlatform $platform) | |
| { | |
| return $platform->getDateTimeTypeDeclarationSQL($fieldDeclaration); | |
| } | |
| public function convertToDatabaseValue($value, AbstractPlatform $platform) | |
| { | |
| if (null === $value) { | |
| return $value; | |
| } | |
| if (!$value instanceof \DateTimeImmutable) { | |
| throw ConversionException::conversionFailedInvalidType($value, $this->getName(), ['null', 'DateTimeImmutable']); | |
| } | |
| if ('UTC' !== $value->getTimeZone()->getName()) { | |
| throw new \Exception(sprintf('DateTime TimeZone should be set to UTC, got %s instead', $value->getTimeZone()->getName())); | |
| } | |
| return $value->format($platform->getDateTimeFormatString()); | |
| } | |
| public function convertToPHPValue($value, AbstractPlatform $platform) | |
| { | |
| if ($value === null || $value instanceof \DateTimeImmutable) { | |
| return $value; | |
| } | |
| $utcValue = \DateTimeImmutable::createFromFormat($platform->getDateTimeFormatString(), $value, new \DateTimeZone('UTC')); | |
| if (!$utcValue) { | |
| throw ConversionException::conversionFailedFormat($value, $this->getName(), $platform->getDateTimeFormatString()); | |
| } | |
| return $utcValue; | |
| } | |
| public function getName() | |
| { | |
| return 'datetime_immutable_utc'; | |
| } | |
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| # config/packages/doctrine.yaml ou bien app/config/config.yml | |
| doctrine: | |
| dbal: | |
| types: | |
| datetime_immutable_utc: App\Type\DateTimeImmutableUtcType |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| <?php | |
| namespace App\Entity; | |
| use Doctrine\ORM\Mapping as ORM; | |
| /** | |
| * @ORM\Entity() | |
| */ | |
| class Event | |
| { | |
| // ... | |
| /** | |
| * @ORM\Column(type="datetime_immutable_utc") | |
| */ | |
| private $datetimeUtc; | |
| /** | |
| * @ORM\Column(type="string") | |
| */ | |
| private $timezone; | |
| public function setLocalDateTime(\DateTimeImmutable $dateTime): self | |
| { | |
| // On doit toujours convertir! | |
| $dateTimeUtc = $dateTime->setTimezone(new \DateTimeZone('UTC')); | |
| $this->datetimeUtc = $dateTimeUtc; | |
| $this->timezone = $dateTime->getTimezone()->getName(); | |
| } | |
| public function getLocalDateTime(): \DateTimeImmutable | |
| { | |
| // On doit toujours repasser par un timestamp pour convertir. | |
| $timestampUtc = $this->datetimeUtc->getTimestamp(); | |
| return \DateTimeImmutable::create('@'.$timestampUtc, new \DateTimeZone($this->timezone)); | |
| } | |
| // Pas besoin de getter/setter sur $timezone, c'est même déconseillé. | |
| // Par contre on peut autoriser l'accès à la date UTC brute, sans risque de mauvaises manipulations. | |
| public function getDateTimeUtc(): \DateTimeImmutable | |
| { | |
| return $this->datetimeUtc; | |
| } | |
| } |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment