Repository: briannesbitt/Carbon (PHP)

Issue:
CarbonTypeConverter broken with Doctrine/Dbal 3.7
<!--
    🛑 DON'T REMOVE ME.
    This issue template applies to all
      - bug reports,
      - feature proposals,
      - and documentation requests

    Having all those informations will allow us to know exactly
    what you expect and answer you faster and precisely (answer
    that matches your Carbon version, PHP version and usage).
    
    Note: Comments between <!- - and - -> won't appear in the final
    issue (See [Preview] tab).
-->
Hello,

I encountered an issue with the following code:
<!--
    ⚠️ Your code below (not the code from inside Carbon library)
    Be sure it's dependency-free and enough to reproduce the issue
    when we run it on:
    https://play.phpsandbox.io/embed/nesbot/carbon
-->
```sh
bin/console doctrine:migrations:diff
```

Carbon version: 2.71.0
<!--
    ⚠️ Run the command `composer show nesbot/carbon` to get "versions"
-->

PHP version: PHP 8.2.8

<!--
    Use `echo phpversion();`
    to get PHP version.

    Some issues can depends on your context, settings,
    macros, timezone, language. So to be sure the code
    you give is enough to reproduce your bug, try it
    first in:
    https://play.phpsandbox.io/embed/nesbot/carbon?input=%3C%3Fphp%0A%0Aecho%20Carbon%3A%3Aparse('2018-06-01')-%3EsubDay()-%3Emonth%3B

    You can use the [Options] button to change the version
    then when you get the bug with this editor, you can use
    the [Export] button, copy the link of the opened tab,
    then paste it in the issue. Then we can immediatly get
    your issue.
-->


I expected to get:

```
Success
```
<!--
    Always give your expectations. Each use has their owns.
    You may want daylight saving time to be taken into account,
    someone else want it to be ignored. You may want timezone
    to be used in comparisons, someone else may not, etc.
-->

But I actually get:

```
In CarbonTypeConverter.php line 39:
                                            
  Warning: Undefined array key "precision"  
```
<!--
    If you did not succeed to get the same result in
    https://play.phpsandbox.io/embed/nesbot/carbon?input=%3C%3Fphp%0A%0Aecho%20Carbon%3A%3Aparse('2018-06-01')%3B then precise the
    result you get.
-->

Thanks!



Discussion: Line 39 should use ?? instead of ? 
But 3.7.0 is bringing lot of preparation to 4.0, so it might bring more important change.

I had to go back to earlier version of DBAL.
That's a great news because in oldest versions of dbal, it was not possible to know if the precision was set to 0 or not set at all (so to use the default).

It would be great to take benefit of this enhancement and so to have behavior depending on the dbal version.
Hello can you try to `composer require "nesbot/carbon:dev-master as 2.72.0"`?



