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

Posted August 29, 2006 at 6:50 PM

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:

 Launch code in new window » Download code as text file »

  • <!--- 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:

 Launch code in new window » Download code as text file »

  • <!--- 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:

 Launch code in new window » Download code as text file »

  • <!--- 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:

 Launch code in new window » Download code as text file »

  • <!--- 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.

Download Code Snippet ZIP File

Post Comment  |  Ask Ben  |  Permalink  |  Other Searches  |  Print Page




Learning ColdFusion 9 - ColdFusion 9 tutorials, samples, examples, demos

Reader Comments

Feb 27, 2009 at 12:22 PM // reply »
1 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?


Feb 27, 2009 at 12:29 PM // reply »
6,516 Comments

@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.


Post Comment  |  Ask Ben

Recent Blog Comments
Nov 20, 2009 at 11:32 PM
Five Months Without Hungarian Notation And I'm Loving It
I've used headless camel case for years for not only ColdFusion variables, but also SQL tables and fields... pretty much everything involving code. I also subscribe to the "don't abbreviate and clea ... read »
Nov 20, 2009 at 11:00 PM
Five Months Without Hungarian Notation And I'm Loving It
@Marcel, Yeah, I always err on the side of longer but more readable variable names. As for the camel casing of CF methods and the headless camel casing of custom items, I get around this by always ... read »
Nov 20, 2009 at 10:56 PM
Five Months Without Hungarian Notation And I'm Loving It
I use the following and love it: my.namespace.MyComponents.functionMethodsOrUDF() CONSTANT_VALUES_OR_PROPERTIES One thing I always try is to CamelCaseBuiltInColdFusionFunctions() so others can tell ... read »
Nov 20, 2009 at 5:38 PM
Learning ColdFusion 8: CFImage Part I - Reading And Writing Images
Hi Ben, Great article. I've been looking around to see if ColdFusion image engine can programatically create the following "wrap around" effect: http://www.creativepro.com/article/photoshop-s-she ... read »
Nov 20, 2009 at 5:35 PM
Maintaining ColdFusion Sessions Across SMS Text Message Requests Without Cookies
@Dave: I talked to Gert he suggested: <cfhttp method="get" url="http://{some cf website}" result="stuff" addtoken="yes" /> Note the addition of cfhttp attribute addtoken. That should persist y ... read »
Nov 20, 2009 at 5:23 PM
Maintaining ColdFusion Sessions Across SMS Text Message Requests Without Cookies
@Todd, Ahh, gotcha, yeah that makes sense. ... read »
Nov 20, 2009 at 5:17 PM
Maintaining ColdFusion Sessions Across SMS Text Message Requests Without Cookies
Ben, sorry if I didn't make this clear. You can make it work like that if you want, just put <cfset session.foo = 1> (and <cfset application.foo = 1>) in your OnRequestStart() and it reve ... read »