Saving a Zend date in the database with Doctrine 2.1
Asked Answered
G

3

2

I want to save a datetime in the database which was created with the doctrine schema tool. In my form I set a date and time and i want to save it as a datetime in the database.

So i tried this:

$e->setStartDateTime(new Zend_Date('2011-09-01T22:00:00',Zend_date::DATETIME));

But i get the error:

PHP Fatal error:  Call to undefined method Zend_Date::format() in /var/www/shared/Doctrine/lib/vendor/doctrine-dbal/lib/Doctrine/DBAL/Types/DateTimeType.php on line 44

Does anyone have experience with this and able to help me with this problem?

Grazynagreabe answered 18/9, 2011 at 17:25 Comment(0)
A
4

Doctrine2 expects PHP DateTime objects for DQL date and datetime types.

If you are not forced to use a Zend_Date, to this:

->setStartDateTime(new DateTime('2011-09-01T22:00:00'))

Else, convert it to a DateTime:

new DateTime('@' . $zendDate->getTimestamp())

See DateTime docs.

Achromatize answered 18/9, 2011 at 17:30 Comment(1)
you have to use a backslash like this ... new \DateTime()... to use the global namespace.Petroglyph
T
5

You can override the native datatypes to use Zend_Date instead of PHP's native DateTime which is the default for Doctrine data types 'datetime', 'time', and 'date'.

First in your application Bootstrap file, add the following BEFORE you instantiate your Doctrine EntityManager. This code should come before any other Doctrine code:

Doctrine\DBAL\Types\Type::overrideType('datetime', 'yournamespace\types\DateTimeType');
Doctrine\DBAL\Types\Type::overrideType('date', 'yournamespace\types\DateType');
Doctrine\DBAL\Types\Type::overrideType('time', 'yournamespace\types\Time');

Now you simply need to implement the 3 classes. It's easiest to just extend the corresponding Doctrine classes to achieve this. The code is actually the same for all 3 classes, the only difference is the class you extend from and the name of your class. Here is the DateTimeType class as an example:

namespace yournamespace\type;

use Doctrine\DBAL\Types\DateTimeType as DoctrineDateTimeType;
use Doctrine\DBAL\Platforms\AbstractPlatform;

/**
 * Override 'datetime' type in Doctrine to use Zend_Date
 */
class DateTimeType extends DoctrineDateTimeType
{

    /**
     * Convert from db to Zend_Date
     *
     * @param string $value
     * @param AbstractPlatform $platform
     * @return \Zend_Date|null
     */
    public function convertToPhpValue($value, AbstractPlatform $platform)
    {
        if (is_null($value)) {
            return null;
        }
        \Zend_Date::setOptions(array('format_type' => 'php', ));
        $phpValue = new \Zend_Date($value, $platform->getDateTimeFormatString());
        \Zend_Date::setOptions(array('format_type' => 'iso', ));

        return $phpValue;
    }

    /**
     * Convert from Zend_Date to db
     *
     * @param string $value
     * @param AbstractPlatform $platform
     * @return string|null
     */
    public function convertToDatabaseValue($value, AbstractPlatform $platform)
    {
        if (is_null($value)) {
            return null;
        }
        \Zend_Date::setOptions(array('format_type' => 'php', ));
        $dbValue = $value->toString($platform->getDateTimeFormatString());
        \Zend_Date::setOptions(array('format_type' => 'iso', ));

        return $dbValue;
    }

}

Now you can still use @Column(type="datetime") annotations in Doctrine. When saving to the database, you can save entity properties of type "datetime" to Zend_Date instances. Also when grabbing entities out of the database, properties of type "datetime" will now be Zend_Dates.

Taimi answered 4/11, 2011 at 16:17 Comment(0)
A
4

Doctrine2 expects PHP DateTime objects for DQL date and datetime types.

If you are not forced to use a Zend_Date, to this:

->setStartDateTime(new DateTime('2011-09-01T22:00:00'))

Else, convert it to a DateTime:

new DateTime('@' . $zendDate->getTimestamp())

See DateTime docs.

Achromatize answered 18/9, 2011 at 17:30 Comment(1)
you have to use a backslash like this ... new \DateTime()... to use the global namespace.Petroglyph
M
3

You can implement a Custom Mapping Type or use this ZendDateType implementation.

You may find this guide helpful.

Medulla answered 19/9, 2011 at 7:53 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.