Unverified Commit 792c5b5e authored by Sergei Morozov's avatar Sergei Morozov Committed by GitHub

Merge pull request #2579 from galeaspablo/fix/date_interval_type

DateIntervalType (negative support) resolves doctrine/dbal#2578
parents 61c5e4e3 7c975933
......@@ -3,12 +3,15 @@
namespace Doctrine\DBAL\Types;
use Doctrine\DBAL\Platforms\AbstractPlatform;
use function substr;
/**
* Type that maps interval string to a PHP DateInterval Object.
*/
class DateIntervalType extends Type
{
public const FORMAT = '%RP%YY%MM%DDT%HH%IM%SS';
/**
* {@inheritdoc}
*/
......@@ -38,7 +41,7 @@ class DateIntervalType extends Type
}
if ($value instanceof \DateInterval) {
return $value->format('P%YY%MM%DDT%HH%IM%SS');
return $value->format(self::FORMAT);
}
throw ConversionException::conversionFailedInvalidType($value, $this->getName(), ['null', 'DateInterval']);
......@@ -54,9 +57,15 @@ class DateIntervalType extends Type
}
try {
return new \DateInterval($value);
$interval = new \DateInterval(substr($value, 1));
if (substr($value, 0, 1) === '-') {
$interval->invert = 1;
}
return $interval;
} catch (\Exception $exception) {
throw ConversionException::conversionFailedFormat($value, $this->getName(), 'P%YY%MM%DDT%HH%IM%SS', $exception);
throw ConversionException::conversionFailedFormat($value, $this->getName(), self::FORMAT, $exception);
}
}
......
......@@ -2,10 +2,13 @@
namespace Doctrine\Tests\DBAL\Types;
use Doctrine\DBAL\Types\ConversionException;
use Doctrine\DBAL\Types\DateIntervalType;
use Doctrine\DBAL\Types\Type;
use Doctrine\Tests\DBAL\Mocks\MockPlatform;
use Doctrine\Tests\DbalTestCase;
class DateIntervalTest extends \Doctrine\Tests\DbalTestCase
final class DateIntervalTest extends DbalTestCase
{
/**
* @var MockPlatform
......@@ -20,38 +23,58 @@ class DateIntervalTest extends \Doctrine\Tests\DbalTestCase
/**
* {@inheritDoc}
*/
protected function setUp()
protected function setUp() : void
{
$this->platform = new MockPlatform();
$this->type = Type::getType('dateinterval');
self::assertInstanceOf('Doctrine\DBAL\Types\DateIntervalType', $this->type);
self::assertInstanceOf(DateIntervalType::class, $this->type);
}
public function testDateIntervalConvertsToDatabaseValue()
public function testDateIntervalConvertsToDatabaseValue() : void
{
$interval = new \DateInterval('P2Y1DT1H2M3S');
$expected = 'P02Y00M01DT01H02M03S';
$expected = '+P02Y00M01DT01H02M03S';
$actual = $this->type->convertToDatabaseValue($interval, $this->platform);
self::assertEquals($expected, $actual);
}
public function testDateIntervalConvertsToPHPValue()
public function testDateIntervalConvertsToPHPValue() : void
{
$date = $this->type->convertToPHPValue('P02Y00M01DT01H02M03S', $this->platform);
self::assertInstanceOf('DateInterval', $date);
self::assertEquals('P02Y00M01DT01H02M03S', $date->format('P%YY%MM%DDT%HH%IM%SS'));
$interval = $this->type->convertToPHPValue('+P02Y00M01DT01H02M03S', $this->platform);
self::assertInstanceOf(\DateInterval::class, $interval);
self::assertEquals('+P02Y00M01DT01H02M03S', $interval->format(DateIntervalType::FORMAT));
}
public function testInvalidDateIntervalFormatConversion()
public function testNegativeDateIntervalConvertsToDatabaseValue() : void
{
$this->expectException('Doctrine\DBAL\Types\ConversionException');
$interval = new \DateInterval('P2Y1DT1H2M3S');
$interval->invert = 1;
$actual = $this->type->convertToDatabaseValue($interval, $this->platform);
self::assertEquals('-P02Y00M01DT01H02M03S', $actual);
}
public function testNegativeDateIntervalConvertsToPHPValue() : void
{
$interval = $this->type->convertToPHPValue('-P02Y00M01DT01H02M03S', $this->platform);
self::assertInstanceOf(\DateInterval::class, $interval);
self::assertEquals('-P02Y00M01DT01H02M03S', $interval->format(DateIntervalType::FORMAT));
}
public function testInvalidDateIntervalFormatConversion() : void
{
$this->expectException(ConversionException::class);
$this->type->convertToPHPValue('abcdefg', $this->platform);
}
public function testDateIntervalNullConversion()
public function testDateIntervalNullConversion() : void
{
self::assertNull($this->type->convertToPHPValue(null, $this->platform));
}
......@@ -59,19 +82,17 @@ class DateIntervalTest extends \Doctrine\Tests\DbalTestCase
/**
* @group DBAL-1288
*/
public function testRequiresSQLCommentHint()
public function testRequiresSQLCommentHint() : void
{
self::assertTrue($this->type->requiresSQLCommentHint($this->platform));
}
/**
* @dataProvider invalidPHPValuesProvider
*
* @param mixed $value
*/
public function testInvalidTypeConversionToDatabaseValue($value)
public function testInvalidTypeConversionToDatabaseValue($value) : void
{
$this->expectException('Doctrine\DBAL\Types\ConversionException');
$this->expectException(ConversionException::class);
$this->type->convertToDatabaseValue($value, $this->platform);
}
......@@ -79,7 +100,7 @@ class DateIntervalTest extends \Doctrine\Tests\DbalTestCase
/**
* @return mixed[][]
*/
public function invalidPHPValuesProvider()
public function invalidPHPValuesProvider() : array
{
return [
[0],
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment