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 19, 2023
1 parent 9d601a1 commit 2d57b7a
Show file tree
Hide file tree
Showing 11 changed files with 192 additions and 73 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
14 changes: 7 additions & 7 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 @@ -64,19 +63,20 @@ public function convertToPHPValue($value, AbstractPlatform $platform)

$dateTime = DateTimeImmutable::createFromFormat($platform->getDateTimeFormatString(), $value);

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

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

return $dateTime;
}

/**
Expand Down
46 changes: 38 additions & 8 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 @@ -44,11 +47,26 @@ public function convertToDatabaseValue($value, AbstractPlatform $platform)
return $value;
}

if ($value instanceof DateTimeImmutable) {
Deprecation::triggerIfCalledFromOutside(
'doctrine/dbal',
'https://github.com/doctrine/dbal/pull/6017',
'Passing an instance of %s is deprecated, use %s::%s() instead.',
get_class($value),
DateTimeImmutableType::class,
__FUNCTION__,
);
}

if ($value instanceof DateTimeInterface) {
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 @@ -62,24 +80,36 @@ public function convertToDatabaseValue($value, AbstractPlatform $platform)
*/
public function convertToPHPValue($value, AbstractPlatform $platform)
{
if ($value instanceof DateTimeImmutable) {
Deprecation::triggerIfCalledFromOutside(
'doctrine/dbal',
'https://github.com/doctrine/dbal/pull/6017',
'Passing an instance of %s is deprecated, use %s::%s() instead.',
get_class($value),
DateTimeImmutableType::class,
__FUNCTION__,
);
}

if ($value === null || $value instanceof DateTimeInterface) {
return $value;
}

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

if ($val === false) {
$val = date_create($value);
if ($dateTime !== false) {
return $dateTime;
}

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

return $val;
}
}
14 changes: 7 additions & 7 deletions src/Types/DateTimeTzImmutableType.php
Original file line number Diff line number Diff line change
Expand Up @@ -62,15 +62,15 @@ public function convertToPHPValue($value, AbstractPlatform $platform)

$dateTime = DateTimeImmutable::createFromFormat($platform->getDateTimeTzFormatString(), $value);

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

return $dateTime;
throw ConversionException::conversionFailedFormat(
$value,
$this->getName(),
$platform->getDateTimeTzFormatString(),
);
}

/**
Expand Down
44 changes: 35 additions & 9 deletions src/Types/DateTimeTzType.php
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,12 @@
namespace Doctrine\DBAL\Types;

use DateTime;
use DateTimeImmutable;
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 @@ -55,14 +59,25 @@ public function convertToDatabaseValue($value, AbstractPlatform $platform)
return $value;
}

if ($value instanceof DateTimeImmutable) {
Deprecation::triggerIfCalledFromOutside(
'doctrine/dbal',
'https://github.com/doctrine/dbal/pull/6017',
'Passing an instance of %s is deprecated, use %s::%s() instead.',
get_class($value),
DateTimeTzImmutableType::class,
__FUNCTION__,
);
}

if ($value instanceof DateTimeInterface) {
return $value->format($platform->getDateTimeTzFormatString());
}

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

Expand All @@ -77,19 +92,30 @@ public function convertToDatabaseValue($value, AbstractPlatform $platform)
*/
public function convertToPHPValue($value, AbstractPlatform $platform)
{
if ($value instanceof DateTimeImmutable) {
Deprecation::triggerIfCalledFromOutside(
'doctrine/dbal',
'https://github.com/doctrine/dbal/pull/6017',
'Passing an instance of %s is deprecated, use %s::%s() instead.',
get_class($value),
DateTimeTzImmutableType::class,
__FUNCTION__,
);
}

if ($value === null || $value instanceof DateTimeInterface) {
return $value;
}

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

return $val;
throw ConversionException::conversionFailedFormat(
$value,
$this->getName(),
$platform->getDateTimeTzFormatString(),
);
}
}
44 changes: 35 additions & 9 deletions src/Types/DateType.php
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,12 @@
namespace Doctrine\DBAL\Types;

use DateTime;
use DateTimeImmutable;
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 +47,21 @@ public function convertToDatabaseValue($value, AbstractPlatform $platform)
}

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

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

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

/**
Expand All @@ -60,19 +75,30 @@ public function convertToDatabaseValue($value, AbstractPlatform $platform)
*/
public function convertToPHPValue($value, AbstractPlatform $platform)
{
if ($value instanceof DateTimeImmutable) {
Deprecation::triggerIfCalledFromOutside(
'doctrine/dbal',
'https://github.com/doctrine/dbal/pull/6017',
'Passing an instance of %s is deprecated, use %s::%s() instead.',
get_class($value),
DateImmutableType::class,
__FUNCTION__,
);
}

if ($value === null || $value instanceof DateTimeInterface) {
return $value;
}

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

return $val;
throw ConversionException::conversionFailedFormat(
$value,
$this->getName(),
$platform->getDateFormatString(),
);
}
}
14 changes: 7 additions & 7 deletions src/Types/TimeImmutableType.php
Original file line number Diff line number Diff line change
Expand Up @@ -62,15 +62,15 @@ public function convertToPHPValue($value, AbstractPlatform $platform)

$dateTime = DateTimeImmutable::createFromFormat('!' . $platform->getTimeFormatString(), $value);

if ($dateTime === false) {
throw ConversionException::conversionFailedFormat(
$value,
$this->getName(),
$platform->getTimeFormatString(),
);
if ($dateTime !== false) {
return $dateTime;
}

return $dateTime;
throw ConversionException::conversionFailedFormat(
$value,
$this->getName(),
$platform->getTimeFormatString(),
);
}

/**
Expand Down
Loading

0 comments on commit 2d57b7a

Please sign in to comment.