Commit cc2d5038 authored by Bill Schaller's avatar Bill Schaller

Merge pull request #854 from v-bartusevicius/DateIntervalType

DateInterval Type
parents 8f0b6b70 47c259fe
......@@ -289,6 +289,15 @@ without date, time and timezone 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.
dateinterval
^^^^^^^^^^^^
Maps and converts date and time difference data without timezone information.
If you know that the data to be stored is the difference between two date and time values,
you should consider using this type.
Values retrieved from the database are always converted to PHP's ``\DateInterval`` object
or ``null`` if no data is present.
.. note::
See the `Known Vendor Issue <./known-vendor-issues>`_ section
......
<?php
namespace Doctrine\DBAL\Types;
use Doctrine\DBAL\Platforms\AbstractPlatform;
/**
* Type that maps interval string to a PHP DateInterval Object.
*/
class DateIntervalType extends Type
{
/**
* {@inheritdoc}
*/
public function getName()
{
return Type::DATEINTERVAL;
}
/**
* {@inheritdoc}
*/
public function getSQLDeclaration(array $fieldDeclaration, AbstractPlatform $platform)
{
$fieldDeclaration['length'] = 20;
$fieldDeclaration['fixed'] = true;
return $platform->getVarcharTypeDeclarationSQL($fieldDeclaration);
}
/**
* {@inheritdoc}
*/
public function convertToDatabaseValue($value, AbstractPlatform $platform)
{
$spec = null;
if ($value !== null) {
/** @var \DateInterval $value */
$spec = 'P'
. str_pad($value->y, 4, '0', STR_PAD_LEFT) . '-'
. $value->format('%M') . '-'
. $value->format('%D') . 'T'
. $value->format('%H') . ':'
. $value->format('%I') . ':'
. $value->format('%S')
;
}
return $spec;
}
/**
* {@inheritdoc}
*/
public function convertToPHPValue($value, AbstractPlatform $platform)
{
if ($value === null || $value instanceof \DateInterval) {
return $value;
}
try {
$interval = new \DateInterval($value);
} catch (\Exception $e) {
throw ConversionException::conversionFailedFormat($value, $this->getName(), 'PY-m-dTH:i:s');
}
return $interval;
}
}
......@@ -52,6 +52,7 @@ abstract class Type
const BLOB = 'blob';
const FLOAT = 'float';
const GUID = 'guid';
const DATEINTERVAL = 'dateinterval';
/**
* Map of already instantiated type objects. One instance per type (flyweight).
......@@ -85,6 +86,7 @@ abstract class Type
self::BINARY => 'Doctrine\DBAL\Types\BinaryType',
self::BLOB => 'Doctrine\DBAL\Types\BlobType',
self::GUID => 'Doctrine\DBAL\Types\GuidType',
self::DATEINTERVAL => 'Doctrine\DBAL\Types\DateIntervalType',
);
/**
......
<?php
namespace Doctrine\Tests\DBAL\Types;
use Doctrine\DBAL\Types\Type;
use Doctrine\Tests\DBAL\Mocks\MockPlatform;
class DateIntervalTest extends \Doctrine\Tests\DbalTestCase
{
protected
$_platform,
$_type;
protected function setUp()
{
$this->_platform = new MockPlatform();
$this->_type = Type::getType('dateinterval');
}
public function testDateIntervalConvertsToDatabaseValue()
{
$interval = new \DateInterval('P2Y1DT1H2M3S');
$expected = 'P0002-00-01T01:02:03';
$actual = $this->_type->convertToDatabaseValue($interval, $this->_platform);
$this->assertEquals($expected, $actual);
}
public function testDateIntervalConvertsToPHPValue()
{
$date = $this->_type->convertToPHPValue('P0002-00-01T01:02:03', $this->_platform);
$this->assertInstanceOf('DateInterval', $date);
$this->assertEquals('P2Y0M1DT1H2M3S', $date->format('P%yY%mM%dDT%hH%iM%sS'));
}
public function testInvalidDateIntervalFormatConversion()
{
$this->setExpectedException('Doctrine\DBAL\Types\ConversionException');
$this->_type->convertToPHPValue('abcdefg', $this->_platform);
}
public function testDateIntervalNullConversion()
{
$this->assertNull($this->_type->convertToPHPValue(null, $this->_platform));
}
}
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