Wednesday, April 1, 2009

SQL Server Search with Dates

Here is a bit on one interesting issue that I faced recently during the search in a SQL server table for dates. Though this was encountered in Microsoft SQL Server the behavior is the same in other relational databases also.

Here is the scenario...I had few records that were similiar to the one given below in the table named FOO

FOO.Date
2008-07-23 12:28:36.963
2008-07-23 12:32:17.467
2008-07-23 12:34:23.130
2008-07-23 12:35:02.587

I ran the following query and expected the result to include all the records given above.
Select * from Foo where date <= '2008-07-23'

Since I had the = along with the less than I figured that will be a match but the results were empty. After thinking for about 10 seconds I realised where I was going wrong. The SQL Server when I dont give a time value assumes the time to be Midnight or the start of the day. So essentially my query is equal to this.
Select * from Foo where date <= '2008-07-23 00:00:00.000'

Since the user input did not have the time component the query input did not have and that created this issue.

Resolution:
A simple resolutions I figured will be to add the time to the query and make it the end of the day. I initiall thought of hardcoding the time to something like 23:59:59.999 but figured that might be a litttle crude. So I just added a java method to get me the end of the day. Here is the method. Please comment on this and let me know if you can think of a better solution.

public Date getEndOfDayDate() {
Calendar newCalendar = Calendar.getInstance();
newCalendar.set(Calendar.DATE, this.getDay());
newCalendar.set(Calendar.MONTH, this.getMonth());
newCalendar.set(Calendar.YEAR, this.getYear());
newCalendar.set(Calendar.HOUR_OF_DAY, newCalendar.getMaximum(Calendar.HOUR_OF_DAY));
newCalendar.set(Calendar.MINUTE, newCalendar.getMaximum(Calendar.MINUTE));
newCalendar.set(Calendar.SECOND, newCalendar.getMaximum(Calendar.SECOND));
newCalendar.set(Calendar.MILLISECOND, newCalendar.getMaximum(Calendar.MILLISECOND));

return new Date(newCalendar);

}

No comments: