56

Could someone tell me how to add the default value on a DateTime column? I can't do it like this:

protected $registration_date = date("Y-m-d H:i:s", time()); 

So how can I handle it?

8 Answers 8

103

For default value CURRENT_TIMESTAMP:

 @ORM\Column(name="created_at", type="datetime", options={"default": "CURRENT_TIMESTAMP"}) 

Or for older Symfony versions:

 @ORM\Column(name="created_at", type="datetime", options={"default": 0}) 

Worked for me... However this works only with MySQL.

Sign up to request clarification or add additional context in comments.

11 Comments

This should be the top answer now IMO, especially if you want the table schema itself to assume CURRENT_TIMESTAMP
Thanks. This helped me a lot. I've used options={"default": "CURRENT_TIMESTAMP"}) before which generally worked aswell. But with my postgres db behind it it got transformed to DEFAULT NOW() which is the postgres way. But then a doctrine:migrations:diff would misinterpret the now() as a deviation from CURRENT_TIMESTAMP and create a diff file each time I run it. But with this solution doctrine gets that everything is in sync.
Great answer and, IMO, the cleanest way to do this. If it's of any interest this was translated as ADD date_added TIMESTAMP(0) WITHOUT TIME ZONE DEFAULT CURRENT_TIMESTAMP NOT NULL for me.
It is to mention, that this only works with MySQL >= 5.6.5 on below MySQL does not support setting CURRENT_TIMESTAMP as a default value for DATETIME columns. See stackoverflow.com/a/168832/4735939
This not work with mysql:5.7 SQLSTATE[42000]: Syntax error or access violation: 1067 Invalid default value for 'date_create'
|
66

You map your property as DateTime type then set the value in the constructor using a new DateTime instance:

/** * @Entity * @Table(name="...") */ class MyEntity { /** @Column(type="datetime") */ protected $registration_date; public function __construct() { $this->registration_date = new DateTime(); } } 

This works as the constructor of a persisted class is not called upon hydration.

2 Comments

I vote up for this answer because it is the pure PHP solution. Other answers may: 1) need special knowledge onPrePersistSetRegistrationDate which add HasLifecycleCallbacks, PrePersist annotations 2) I want to set a default value needs me to add 3rd library @Gedmo\Timestampable?!! 3) CURRENT_TIMESTAMP is sometimes not good. Ex.: when your script server in China but database server in America. ( of cause, it is not very common, but there are such cases )
@Yarco It depends on a case. When you have a table without a datetime column and then decides to add it - you need a default value to be populated for existing table rows. In this case PHP solution will not work.
62

You can also use lifecycle callbacks if you want to be very precise:

use Doctrine\ORM\Mapping as ORM; /** * @ORM\HasLifecycleCallbacks * ... */ class MyEntity { /** * @ORM\PrePersist */ public function onPrePersistSetRegistrationDate() { $this->registration_date = new \DateTime(); } } 

3 Comments

I prefer this answer as it makes it much more clear how Doctrine will handle it.
+1 It will put latest date in the record. If the record have two dates modified_datetime and created_datetime. If you put the modified_datetime in constructor, the created_time may be newer than modified_datetime.
For reference on all of the capabilities of lifecycle callbacks: doctrine-orm.readthedocs.org/en/latest/reference/…
24

I think, the best way to accomplish autofill for datetime is to make like that:

* @ORM\Column(type="datetime", options={"default"="CURRENT_TIMESTAMP"}) 

Putting logic to constructor isn't right solution, because setting default values are SQL client responsibility. If you decide no longer use ORM - you will lost business logic. Plus, if using constructor you won't be able to add default timestamps to datetime attributes for existing rows.

1 Comment

As mentioned below "default": 0 works better with doctrine migrations.
23

There is an extension for this automating this...

https://github.com/l3pp4rd/DoctrineExtensions/blob/master/doc/timestampable.md

/** * @var \DateTime * * @ORM\Column(name="date_added", type="datetime") * @Gedmo\Timestampable(on="create") */ private $date_added; /** * @var \DateTime * * @ORM\Column(name="date_modified", type="datetime") * @Gedmo\Timestampable(on="update") */ private $date_modified; 

4 Comments

This needs upvoting as it is certainly the best way to do this.
@Sc0ttyD Why use an extension if you can reach exactly the same goal with the basic features?
No idea - don't use PHP any more, this was 3 years ago :-)
@luba To ensure database compatibility would be one thought. What if one database doesn't handle setting the default to 0 and mapping it to current_timestamp or doesn't understand current_timestamp?
8
@var string @ORM\Column(name="login_at", type="datetime", options={"default" = "CURRENT_TIMESTAMP"}) 

This will work. Just posting for future ref.

4 Comments

This does not work: Integrity constraint violation: 1048 Column 'login_at' cannot be null
@cwhisperer The above will work if you dont have any data for that table. Means if you have the column already, you have to add some values to this column for every row. Or else, please add the allow default : nullable=true In my case, i was creating a new table, so i didn't had any data in that new table.
correct, but the question is to add default value and not null
@cwhisperer, as i said in the first answer, it will add default value as current timestamp. But IF you're trying to apply this to an already existing table with data & column, then, this won't work, as if there's any row with empty value, then when the alter query runs its won't know which timestamp to put to those column's. won't they? I hope this clears the confusion you might had
0

Work for me with MySql and Symfony 3.4.

... fields: start_date: type: date nullable: false options: default: '1910-01-01' comment: 'The default date is 1910-01-01' ... 

Comments

0

For doctrine-bundle: 2.10 and PHP Attributes, setting a default value:

#[ORM\Column(options: ['default' => 0])] private bool $isActive = false; 

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.