doctrine / mongodb-odm

The Official PHP MongoDB ORM/ODM
https://www.doctrine-project.org/projects/doctrine-mongodb-odm/en/latest/
MIT License
1.09k stars 504 forks source link

DateTest::testOldDate() fails on 32-bit platforms #1060

Closed jmikola closed 1 year ago

jmikola commented 9 years ago

@jwage mentioned that https://github.com/doctrine/mongodb-odm/commit/c36c0606fb0a2f933e843cf68963f3cf4e8f207f failed for him on a 32-bit test environment:

1) Doctrine\ODM\MongoDB\Tests\Functional\DateTest::testOldDate
InvalidArgumentException: Could not convert "1900-01-01" to a date value

This is due to the the test date exceeding the bounds for a negative 32-bit int. From strtotime()'s documentation:

The valid range of a timestamp is typically from Fri, 13 Dec 1901 20:45:54 UTC to Tue, 19 Jan 2038 03:14:07 UTC. (These are the dates that correspond to the minimum and maximum values for a 32-bit signed integer.)

Interestingly, DateTime doesn't seem to have this problem:

vagrant@precise32:/vagrant/data/mongodb-odm$ php -r "echo (new \DateTime('1900-01-01'))->format('c');"
1900-01-01T00:00:00+00

vagrant@precise32:/vagrant/data/mongodb-odm$ php -r "var_dump((new \DateTime('1900-01-01'))->format('U'));"
string(11) "-2208988800"

vagrant@precise32:/vagrant/data/mongodb-odm$ php -r "var_export(strtotime('1900-01-01'));"
false

This is mainly because it prints a long long directly to a string buffer (see: here), which it returns. Meanwhile, strtotime() returns a platform-dependent long (see: here).


There is no clear solution for ODM, since MongoDate::__construct() takes long values for its sec and usec parameters. Ultimately, MongoDate would need to accept a string as its first argument, and parse that directly into an int64_t (reported and tracked by PHP-1424).

malarzm commented 7 years ago

@jmikola related JIRA ticket was made for legacy driver, is this something new one is tackling/will tackle?

jmikola commented 7 years ago

related JIRA ticket was made for legacy driver, is this something new one is tackling/will tackle?

MongoDB\BSON\UTCDateTime::__construct() accepts a string argument since 1.0.0, which will be parsed as a 64-bit integer.

alcaeus commented 6 years ago

It's almost 2018 and I'm very willing to close this and ignore 32-bit platforms (sorry @jwage).

@jmikola I didn't quite get whether ext-mongodb still has the same problem - now that dev-master uses ext-mongodb this might no longer be an issue.

jmikola commented 6 years ago

I didn't quite get whether ext-mongodb still has the same problem - now that dev-master uses ext-mongodb this might no longer be an issue.

Looking at DateType, I believe the issue still remains, as you cast a concatenated string of seconds and milliseconds to an integer.

An easy and portable fix would be to simply pass the DateTime object to UTCDateTime::__construct(), which has been supported since ext-monogdb 1.2.0. Is there any reason that wasn't done in the original implementation?

malarzm commented 1 year ago

It's almost 2018 and I'm very willing to close this and ignore 32-bit platforms (sorry @jwage).

Yeah, gonna do that now it's 2023 👼