DDC-2302: entity not updating with existing \Datetime object #2891

Closed
opened 2026-01-22 14:06:48 +01:00 by admin · 6 comments
Owner

Originally created by @doctrinebot on GitHub (Feb 17, 2013).

Originally assigned to: @beberlei on GitHub.

Jira issue originally created by user stijink:

Within an entity i have an method to add days to a subscription. For that an datetime object is modified.

But the database is not going to be updated if an already existing datetime-object is modified an set. It's only working when an freshly created datetime object is used.

NOT WORKING EXAMPLE:

    public function addDaysToSubscription($days) {

        if ($this->hasValidSubscription()) {

            $startFromDate = $this->getSubscriptionValidUntil();
        }
        else {

            $startFromDate = new \DateTime('now');
        }

        $this->setSubscriptionValidUntil($startFromDate->modify('<ins>' . $days .' days'));
    }

WORKAROUND:

    public function addDaysToSubscription($days) {

        if ($this->hasValidSubscription()) {

            $validDate = $this->getSubscriptionValidUntil()->format('Y-m-d H:i:s');
            $startFromDate = new \DateTime($validDate);
        }
        else {

            $startFromDate = new \DateTime('now');
        }

        $this->setSubscriptionValidUntil($startFromDate->modify('</ins>' . $days .' days'));
    }
Originally created by @doctrinebot on GitHub (Feb 17, 2013). Originally assigned to: @beberlei on GitHub. Jira issue originally created by user stijink: Within an entity i have an method to add days to a subscription. For that an datetime object is modified. But the database is not going to be updated if an already existing datetime-object is modified an set. It's only working when an freshly created datetime object is used. NOT WORKING EXAMPLE: ``` public function addDaysToSubscription($days) { if ($this->hasValidSubscription()) { $startFromDate = $this->getSubscriptionValidUntil(); } else { $startFromDate = new \DateTime('now'); } $this->setSubscriptionValidUntil($startFromDate->modify('<ins>' . $days .' days')); } ``` WORKAROUND: ``` public function addDaysToSubscription($days) { if ($this->hasValidSubscription()) { $validDate = $this->getSubscriptionValidUntil()->format('Y-m-d H:i:s'); $startFromDate = new \DateTime($validDate); } else { $startFromDate = new \DateTime('now'); } $this->setSubscriptionValidUntil($startFromDate->modify('</ins>' . $days .' days')); } ```
admin added the Bug label 2026-01-22 14:06:48 +01:00
admin closed this issue 2026-01-22 14:06:48 +01:00
Author
Owner

@doctrinebot commented on GitHub (Feb 17, 2013):

Comment created by @beberlei:

From the documentation (Mapping Objects):

DateTime and Object types are compared by reference, not by value. Doctrine updates this values if the reference changes and therefore behaves as if these objects are immutable value objects.

You have to replace them with a new instance.

@doctrinebot commented on GitHub (Feb 17, 2013): Comment created by @beberlei: From the documentation (Mapping Objects): ``` DateTime and Object types are compared by reference, not by value. Doctrine updates this values if the reference changes and therefore behaves as if these objects are immutable value objects. ``` You have to replace them with a new instance.
Author
Owner

@doctrinebot commented on GitHub (Feb 17, 2013):

Comment created by stijink:

Whats the reason for this behaviour ? For me it seem not very intuitive and cost me a couple of hours of project time :)

@doctrinebot commented on GitHub (Feb 17, 2013): Comment created by stijink: Whats the reason for this behaviour ? For me it seem not very intuitive and cost me a couple of hours of project time :)
Author
Owner

@doctrinebot commented on GitHub (Feb 17, 2013):

Comment created by @ocramius:

[~stijink] there is no real "global" way of comparing objects in PHP. The only way would be to use a non-strict comparison (aka == vs ===), and that leads to many unexpected problems.

Since DateTime instances are objects like any other, the comparison is applied with ===.

This the safest way to handle this is to work with it as if it was an immutable:

public function setCreationTime(\DateTime $dateTime)
{
    $this->creationTime = clone $dateTime;
}

public function getCreationTime(\DateTime $dateTime)
{
    return clone $this->creationTime;
}

This basically disallows a lot of unexpected behaviors, even when not working with the ORM.

@doctrinebot commented on GitHub (Feb 17, 2013): Comment created by @ocramius: [~stijink] there is no real "global" way of comparing objects in PHP. The only way would be to use a non-strict comparison (aka `==` vs `===`), and that leads to many unexpected problems. Since `DateTime` instances are objects like any other, the comparison is applied with `===`. This the safest way to handle this is to work with it as if it was an immutable: ``` public function setCreationTime(\DateTime $dateTime) { $this->creationTime = clone $dateTime; } public function getCreationTime(\DateTime $dateTime) { return clone $this->creationTime; } ``` This basically disallows a lot of unexpected behaviors, even when not working with the ORM.
Author
Owner

@doctrinebot commented on GitHub (Feb 17, 2013):

Comment created by @beberlei:

Also DateTime objects being mutable was a mistake in PHP, this is why 5.5 will have DateTimeImmutable, which we will switch to if possible in the future :)

@doctrinebot commented on GitHub (Feb 17, 2013): Comment created by @beberlei: Also DateTime objects being mutable was a mistake in PHP, this is why 5.5 will have DateTimeImmutable, which we will switch to if possible in the future :)
Author
Owner

@doctrinebot commented on GitHub (Sep 8, 2013):

Comment created by @beberlei:

Change to 'Invalid'

@doctrinebot commented on GitHub (Sep 8, 2013): Comment created by @beberlei: Change to 'Invalid'
Author
Owner

@doctrinebot commented on GitHub (Sep 8, 2013):

Issue was closed with resolution "Invalid"

@doctrinebot commented on GitHub (Sep 8, 2013): Issue was closed with resolution "Invalid"
Sign in to join this conversation.
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: doctrine/archived-orm#2891