The comparison of two DrupalDateTime object instances using relational operators in PHP 7.3 does not produce the same result as two regular DateTime object instances in some circumstances. See the following example:

use Drupal\Core\Datetime\DrupalDateTime;

$dt_now = new DateTime();
$dt_past = new DateTime('-1 day');
$ddt_now = new DrupalDateTime();
$ddt_past = new DrupalDateTime('-1 day');

var_export($dt_past->format('F a')); // "May pm"
var_export($dt_now < $dt_past); // false
var_export($dt_now->format('c')); // 2019-05-29T15:43:02-04:00
var_export($dt_past->format('c')); // 2019-05-28T15:43:02-04:00

var_export($ddt_past->format('F a')); // "May pm"
var_export($ddt_now < $ddt_past); // true
var_export($ddt_now->format('c')); // 2019-05-29T15:43:02-04:00
var_export($ddt_past->format('c')); // 2019-05-28T15:43:02-04:00

In PHP 7.3, the relative comparison of user-defined objects results in the recursive, short-circuit comparison of each instance property's value (see this link). Considering this information, it logically follows that $ddt_past->format('F a') should then cause $ddt_now->formatTranslationCache[] to alter how the $ddt_past object instance is compared with other instances of the same type.

Ideally, DrupalDateTime (and DateTimePlus) should behave identically to DateTime with respect to the use of relational operators to compare two object instances.

Support from Acquia helps fund testing for Drupal Acquia logo

Comments

clayfreeman created an issue. See original summary.

clayfreeman’s picture

Title: DrupalDateTime (and possibly DateTimePlus) relative comparison broken in PHP 7.3 using relational operators, but DateTime relative comparison working as intended » DrupalDateTime (and possibly DateTimePlus) relative comparison is broken in PHP 7.3 using relational operators, but DateTime relative comparison is working as intended
Issue summary: View changes
clayfreeman’s picture

The attached patch adds a test case for DrupalDateTime to further demonstrate the issue's testing criteria and is intended to fail for this bug.

jonathanshaw’s picture

Issue tags: +PHP 7.3
ivanhelguera’s picture

I have a situation when comapring DateTimePlus to DrupalDateTime always yields False. Fine with two DateTimePlus objects.

andypost’s picture

Version: 8.7.x-dev » 8.8.x-dev

Version: 8.8.x-dev » 8.9.x-dev

Drupal 8.8.0-alpha1 will be released the week of October 14th, 2019, which means new developments and disruptive changes should now be targeted against the 8.9.x-dev branch. (Any changes to 8.9.x will also be committed to 9.0.x in preparation for Drupal 9’s release, but some changes like significant feature additions will be deferred to 9.1.x.). For more information see the Drupal 8 and 9 minor version schedule and the Allowed changes during the Drupal 8 and 9 release cycles.

neclimdul’s picture

Being as this is a failure in all versions or php testbot tests this is just the way PHP behaves right? I'm not clear on a compatibility change in 7.3 that would cause this.

I'm also not really sure how we could change the operator behavior since PHP doesn't allow operator overloading. What's the critical break here we need to come up with a solution to? Maybe methods or some helper object to help comparing dates. That's what Carbon does. https://carbon.nesbot.com/docs/#api-comparison

dpi’s picture

This looks like a wontfix to me.

I doubt behavior changed as a result of PHP version. And if it did, it would be because of property comparison, for which I think it would be plain luck if it worked before.

\DateTime has innate comparison magic since PHP 5.2.2. At this time classes cannot implement their own magic comparison [methods].

When comparing same userland classes, PHP will check properties, but this does not work with instances of different classes. So you're out of luck if you wanted to compare DTT/DTP/DT.

catch’s picture

Category: Bug report » Task
Priority: Critical » Normal

Moving this to a task, we could possibly add a helper to ease comparison per neclimdul's suggestion in #9, but this isn't a critical bug.

Version: 8.9.x-dev » 9.1.x-dev

Drupal 8.9.0-beta1 was released on March 20, 2020. 8.9.x is the final, long-term support (LTS) minor release of Drupal 8, which means new developments and disruptive changes should now be targeted against the 9.1.x-dev branch. For more information see the Drupal 8 and 9 minor version schedule and the Allowed changes during the Drupal 8 and 9 release cycles.

Version: 9.1.x-dev » 9.2.x-dev

Drupal 9.1.0-alpha1 will be released the week of October 19, 2020, which means new developments and disruptive changes should now be targeted for the 9.2.x-dev branch. For more information see the Drupal 9 minor version schedule and the Allowed changes during the Drupal 9 release cycle.

moshe weitzman’s picture

I have to say that this is surprising that our wrapper class is less functional than the built-in DateTime class. Helper methods would be much appreciated.

Version: 9.2.x-dev » 9.3.x-dev

Drupal 9.2.0-alpha1 will be released the week of May 3, 2021, which means new developments and disruptive changes should now be targeted for the 9.3.x-dev branch. For more information see the Drupal core minor version schedule and the Allowed changes during the Drupal core release cycle.

Rob230’s picture

So can we really not use comparison operators with DrupalDateTime? That's quite a setback. There should be a compare method at least. Instead I suppose we have to format it and compare the strings?

Version: 9.3.x-dev » 9.4.x-dev

Drupal 9.3.0-rc1 was released on November 26, 2021, which means new developments and disruptive changes should now be targeted for the 9.4.x-dev branch. For more information see the Drupal core minor version schedule and the Allowed changes during the Drupal core release cycle.

Version: 9.4.x-dev » 9.5.x-dev

Drupal 9.4.0-alpha1 was released on May 6, 2022, which means new developments and disruptive changes should now be targeted for the 9.5.x-dev branch. For more information see the Drupal core minor version schedule and the Allowed changes during the Drupal core release cycle.

Version: 9.5.x-dev » 10.1.x-dev

Drupal 9.5.0-beta2 and Drupal 10.0.0-beta2 were released on September 29, 2022, which means new developments and disruptive changes should now be targeted for the 10.1.x-dev branch. For more information see the Drupal core minor version schedule and the Allowed changes during the Drupal core release cycle.

Version: 10.1.x-dev » 11.x-dev

Drupal core is moving towards using a “main” branch. As an interim step, a new 11.x branch has been opened, as Drupal.org infrastructure cannot currently fully support a branch named main. New developments and disruptive changes should now be targeted for the 11.x branch, which currently accepts only minor-version allowed changes. For more information, see the Drupal core minor version schedule and the Allowed changes during the Drupal core release cycle.