Ben Nadel
On User Experience (UX) Design, JavaScript, ColdFusion, Node.js, Life, and Love.
I am the chief technical officer at InVision App, Inc - a prototyping and collaboration platform for designers, built by designers. I also rock out in JavaScript and ColdFusion 24x7.
Meanwhile on Twitter
Loading latest tweet...
Ben Nadel at cf.Objective() 2011 (Minneapolis, MN) with:

ColdFusion Date Math Faster Than Date Methods... And Other Date/Math Ramblings

By Ben Nadel on
Tags: ColdFusion

Ben Forta had posted something about subtracting one date from another and it got me thinking. If you follow my blog, you know that I am a big fan of performing straight up date math (leveraging the fractional format of a date) rather than using built in ColdFusion methods such as DateAdd() and CreateDate() WHEN I CAN (which is not all the time of course). So anyway, it reminded me of the time I compared CreateDate() to DateFormat() in terms of speed of removing time. I was pretty sure that date math would be faster than things like CreateDate() but I wanted to test for confirmation.

I set up two test. One that removes the time from a date and one that subtracts a day from a date.

Test 1: Removing Time From A Date

Often times in an application I will want to remove the time from a date before I either use it in a database query or a loop. This compares the Int() method which rounds DOWN on a date to the CreateDate() method which will create a time-less date object:

  • <!--- Test the CreateDate() method. --->
  • <cftimer label="Date Methods" type="outline">
  •  
  • <!--- Loop for time testing. --->
  • <cfloop index="intI" from="1" to="10000" step="1">
  •  
  • <!--- Get Now for less method calls. --->
  • <cfset dtNow = Now() />
  •  
  • <!--- Create a date-only date object. --->
  • <cfset dtToday = CreateDate(
  • Year( dtNow ),
  • Month( dtNow ),
  • Day( dtNow )
  • ) />
  •  
  • </cfloop>
  •  
  • <!--- Output for feedback. --->
  • #DateFormat( dtToday )#
  •  
  • </cftimer>
  •  
  •  
  • <!--- Test the fractional math method. --->
  • <cftimer label="Date Math" type="outline">
  •  
  • <!--- Loop for time testing. --->
  • <cfloop index="intI" from="1" to="10000" step="1">
  •  
  • <!--- Create the date-only object. --->
  • <cfset dtToday = Int( Now() ) />
  •  
  • </cfloop>
  •  
  • <!--- Output for feedback. --->
  • #DateFormat( dtToday )#
  •  
  • </cftimer>

In these test, just as I suspected, the math method was faster. For 10,000 iterations, the math method ran at best 3 times faster than CreateDate() and at worst was on par with CreateDate(). But if you think about it, it just makes sense - CreateDate() uses 4 method calls where as the math method uses only two method calls.

Test 2: Subtracting Days From A Date

Often times in an application, I will need to change a given date by adding or subtracting days from a it, such as finding the date 7 days from the given date. This test was to compare the math method to the DateAdd() method:

  • <!--- Test the DateAdd() method. --->
  • <cftimer label="Date Methods" type="outline">
  •  
  • <!--- Get current date. --->
  • <cfset dtNow = Now() />
  •  
  • <!--- Loop for time testing. --->
  • <cfloop index="intI" from="1" to="10000" step="1">
  •  
  • <!--- Get a new date. --->
  • <cfset dtNewDay = DateAdd( "d", -intI, dtNow ) />
  •  
  • </cfloop>
  •  
  • <!--- Output for feedback. --->
  • #DateFormat( dtNewDay )#
  •  
  • </cftimer>
  •  
  •  
  • <!--- Test the fractional math method. --->
  • <cftimer label="Date Math" type="outline">
  •  
  • <!--- Get current date. --->
  • <cfset dtNow = Now() />
  •  
  • <!--- Loop for time testing. --->
  • <cfloop index="intI" from="1" to="10000" step="1">
  •  
  • <!--- Get a new date. --->
  • <cfset dtNewDay = (dtNow - intI) />
  •  
  • </cfloop>
  •  
  • <!--- Output for feedback. --->
  • #DateFormat( dtNewDay )#
  •  
  • </cftimer>

This test proved that date math is faster than DateAdd(). However, the results where not as big. Subtracting a number from a date outperformed DateAdd() only slightly to moderately, not drastically.

I have talked about this before, but I will touch on it once again as it is such an important concept to understand. Date/Time objects can be considered to represent the number of days that have passed since the zero day, where the integer part represents the whole days and the decimal part represents the time. The zero day differs from system to system (I think), but for ColdFusion, the zero day is Saturday, December 30, 1899. Taking that into account, the date "100" is merely 100 days later than the zero date. That is why the following two lines output the same thing:

  • <!--- Math version. --->
  • #DateFormat( 100, "full" )#
  •  
  • <!--- Date version. --->
  • #DateFormat(
  • DateAdd( "d", 100, CreateDate( 1899, 12, 30 ) ),
  • "full"
  • )#

Now, that is not to say that you cannot go back in time even farther. The only difference is that the fractional representation of the number becomes negative. That is why:

  • <!--- Negative date/time fraction. --->
  • #DateFormat( -10, "full" )#

... will give you Wednesday, December 20, 1899. This is 10 days before ColdFusion's zero date.

There you have it; date/time objects are numeric. That is why ColdFusion has a built in method to determine if your number is a valid date: IsNumericDate(). So, feel free start adding numbers and dates together to get some really fast results. Just remember, one day is 1.




Reader Comments

I use a .js datepicker to select from and to date for carrental.
the output of these dates is mm/dd/yyyy.
Is it possible to convert a formatted date back into a numeric value?

@Grietje,

If you simply multiply the date by one, it will convert it to numeric. However, there's nothing much to be gained by that as the conversion will happen automatically as needed.

I'm stumped and can't find anything online. Our CF code calls an ASP.NET web service passing the following parameters:

Web service operation Usage with parameters {EndDate={{ts '2011-08-31 00:00:00'}},StartDate={{ts '2011-08-01 00:00:00'}},CustomerCode={905841},FullUserName={customeris},SessionID={184F2426-685D-4F14-B8F1-C5E9E3B56DA2}}

For some reason, the ASP.NET developer can run it outside the code on her system and get everything between 2011-08-01 and 2011-08-31, but when we run it through the coldfusion code, it seems to be subtracting one day from both the start and end dates, such that we get data between 2011-07-31 and 2011-08-30.

Has anyone struck anything like that?

Hi Ben,
I found replaceDateCodes function in one of application, wht it will do. I searched in cf documentation i didnt found

Thank you in advance