Symfony 4中如何通过set方法为实体设置DateTime类型字段值
Hey there! Let's work through this datetime field issue you're facing with Symfony and Doctrine. The core problem here is that your setCreatedTs method expects a DateTimeInterface object (like \DateTime or \DateTimeImmutable), not a plain string—and the boolean error from createFromFormat pops up because the date string you used didn't match the format you specified, leading to a failed parse.
Here are the most reliable ways to fix this:
1. Use the Current Time (Simplest Option)
If you just need to set the field to the current date and time, directly instantiate a DateTime or DateTimeImmutable object (Immutable is preferred for entity fields since it prevents accidental modifications later):
// Using mutable DateTime $yourEntity->setCreatedTs(new \DateTime()); // Or using immutable DateTime (better practice for entities) $yourEntity->setCreatedTs(new \DateTimeImmutable());
2. Parse a String to DateTime Correctly
When converting a string to a DateTime object, you must ensure the format string exactly matches the structure of your date string. Also, always validate if createFromFormat returns a valid object (it returns false if parsing fails, which was causing your boolean error).
For example, if your date string is 2024-05-20 14:30:00, use this code:
$dateString = "2024-05-20 14:30:00"; $date = \DateTime::createFromFormat('Y-m-d H:i:s', $dateString); // Validate before passing to the setter if ($date instanceof \DateTimeInterface) { $yourEntity->setCreatedTs($date); } else { // Handle invalid input—throw an error or set a default throw new \InvalidArgumentException("Invalid date format. Expected 'YYYY-MM-DD HH:MM:SS'."); }
Common format tokens to keep in mind:
Y: 4-digit yearm: 2-digit monthd: 2-digit dayH: 24-hour format houri: Minutess: Seconds
3. Let Symfony Handle Conversion Automatically
If you're getting the date from a form or API request, use Symfony's built-in tools to skip manual parsing:
- For forms: Use the
DateTimeTypefield in your form class. It will automatically convert user input strings toDateTimeInterfaceobjects. - For API requests: Use the Serializer component's
DateTimeNormalizerto deserialize JSON/XML date strings directly into DateTime objects.
4. Auto-Set the Timestamp (No Manual Setter Calls)
To avoid having to call setCreatedTs altogether, auto-populate the field when the entity is created:
Option A: Constructor Initialization
use Doctrine\ORM\Mapping as ORM; /** * @ORM\Entity */ class YourEntity { // ... other fields /** * @ORM\Column(type="datetime") */ private \DateTimeInterface $createdTs; public function __construct() { // Set to current time when the entity is created $this->createdTs = new \DateTimeImmutable(); } // ... keep the setter if you need to override the value later }
Option B: Doctrine Lifecycle Callback
Use a PrePersist callback to set the timestamp right before the entity is saved to the database:
use Doctrine\ORM\Mapping as ORM; /** * @ORM\Entity * @ORM\HasLifecycleCallbacks */ class YourEntity { // ... other fields /** * @ORM\Column(type="datetime") */ private \DateTimeInterface $createdTs; /** * @ORM\PrePersist */ public function setCreatedTsOnPersist(): void { $this->createdTs = new \DateTimeImmutable(); } // ... getter and setter }
内容的提问来源于stack exchange,提问作者treyBake

