After years of date wrangling I really should know better, but ColdFusions's dateCompare function still managed to trip me up today. As its name implies, dateCompare compares two dates and returns a -1 if the first date is before the second date, 0 if they are equal, or 1 if the first is after the second. The gotcha lies in what a date is in ColdFusion. A date is not just the month, day, and year, but also the time.

This code snippet illustrates my head-slapping moment:

view plain print about
1<cfset currentDate = now()>
2<cfset targetDate = createDate(2008, 04, 30)>
3
4<cfloop condition="dateCompare(currentDate, targetDate) LTE 0">
5    <cfoutput>#dateFormat(currentDate, "mm/dd/yyyy")#<br /></cfoutput>
6    <cfset currentDate = dateAdd("d", 1, currentDate)>
7</cfloop>

I wanted a list of days between today, April 23, and the end of the month. However, I ended up missing a day, April 30. The output of the above snippet is:

04/23/2008
04/24/2008
04/25/2008
04/26/2008
04/27/2008
04/28/2008
04/29/2008

So where did that missing day go? Into the time portion of the date. DateCompare not only looks at the date portion of a date, but also the time portion.

view plain print about
1<!--- Returns 1 because the second date is midnight on April 23. --->
2<cfoutput>#dateCompare(now(), createDate(2008, 04, 23))#</cfoutput>

To accommodate the time element of a date, I changed the code to use the dateDiff function and examine only the day:

view plain print about
1<cfset currentDate = now()>
2<cfset targetDate = createDate(2008, 04, 30)>
3
4<cfloop condition="dateDiff('d', targetDate, currentDate) LTE 0">
5    <cfoutput>#dateFormat(currentDate, "mm/dd/yyyy")#<br /></cfoutput>
6    <cfset currentDate = dateAdd("d", 1, currentDate)>
7</cfloop>

Which outputs:

04/23/2008
04/24/2008
04/25/2008
04/26/2008
04/27/2008
04/28/2008
04/29/2008
04/30/2008

Problem solved, until next time. :)