CreateDate() Much Faster Than DateFormat() For Date-Only Creation
There are times when I need a date/time stamp that only has a date part and a zero'd out time part. Take for example, needing to get all events on a given day. I can't use a simple =, <, or > since the time part will not compare easily or work nicely with DateAdd() execution. But don't get hung up on the example, just imagine that sometimes you want a date-only date/time object.
To do this, I usually do a CreateDate() on the date/time stamp to get a date-only date object:
CreateDate( [YEAR], [MONTH], [DAY] )
I thought maybe it would be faster to do a DateFormat() call since this requires less method calls (superficially - does not have to call Year(), Month(), Day() methods). Plus, DateFormat() looks a bit more streamlined.
It turns out that DateFormat(), for this purpose, is MUCH slower than CreateDate(). In general, my testing (below) found CreateDate() to be about 8 times faster than DateFormat().
<!--- Set up test for CreateDate(). --->
<cftimer label="Using CreateDate()" type="outline">
<!--- Loop over enough times to see a non-zero time. --->
<cfloop index="intI" from="1" to="1000" step="1">
<!--- Get date/time stamp. --->
<cfset dtNow = Now() />
<!--- Get the "date-only" part of the date/time stamp. --->
<cfset dtNowDate = CreateDate( Year( dtNow ), Month( dtNow ), Day( dtNow ) ) />
<!--- Do some computation on the date. --->
<cfset dtComputed = DateAdd( "d", RandRange( 1, 5 ), dtNowDate ) />
<!--- For screen output. --->
.
</cfloop>
</cftimer>
<!--- Set up test for DateFormat(). --->
<cftimer label="Using DateFormat()" type="outline">
<!--- Loop over enough times to see a non-zero time. --->
<cfloop index="intI" from="1" to="1000" step="1">
<!--- Get the "date-only" part of the date/time stamp. --->
<cfset dtNowDate = DateFormat( Now(), "mm/dd/yyyy" ) />
<!--- Do some computation on the date. --->
<cfset dtComputed = DateAdd( "d", RandRange( 1, 5 ), dtNowDate ) />
<!--- For screen output. --->
.
</cfloop>
</cftimer>
However, keep in mind that this is for extreme bulk date creation. For a single instance on a page, the difference would be inconsequential. So the question is, which is "better"? I guess it depends. If this is going to be in an encapsulated area, then by all means, use the faster, more efficient CreateDate() method. But, if you are going to use it once or twice on a page in a CFQueryParam or something, I say go with which ever one seems easier to read and maintain.
Want to use code from this post? Check out the license.
Reader Comments
Thanks a lot for this Ben.
Just one of the thousand other posts you've help me with.
Thanks
Arshad
@Arshad,
Ha ha, thanks my man :)
You shouldn't really use dateformat() unless you are outputting the data to the screen. Why? If you ever want to internationalise your code you'll run into trouble. CFs date formatting functions only work reliably with American date masks (month then date) unless you use CF date objects to store the dates.
You should use CreateDate() to make a date object and use that at all times for internal date functions (like adding etc), and only use dateFormat() at the last moment for display.
Here's an example of what happens just using dateformat:
Run that and if you set an initial UK date between the 1st and 12th of a month you'll get:
Ben this is my first post on your site and I'm pretty new to coldfusion. You've helped me considerably in my short time here so I have faith you will know what to do. I'm having an issue using isValid("date", string) and then using CreateDate() Here is the issue.
<cfset var.datestring = trim(ListGetAt(74406|CCW14|4675.00|4302014|N/A,4,"I"))>
<cfif isValid("date", var.datestring)>
<cfset paymentdate = CreateDate(Right(variables.datestring,4), Left(variables.datestring,2), Mid(variables.datestring,3,2))>
</cfif>
The issue is that 4302014 is recognized as a valid date by isDate() and isValid(), but this oddly written CreateDate() Function fails creating the MONTH because it is not valid. (The month is being inserted to the function as '43' by the Left() function.)
I have fixed it by appending a "0" to the beginning of the datestring and the taking the Right "8" characters for now. But I'm afraid now that if a user puts in an abbreviated year or forgets the leading 0 somewhere else I'm screwed. If you have any questions or I can better explain lmk. Thanks Ben!