2

Can i compare 2 mongodates like below? In my testing it is working good. But mongodates are objects and will they work the same way in future as well?

$d1 = new MongoDate(1391671630);
$d2 = new MongoDate(1391671631);

echo ($d1 < $d2); //returns 1 which is correct. 
//and i tried all other comparisons (>, ==, >=, <=). Everything works good. 
user10
  • 5,186
  • 8
  • 43
  • 64
  • I've not used mongodates before, but I'm guessing they're deterministic? (Same time stamp means 'equal' mongo dates?) can you just compare the integer time stamps you're passing in? – PandemoniumSyndicate Feb 06 '14 at 08:10

3 Answers3

2

You will need to use the sec property of the MongoDate object:

$d1->sec < $d2->sec
Sammaye
  • 43,242
  • 7
  • 104
  • 146
  • If `$d1` is null or empty string `$d1 < $d2` works fine. In your case i have to check whether `$d1` is not null and it is having `sec` or not. So what do you think about my way of comparison. Will it give any problem in future? – user10 Feb 06 '14 at 13:05
  • @user10 technically PHP will cast to an int before casting string to work out the comparison however a return of `1` sounds odd, it should return `true` – Sammaye Feb 06 '14 at 14:44
  • @Sammaye: this solution fails for cases where two MongoDate instances have the same second precision but differ in microsecond precision. – jmikola Feb 12 '14 at 21:24
  • @jmikola Doesn't mongodb itself only go on milisecond? http://docs.mongodb.org/manual/reference/bson-types/#date – Sammaye Feb 12 '14 at 22:52
  • @Sammaye: Yes, I mispoke. The MongoDate constructor takes microseconds but we truncate it to milliseconds before assigning the value to the `$usec` property, since BSON is only millisecond precision. My point was that we can't simply compare the `$sec` property, since two MongoDates could differ by a fraction of a second. – jmikola Feb 13 '14 at 03:29
1

The MongoDate classes in the mongo driver have no special support for comparison operators. The behavior you're seeing is likely internal PHP behavior, where comparing two objects with <, <=, >, and >= operators examines the properties in order. It just so happens that MongoDate declares its $sec property before $usec, so this works out. I didn't find this behavior documented in the PHP manual, but it is discussed in this comment on the page where I'd expect to find it.

You may want to track PHP-226, as there are plans to add a helper method to return the float value of a MongoDate (akin to microtime(true)). As-is, the __toString() return value isn't very helpful, since microseconds appear before seconds.

I've also opened PHP-979 to track this as a feature request (overloading support for comparison operators).

jmikola
  • 6,892
  • 1
  • 31
  • 61
  • If BSON dates in MongoDB are milisecond precision I am unsure how microsecond precision differences will make a huge difference here? – Sammaye Feb 12 '14 at 22:54
  • I'm writing "microsecond" above since the PHP property is `$usec`. I think I addressed the importance of checking both `$sec` in `$usec` in [my other comment](http://stackoverflow.com/questions/21596730/php-compare-two-mongodates/21739961#comment32888565_21597356), but my point in this answer was just to explain exactly what PHP is doing internally when the OP compares two MongoDate objects. – jmikola Feb 13 '14 at 03:33
0

The drivers are maintained by staff at MongoDB, well most of them. So the majority of things listed as a base driver implementation are always going to be part of the specification anyhow.

Under the hood MongoDB actually stores the value as an epoch timestamp internally and the MongoDate class is making sure that this is passed in over the wire as the valid BSON type with the correct value. So it's in your advantage that you use a type recognized internally so the server side comparison of dates works as expected.

Neil Lunn
  • 148,042
  • 36
  • 346
  • 317