Symfony 6, Doctrine, DateTime and microseconds
Fabian Blechschmidt
Not tested in production
This is not tested on a stage or production environment yet – and I’m sure I forget to remove this warning, once it is properly tested. Feel free to write a comment, so we can update this post 🙂
Doctrine isn’t yet able to handle microseconds , if I understand correctly, especially because they are not sure how to handle the on the difference database management systems.
But thankfully it is relatively simple to implement our own type (or overwrite the datetime type).
Implement your own type
Thanks to flauschi , I was able to adapt his code for our purpose (especially without using Carbon)
<?php
declare(strict_types=1);
namespace Winkelwagen\Dbal;
use Doctrine\DBAL\Platforms\AbstractPlatform;
use Doctrine\DBAL\Platforms\PostgreSQLPlatform;
use Doctrine\DBAL\Types\ConversionException;
use Doctrine\DBAL\Types\Type;
class DateTimeWithMicroseconds extends Type
{
private const TYPENAME = 'datetime';
public function getSQLDeclaration(array $column, AbstractPlatform $platform): string
{
if (isset($column['version']) && $column['version'] === true) {
return 'TIMESTAMP';
}
if ($platform instanceof PostgreSqlPlatform) {
return 'TIMESTAMP(6) WITHOUT TIME ZONE';
}
return 'DATETIME(6)';
}
public function convertToPHPValue($value, AbstractPlatform $platform): mixed
{
if ($value === null || $value instanceof \DateTimeInterface) {
return $value;
}
if (str_contains($value, '.')) {
return \DateTimeImmutable::createFromFormat('Y-m-d H:i:s.u', $value);
}
return \DateTimeImmutable::createFromFormat('Y-m-d H:i:s', $value);
}
public function convertToDatabaseValue($value, AbstractPlatform $platform): mixed
{
if (null === $value) {
return null;
}
if ($value instanceof \DateTimeInterface) {
return $value->format('Y-m-d H:i:s.u');
}
throw ConversionException::conversionFailedInvalidType(
$value,
$this->getName(),
['null', 'DateTime']
);
}
public function getName(): string
{
return self::TYPENAME;
}
public function requiresSQLCommentHint(AbstractPlatform $platform): bool
{
return true;
}
}
With this class and the following configuration, you are set:
# config/packages/doctrine.yaml
doctrine:
dbal:
types:
datetime: \Paddox\Dbal\DateTimeWithMicroseconds
To change the name of the type, you need to change the YAML key and the PHP constant.
gist with everything
https://gist.github.com/Schrank/d1f3243e47e52bc20809a3c20cd0441a
Other articles from this category
PHPStorm/IDEA, composer updates and 100% CPU
In one of our projects PHPStorm ran a while on 100% CPU, an investigation showed, that the process „checking for available composer updates“ ran and used all the resources. Most likely it got stuck somewhere. To get rid of the problem, one can turn off this feature. In IDEA Ultimate here: [Settings] -> Languages & […]
Custom Fields, dots and MySQL’s JSON_EXTRACT
We all know custom fields – hopefully – at least this is not about the basics. You can add custom fields to nearly all entites: orders, products, categories, … You can name them whatever you like, e.g. pluginname.property – but using dots . in your custom field name is a bad idea, because then you […]
gpg failed to sign the data
I was doing some work, when suddenly my git failed to commit changed. I dig a little around, asked StackOverflow but it didn’t help. Finally when running the commit manually and not through PHPStorm I got a proper error: Ah! The key is expired! Got it. Did you know you can extend a GPG key? […]