Thursday, December 29, 2011

Last Modified Date Rounding to Whole Seconds

The DateTime class in Salesforce has precision down to the order of milliseconds, as implied by the getTime method which "returns the number of milliseconds since January 1, 1970, 00:00:00 GMT represented by this DateTime object." Since the Last Modified Date field is a Date/Time field, one would assume that the Last Modified Date includes the millisecond value when stamping a record, right? Alas, this is not the case.

A video demonstrating the behavior: http://www.youtube.com/watch?v=IyRd1woiS24

It seems that Salesforce only includes the year, month, day, hour, minute and second when stamping the Last Modified Date. The millisecond value is simply zeroed out without any rounding. So, if a record was actually modified at 12/29/2011 12:31:20.578, Salesforce will stamp the record as being modified at 12/29/2011 12:31:20.000.

Okay, so there's a tiny discrepancy. I mean, we're talking tiny differences here. The million-dollar question: Why do I care?

I care because this little quirk caused my unit test to fail over 80% of the time due to the fact that comparing the Last Modified Date to DateTime.now() was producing unexpected results. For example:
  • At the beginning of the test method, DateTime.now() returned 12/29/2011 4:00:01.500.
  • At the end of the test method, the updated record's Last Modified Date shows 12/29/2011 4:00:01.000.
  • System.assert(record.LastModifiedDate >= testStartDateTime) fails unexpectedly and inconsistently.

The oddity with Last Modified Date is not an impossible problem to work around, but should I really be working around it? What does this mean for test-driven development that Apex is supposed to enable?