1<?php
2
3namespace Doctrine\DBAL\Types;
4
5use DateInterval;
6use Doctrine\DBAL\Platforms\AbstractPlatform;
7use Throwable;
8
9use function substr;
10
11/**
12 * Type that maps interval string to a PHP DateInterval Object.
13 */
14class DateIntervalType extends Type
15{
16    public const FORMAT = '%RP%YY%MM%DDT%HH%IM%SS';
17
18    /**
19     * {@inheritdoc}
20     */
21    public function getName()
22    {
23        return Types::DATEINTERVAL;
24    }
25
26    /**
27     * {@inheritdoc}
28     */
29    public function getSQLDeclaration(array $column, AbstractPlatform $platform)
30    {
31        $column['length'] = 255;
32
33        return $platform->getVarcharTypeDeclarationSQL($column);
34    }
35
36    /**
37     * {@inheritdoc}
38     */
39    public function convertToDatabaseValue($value, AbstractPlatform $platform)
40    {
41        if ($value === null) {
42            return null;
43        }
44
45        if ($value instanceof DateInterval) {
46            return $value->format(self::FORMAT);
47        }
48
49        throw ConversionException::conversionFailedInvalidType($value, $this->getName(), ['null', 'DateInterval']);
50    }
51
52    /**
53     * {@inheritdoc}
54     */
55    public function convertToPHPValue($value, AbstractPlatform $platform)
56    {
57        if ($value === null || $value instanceof DateInterval) {
58            return $value;
59        }
60
61        $negative = false;
62
63        if (isset($value[0]) && ($value[0] === '+' || $value[0] === '-')) {
64            $negative = $value[0] === '-';
65            $value    = substr($value, 1);
66        }
67
68        try {
69            $interval = new DateInterval($value);
70
71            if ($negative) {
72                $interval->invert = 1;
73            }
74
75            return $interval;
76        } catch (Throwable $exception) {
77            throw ConversionException::conversionFailedFormat($value, $this->getName(), self::FORMAT, $exception);
78        }
79    }
80
81    /**
82     * {@inheritdoc}
83     */
84    public function requiresSQLCommentHint(AbstractPlatform $platform)
85    {
86        return true;
87    }
88}
89