Skip to content

Commit

Permalink
Narrow responsibilities in datetime related types
Browse files Browse the repository at this point in the history
  • Loading branch information
phansys committed Apr 18, 2023
1 parent 1265f8c commit 3731555
Show file tree
Hide file tree
Showing 9 changed files with 154 additions and 54 deletions.
18 changes: 15 additions & 3 deletions docs/en/reference/types.rst
Original file line number Diff line number Diff line change
Expand Up @@ -278,13 +278,19 @@ or ``null`` if no data is present.
could cause quite some troubles on platforms that had various
microtime precision formats.
Starting with 2.5 whenever the parsing of a date fails with
the predefined platform format, the ``date_create()``
function will be used to parse the date.
the predefined platform format, ``DateTime::__construct()``
method will be used to parse the date.

This could cause some troubles when your date format is weird
and not parsed correctly by ``date_create()``, however since
and not parsed correctly by ``DateTime::__construct()``, however since
databases are rather strict on dates there should be no problem.

.. warning::

Passing instances of ``DateTimeImmutable`` to this type is deprecated since 3.7. Use
:ref:`datetime_immutable` instead.

.. _datetime_immutable:
datetime_immutable
^^^^^^^^^^^^^^^^^^

Expand All @@ -301,6 +307,12 @@ information, you should consider using this type.
Values retrieved from the database are always converted to PHP's ``\DateTime`` object
or ``null`` if no data is present.

.. warning::

Passing instances of ``DateTimeImmutable`` to this type is deprecated since 3.7. Use
:ref:`datetimetz_immutable` instead.

.. _datetimetz_immutable:
datetimetz_immutable
^^^^^^^^^^^^^^^^^^^^

Expand Down
2 changes: 1 addition & 1 deletion src/Types/DateIntervalType.php
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,7 @@ public function convertToDatabaseValue($value, AbstractPlatform $platform)
return $value->format(self::FORMAT);
}

throw ConversionException::conversionFailedInvalidType($value, $this->getName(), ['null', 'DateInterval']);
throw ConversionException::conversionFailedInvalidType($value, $this->getName(), ['null', DateInterval::class]);
}

