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.
Comments
Comment #2
clayfreemanComment #3
clayfreemanThe attached patch adds a test case for
DrupalDateTime
to further demonstrate the issue's testing criteria and is intended to fail for this bug.Comment #4
clayfreemanFix patch prefix so that it can be applied correctly.
Comment #5
jonathanshawComment #6
ivanhelguera CreditAttribution: ivanhelguera commentedI have a situation when comapring DateTimePlus to DrupalDateTime always yields False. Fine with two DateTimePlus objects.
Comment #7
andypostComment #9
neclimdulBeing 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
Comment #10
dpiThis 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.
Comment #11
catchMoving 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.
Comment #14
moshe weitzman CreditAttribution: moshe weitzman commentedI 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.
Comment #16
Rob230 CreditAttribution: Rob230 at CTI Digital commentedSo 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?