Fix (patch):
diff --git a/composer.json b/composer.json
index 7560763027..48366b5ddc 100644
--- a/composer.json
+++ b/composer.json
@@ -42,14 +42,15 @@
     "require": {
         "php": "^7.1.8 || ^8.0",
         "ext-json": "*",
+        "carbonphp/carbon-doctrine-types": "*",
         "psr/clock": "^1.0",
         "symfony/polyfill-mbstring": "^1.0",
         "symfony/polyfill-php80": "^1.16",
         "symfony/translation": "^3.4 || ^4.0 || ^5.0 || ^6.0"
     },
     "require-dev": {
-        "doctrine/dbal": "^2.0 || ^3.1.4",
-        "doctrine/orm": "^2.7",
+        "doctrine/dbal": "^2.0 || ^3.1.4 || ^4.0",
+        "doctrine/orm": "^2.7 || ^3.0",
         "friendsofphp/php-cs-fixer": "^3.0",
         "kylekatarnls/multi-tester": "^2.0",
         "ondrejmirtes/better-reflection": "*",
diff --git a/src/Carbon/Doctrine/CarbonDoctrineType.php b/src/Carbon/Doctrine/CarbonDoctrineType.php
deleted file mode 100644
index ccc457fcd2..0000000000
--- a/src/Carbon/Doctrine/CarbonDoctrineType.php
+++ /dev/null
@@ -1,23 +0,0 @@
-<?php
-
-/**
- * This file is part of the Carbon package.
- *
- * (c) Brian Nesbitt <brian@nesbot.com>
- *
- * For the full copyright and license information, please view the LICENSE
- * file that was distributed with this source code.
- */
-
-namespace Carbon\Doctrine;
-
-use Doctrine\DBAL\Platforms\AbstractPlatform;
-
-interface CarbonDoctrineType
-{
-    public function getSQLDeclaration(array $fieldDeclaration, AbstractPlatform $platform);
-
-    public function convertToPHPValue($value, AbstractPlatform $platform);
-
-    public function convertToDatabaseValue($value, AbstractPlatform $platform);
-}
diff --git a/src/Carbon/Doctrine/CarbonImmutableType.php b/src/Carbon/Doctrine/CarbonImmutableType.php
deleted file mode 100644
index bf476a77e5..0000000000
--- a/src/Carbon/Doctrine/CarbonImmutableType.php
+++ /dev/null
@@ -1,37 +0,0 @@
-<?php
-
-/**
- * This file is part of the Carbon package.
- *
- * (c) Brian Nesbitt <brian@nesbot.com>
- *
- * For the full copyright and license information, please view the LICENSE
- * file that was distributed with this source code.
- */
-
-namespace Carbon\Doctrine;
-
-use Doctrine\DBAL\Platforms\AbstractPlatform;
-
-class CarbonImmutableType extends DateTimeImmutableType implements CarbonDoctrineType
-{
-    /**
-     * {@inheritdoc}
-     *
-     * @return string
-     */
-    public function getName()
-    {
-        return 'carbon_immutable';
-    }
-
-    /**
-     * {@inheritdoc}
-     *
-     * @return bool
-     */
-    public function requiresSQLCommentHint(AbstractPlatform $platform)
-    {
-        return true;
-    }
-}
diff --git a/src/Carbon/Doctrine/CarbonType.php b/src/Carbon/Doctrine/CarbonType.php
deleted file mode 100644
index 9289d84d34..0000000000
--- a/src/Carbon/Doctrine/CarbonType.php
+++ /dev/null
@@ -1,37 +0,0 @@
-<?php
-
-/**
- * This file is part of the Carbon package.
- *
- * (c) Brian Nesbitt <brian@nesbot.com>
- *
- * For the full copyright and license information, please view the LICENSE
- * file that was distributed with this source code.
- */
-
-namespace Carbon\Doctrine;
-
-use Doctrine\DBAL\Platforms\AbstractPlatform;
-
-class CarbonType extends DateTimeType implements CarbonDoctrineType
-{
-    /**
-     * {@inheritdoc}
-     *
-     * @return string
-     */
-    public function getName()
-    {
-        return 'carbon';
-    }
-
-    /**
-     * {@inheritdoc}
-     *
-     * @return bool
-     */
-    public function requiresSQLCommentHint(AbstractPlatform $platform)
-    {
-        return true;
-    }
-}
diff --git a/src/Carbon/Doctrine/CarbonTypeConverter.php b/src/Carbon/Doctrine/CarbonTypeConverter.php
deleted file mode 100644
index ecfe17e793..0000000000
--- a/src/Carbon/Doctrine/CarbonTypeConverter.php
+++ /dev/null
@@ -1,123 +0,0 @@
-<?php
-
-/**
- * This file is part of the Carbon package.
- *
- * (c) Brian Nesbitt <brian@nesbot.com>
- *
- * For the full copyright and license information, please view the LICENSE
- * file that was distributed with this source code.
- */
-
-namespace Carbon\Doctrine;
-
-use Carbon\Carbon;
-use Carbon\CarbonInterface;
-use DateTimeInterface;
-use Doctrine\DBAL\Platforms\AbstractPlatform;
-use Doctrine\DBAL\Types\ConversionException;
-use Exception;
-
-/**
- * @template T of CarbonInterface
- */
-trait CarbonTypeConverter
-{
-    /**
-     * @return class-string<T>
-     */
-    protected function getCarbonClassName(): string
-    {
-        return Carbon::class;
-    }
-
-    /**
-     * @return string
-     */
-    public function getSQLDeclaration(array $fieldDeclaration, AbstractPlatform $platform)
-    {
-        $precision = $fieldDeclaration['precision'] ?: 10;
-
-        if ($fieldDeclaration['secondPrecision'] ?? false) {
-            $precision = 0;
-        }
-
-        if ($precision === 10) {
-            $precision = DateTimeDefaultPrecision::get();
-        }
-
-        $type = parent::getSQLDeclaration($fieldDeclaration, $platform);
-
-        if (!$precision) {
-            return $type;
-        }
-
-        if (str_contains($type, '(')) {
-            return preg_replace('/\(\d+\)/', "($precision)", $type);
-        }
-
-        [$before, $after] = explode(' ', "$type ");
-
-        return trim("$before($precision) $after");
-    }
-
-    /**
-     * @SuppressWarnings(PHPMD.UnusedFormalParameter)
-     *
-     * @return T|null
-     */
-    public function convertToPHPValue($value, AbstractPlatform $platform)
-    {
-        $class = $this->getCarbonClassName();
-
-        if ($value === null || is_a($value, $class)) {
-            return $value;
-        }
-
-        if ($value instanceof DateTimeInterface) {
-            return $class::instance($value);
-        }
-
-        $date = null;
-        $error = null;
-
-        try {
-            $date = $class::parse($value);
-        } catch (Exception $exception) {
-            $error = $exception;
-        }
-
-        if (!$date) {
-            throw ConversionException::conversionFailedFormat(
-                $value,
-                $this->getName(),
-                'Y-m-d H:i:s.u or any format supported by '.$class.'::parse()',
-                $error
-            );
-        }
-
-        return $date;
-    }
-
-    /**
-     * @SuppressWarnings(PHPMD.UnusedFormalParameter)
-     *
-     * @return string|null
-     */
-    public function convertToDatabaseValue($value, AbstractPlatform $platform)
-    {
-        if ($value === null) {
-            return $value;
-        }
-
-        if ($value instanceof DateTimeInterface) {
-            return $value->format('Y-m-d H:i:s.u');
-        }
-
-        throw ConversionException::conversionFailedInvalidType(
-            $value,
-            $this->getName(),
-            ['null', 'DateTime', 'Carbon']
-        );
-    }
-}
diff --git a/src/Carbon/Doctrine/DateTimeDefaultPrecision.php b/src/Carbon/Doctrine/DateTimeDefaultPrecision.php
deleted file mode 100644
index 642fd41354..0000000000
--- a/src/Carbon/Doctrine/DateTimeDefaultPrecision.php
+++ /dev/null
@@ -1,37 +0,0 @@
-<?php
-
-/**
- * This file is part of the Carbon package.
- *
- * (c) Brian Nesbitt <brian@nesbot.com>
- *
- * For the full copyright and license information, please view the LICENSE
- * file that was distributed with this source code.
- */
-
-namespace Carbon\Doctrine;
-
-class DateTimeDefaultPrecision
-{
-    private static $precision = 6;
-
-    /**
-     * Change the default Doctrine datetime and datetime_immutable precision.
-     *
-     * @param int $precision
-     */
-    public static function set(int $precision): void
-    {
-        self::$precision = $precision;
-    }
-
-    /**
-     * Get the default Doctrine datetime and datetime_immutable precision.
-     *
-     * @return int
-     */
-    public static function get(): int
-    {
-        return self::$precision;
-    }
-}
diff --git a/src/Carbon/Doctrine/DateTimeImmutableType.php b/src/Carbon/Doctrine/DateTimeImmutableType.php
deleted file mode 100644
index 499271031e..0000000000
--- a/src/Carbon/Doctrine/DateTimeImmutableType.php
+++ /dev/null
@@ -1,24 +0,0 @@
-<?php
-
-/**
- * Thanks to https://github.com/flaushi for his suggestion:
- * https://github.com/doctrine/dbal/issues/2873#issuecomment-534956358
- */
-namespace Carbon\Doctrine;
-
-use Carbon\CarbonImmutable;
-use Doctrine\DBAL\Types\VarDateTimeImmutableType;
-
-class DateTimeImmutableType extends VarDateTimeImmutableType implements CarbonDoctrineType
-{
-    /** @use CarbonTypeConverter<CarbonImmutable> */
-    use CarbonTypeConverter;
-
-    /**
-     * @return class-string<CarbonImmutable>
-     */
-    protected function getCarbonClassName(): string
-    {
-        return CarbonImmutable::class;
-    }
-}
diff --git a/src/Carbon/Doctrine/DateTimeType.php b/src/Carbon/Doctrine/DateTimeType.php
deleted file mode 100644
index 29b0bb955e..0000000000
--- a/src/Carbon/Doctrine/DateTimeType.php
+++ /dev/null
@@ -1,16 +0,0 @@
-<?php
-
-/**
- * Thanks to https://github.com/flaushi for his suggestion:
- * https://github.com/doctrine/dbal/issues/2873#issuecomment-534956358
- */
-namespace Carbon\Doctrine;
-
-use Carbon\Carbon;
-use Doctrine\DBAL\Types\VarDateTimeType;
-
-class DateTimeType extends VarDateTimeType implements CarbonDoctrineType
-{
-    /** @use CarbonTypeConverter<Carbon> */
-    use CarbonTypeConverter;
-}