/**
Expand Down
22 changes: 11 additions & 11 deletions src/Types/DateTimeImmutableType.php
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,7 @@
use DateTimeImmutable;
use Doctrine\DBAL\Platforms\AbstractPlatform;
use Doctrine\Deprecations\Deprecation;

use function date_create_immutable;
use Throwable;

/**
* Immutable type of {@see DateTimeType}.
Expand Down Expand Up @@ -65,15 +64,16 @@ public function convertToPHPValue($value, AbstractPlatform $platform)
$dateTime = DateTimeImmutable::createFromFormat($platform->getDateTimeFormatString(), $value);

if ($dateTime === false) {
$dateTime = date_create_immutable($value);
}

if ($dateTime === false) {
throw ConversionException::conversionFailedFormat(
$value,
$this->getName(),
$platform->getDateTimeFormatString(),
);
try {
$dateTime = new DateTimeImmutable($value);
} catch (Throwable $e) {
throw ConversionException::conversionFailedFormat(
$value,
$this->getName(),
$platform->getDateTimeFormatString(),
$e,
);
}
}

return $dateTime;
Expand Down
54 changes: 40 additions & 14 deletions src/Types/DateTimeType.php
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,13 @@
namespace Doctrine\DBAL\Types;

use DateTime;
use DateTimeImmutable;
use DateTimeInterface;
use Doctrine\DBAL\Platforms\AbstractPlatform;
use Doctrine\Deprecations\Deprecation;
use Throwable;

use function date_create;
use function get_class;

/**
* Type that maps an SQL DATETIME/TIMESTAMP to a PHP DateTime object.
Expand Down Expand Up @@ -45,10 +48,23 @@ public function convertToDatabaseValue($value, AbstractPlatform $platform)
}

if ($value instanceof DateTimeInterface) {
if (! $value instanceof Datetime) {
Deprecation::triggerIfCalledFromOutside(
'doctrine/dbal',
'https://github.com/doctrine/dbal/pull/6017',
'Passing an instance of %s is deprecated.',
get_class($value),
);
}

return $value->format($platform->getDateTimeFormatString());
}

throw ConversionException::conversionFailedInvalidType($value, $this->getName(), ['null', 'DateTime']);
throw ConversionException::conversionFailedInvalidType(
$value,
$this->getName(),
['null', DateTime::class, DateTimeImmutable::class],
);
}

/**
Expand All @@ -63,23 +79,33 @@ public function convertToDatabaseValue($value, AbstractPlatform $platform)
public function convertToPHPValue($value, AbstractPlatform $platform)
{
if ($value === null || $value instanceof DateTimeInterface) {
if ($value !== null && ! $value instanceof Datetime) {
Deprecation::triggerIfCalledFromOutside(
'doctrine/dbal',
'https://github.com/doctrine/dbal/pull/6017',
'Passing an instance of %s is deprecated.',
get_class($value),
);
}

return $value;
}

$val = DateTime::createFromFormat($platform->getDateTimeFormatString(), $value);

if ($val === false) {
$val = date_create($value);
}
$dateTime = DateTime::createFromFormat($platform->getDateTimeFormatString(), $value);

if ($val === false) {
throw ConversionException::conversionFailedFormat(
$value,
$this->getName(),
$platform->getDateTimeFormatString(),
);
if ($dateTime === false) {
try {
$dateTime = new DateTime($value);
} catch (Throwable $e) {
throw ConversionException::conversionFailedFormat(
$value,
$this->getName(),
$platform->getDateTimeFormatString(),
$e,
);
}
}

return $val;
return $dateTime;
}
}
29 changes: 25 additions & 4 deletions src/Types/DateTimeTzType.php
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,9 @@
use DateTime;
use DateTimeInterface;
use Doctrine\DBAL\Platforms\AbstractPlatform;
use Doctrine\Deprecations\Deprecation;

use function get_class;

/**
* DateTime type saving additional timezone information.
Expand Down Expand Up @@ -56,13 +59,22 @@ public function convertToDatabaseValue($value, AbstractPlatform $platform)
}

if ($value instanceof DateTimeInterface) {
if (! $value instanceof Datetime) {
Deprecation::triggerIfCalledFromOutside(
'doctrine/dbal',
'https://github.com/doctrine/dbal/pull/6017',
'Passing an instance of %s is deprecated.',
get_class($value),
);
}

return $value->format($platform->getDateTimeTzFormatString());
}

throw ConversionException::conversionFailedInvalidType(
$value,
$this->getName(),
['null', 'DateTime'],
['null', DateTime::class],
);
}

Expand All @@ -78,18 +90,27 @@ public function convertToDatabaseValue($value, AbstractPlatform $platform)
public function convertToPHPValue($value, AbstractPlatform $platform)
{
if ($value === null || $value instanceof DateTimeInterface) {
if ($value !== null && ! $value instanceof Datetime) {
Deprecation::triggerIfCalledFromOutside(
'doctrine/dbal',
'https://github.com/doctrine/dbal/pull/6017',
'Passing an instance of %s is deprecated.',
get_class($value),
);
}

return $value;
}

$val = DateTime::createFromFormat($platform->getDateTimeTzFormatString(), $value);
if ($val === false) {
$dateTime = DateTime::createFromFormat($platform->getDateTimeTzFormatString(), $value);
if ($dateTime === false) {
throw ConversionException::conversionFailedFormat(
$value,
$this->getName(),
$platform->getDateTimeTzFormatString(),
);
}

return $val;
return $dateTime;
}
}
29 changes: 25 additions & 4 deletions src/Types/DateType.php
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,9 @@
use DateTime;
use DateTimeInterface;
use Doctrine\DBAL\Platforms\AbstractPlatform;
use Doctrine\Deprecations\Deprecation;

use function get_class;

/**
* Type that maps an SQL DATE to a PHP Date object.
Expand Down Expand Up @@ -43,10 +46,19 @@ public function convertToDatabaseValue($value, AbstractPlatform $platform)
}

if ($value instanceof DateTimeInterface) {
if (! $value instanceof Datetime) {
Deprecation::triggerIfCalledFromOutside(
'doctrine/dbal',
'https://github.com/doctrine/dbal/pull/6017',
'Passing an instance of %s is deprecated.',
get_class($value),
);
}

return $value->format($platform->getDateFormatString());
}

throw ConversionException::conversionFailedInvalidType($value, $this->getName(), ['null', 'DateTime']);
throw ConversionException::conversionFailedInvalidType($value, $this->getName(), ['null', DateTime::class]);
}

/**
Expand All @@ -61,18 +73,27 @@ public function convertToDatabaseValue($value, AbstractPlatform $platform)
public function convertToPHPValue($value, AbstractPlatform $platform)
{
if ($value === null || $value instanceof DateTimeInterface) {
if ($value !== null && ! $value instanceof Datetime) {
Deprecation::triggerIfCalledFromOutside(
'doctrine/dbal',
'https://github.com/doctrine/dbal/pull/6017',
'Passing an instance of %s is deprecated.',
get_class($value),
);
}

return $value;
}

$val = DateTime::createFromFormat('!' . $platform->getDateFormatString(), $value);
if ($val === false) {
$dateTime = DateTime::createFromFormat('!' . $platform->getDateFormatString(), $value);
if ($dateTime === false) {
throw ConversionException::conversionFailedFormat(
$value,
$this->getName(),
$platform->getDateFormatString(),
);
}

return $val;
return $dateTime;
}
}
29 changes: 25 additions & 4 deletions src/Types/TimeType.php
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,9 @@
use DateTime;
use DateTimeInterface;
use Doctrine\DBAL\Platforms\AbstractPlatform;
use Doctrine\Deprecations\Deprecation;

use function get_class;

/**
* Type that maps an SQL TIME to a PHP DateTime object.
Expand Down Expand Up @@ -43,10 +46,19 @@ public function convertToDatabaseValue($value, AbstractPlatform $platform)
}

if ($value instanceof DateTimeInterface) {
if (! $value instanceof Datetime) {
Deprecation::triggerIfCalledFromOutside(
'doctrine/dbal',
'https://github.com/doctrine/dbal/pull/6017',
'Passing an instance of %s is deprecated.',
get_class($value),
);
}

return $value->format($platform->getTimeFormatString());
}

throw ConversionException::conversionFailedInvalidType($value, $this->getName(), ['null', 'DateTime']);
throw ConversionException::conversionFailedInvalidType($value, $this->getName(), ['null', DateTime::class]);
}

/**
Expand All @@ -61,18 +73,27 @@ public function convertToDatabaseValue($value, AbstractPlatform $platform)
public function convertToPHPValue($value, AbstractPlatform $platform)
{
if ($value === null || $value instanceof DateTimeInterface) {
if ($value !== null && ! $value instanceof Datetime) {
Deprecation::triggerIfCalledFromOutside(
'doctrine/dbal',
'https://github.com/doctrine/dbal/pull/6017',
'Passing an instance of %s is deprecated.',
get_class($value),
);
}

return $value;
}

$val = DateTime::createFromFormat('!' . $platform->getTimeFormatString(), $value);
if ($val === false) {
$dateTime = DateTime::createFromFormat('!' . $platform->getTimeFormatString(), $value);
if ($dateTime === false) {
throw ConversionException::conversionFailedFormat(
$value,
$this->getName(),
$platform->getTimeFormatString(),
);
}

return $val;
return $dateTime;
}
}
11 changes: 5 additions & 6 deletions src/Types/VarDateTimeImmutableType.php
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,7 @@
use DateTimeImmutable;
use Doctrine\DBAL\Platforms\AbstractPlatform;
use Doctrine\Deprecations\Deprecation;

use function date_create_immutable;
use Throwable;

/**
* Immutable type of {@see VarDateTimeType}.
Expand Down Expand Up @@ -62,10 +61,10 @@ public function convertToPHPValue($value, AbstractPlatform $platform)
return $value;
}

$dateTime = date_create_immutable($value);

if ($dateTime === false) {
throw ConversionException::conversionFailed($value, $this->getName());
try {
$dateTime = new DateTimeImmutable($value);
} catch (Throwable $e) {
throw ConversionException::conversionFailed($value, $this->getName(), $e);
}

return $dateTime;
Expand Down
Loading

0 comments on commit 3731555

Please sign in to comment.