Ask Ben: Appending Times To Date/Time Objects

Posted July 19, 2006 at 9:32 AM by Ben Nadel

Tags: ColdFusion, Ask Ben

In ColdFusion, how can I append a time to a date?

This question is a bit ambiguous so I will try to answer both questions it might be. I think you are asking one of the two following questions:

  1. How can I add or replace the time portion of a date/time object so that the resultant date/time object has the original date and the given time?
  2. How can I add a given amount of time to a given date/time object?

If you have been following my earlier posts, you will see that you can handle date/time objects in ColdFusion in many, many ways. This means that the problems above can be solved in many ways. To start with, I will discuss the possible solutions. Then, I will go over time testing so you can see which one is actually faster.

For starters, I am going to tackle the idea of replacing the time part of a date/time object with the given time parameters. This will not change the date portion, only the time portion. For this section, I am going to assume that we have the following date/time object:

  • <cfset dtNow = "2006-07-19 08:43:15 AM" />

This will give us a date/time object that has both a date and a time portion.

Solution A1: We can use the built-in ColdFusion method CreateDateTime(). This method allows us to create a date/time object by supplying all of the individual parts (year, month, day, hours, minutes, seconds). Since we only want to "create" the time part, you can pass in the year, month, and day from the existing date/time object:<br>

  • <!--- Create a new date with a time portion. --->
  • <cfset dtOne = CreateDateTime(
  • Year( dtNow ),
  • Month( dtNow ),
  • Day( dtNow ),
  • 18, <!--- 6 PM. --->
  • 00, <!--- 0 Minutes. --->
  • 00  <!--- 0 Seconds. --->
  • ) />
  •  
  • <!--- Dump out result. --->
  • <cfdump var="#CreateODBCDateTime( dtOne )#" /><br>

Here, you can see that we are only setting the time parts but keeping the old date parts. Also, I am using the ColdFusion method CreateODBCDateTime() here (and throughout the entry) because it will give us a consistent formatting of both the date and time parts of the date/time object with minimal coding. This is for display purposes only. I would not use this to format dates in my code.

Solution A2: We can treat the date/time object as a number whose integers are the days and whose decimals are the time part (day fractions). To do so, we can round out the date, creating a number that has no time, then add a time span to it:<br />

  • <!--- Create a new date based on the rounded date and a time span. --->
  • <cfset dtTwo = (
  • Round( dtNow ) +
  • CreateTimeSpan(
  • 0,  <!--- Days. --->
  • 18, <!--- Hours. --->
  • 0,  <!--- Minutes. --->
  • 0   <!--- Seconds. --->
  • )
  • ) />
  •  
  • <!--- Dump out result. --->
  • <cfdump var="#CreateODBCDateTime( dtTwo )#" /><br>

This method has the advantage that you don't have to pass in the three parts of the original date object but instead just pass in the date object as a whole to the Round() method. While you cannot see it if you use my CFDump tag, keep in mind that when you Round() the date and use CreateTimeSpan(), ColdFusion is converting the date/time object to a floating point number. This is STILL a date, but you need to format it for display (can be used internally as a date without formatting).

Solutions A3: You can treat the date/time object as a formatting string and then just text-append the time part to the date part:<br />

  • <!--- Create a date/time as a string object. --->
  • <cfset dtThree = (
  • DateFormat( dtNow, "yyyy-mm-dd" ) &
  • " " &
  • "18:00:00"
  • ) />
  •  
  • <!--- Dump out result. --->
  • <cfdump var="#CreateODBCDateTime( dtThree )#" /><br>

This method will create the string "2006-07-19 18:00:00" which ColdFusion will properly treat as a date/time object. Even before testing though, I can tell you that this is slow. DateFormat() is a slow function and string concatenation is slow.

That's all I can really think of for problem one. Now, let's talk about problem two, adding time to an existing date/time object so that both the date and the time parts are potentially updated. There's really only one way I can think about doing this that isn't entirely crappy and that is to simply add the time span to the date/time object:

  • <!--- Create a new date by adding a time span. --->
  • <cfset dtFour = (
  • dtNow +
  • CreateTimeSpan(
  • 0, <!--- Days. --->
  • 2, <!--- Hours. --->
  • 0, <!--- Minutes. --->
  • 0  <!--- Seconds. --->
  • )
  • ) />
  •  
  • <!--- Dump out result. --->
  • <cfdump var="#CreateODBCDateTime( dtFour )#" /><br>

The equation above forces the date/time object (dtNow) to be converted to a floating point number so that it can play well with CreateTimeSpan(). Then, we add the time span (another floating point number) and get the resultant date as a floating point number (which we already discussed).

Keep in mind that while our examples have used the CreateTimeSpan() method to create time spans less than a day, if you had over 24 hours or set the day argument, the date portion of the resultant date/time object will also be altered.

One final note, you CANNOT use DateAdd() and CreateTimeSpan() to add fractions of a day. This would be nice, but DateAdd() requires the use of integer values and CreateTimeSpan() created floating point numbers.

Ok, so those are the potential solutions, now let's test which ones of the first set are the fastest.

  • <cftimer label="One" type="outline">
  • <cfloop index="intI" from="1" to="1000">
  •  
  • <cfset dtOne = CreateDateTime(
  • Year( dtNow ),
  • Month( dtNow ),
  • Day( dtNow ),
  • 18, <!--- 6 PM. --->
  • 00, <!--- 0 Minutes. --->
  • 00  <!--- 0 Seconds. --->
  • ) />
  •  
  • <cfset WriteOutput(
  • CreateODBCDateTime( dtOne )
  • ) />
  •  
  • </cfloop>
  • </cftimer>

... This runs on average at about 540 ms.

  • <cftimer label="Two" type="outline">
  • <cfloop index="intI" from="1" to="1000">
  •  
  • <cfset dtTwo = (
  • Round( dtNow ) +
  • CreateTimeSpan(
  • 0, <!--- Days. --->
  • 18, <!--- Hours. --->
  • 0, <!--- Minutes. --->
  • 0 <!--- Seconds. --->
  • )
  • ) />
  •  
  • <cfset WriteOutput(
  • CreateODBCDateTime( dtTwo )
  • ) />
  •  
  • </cfloop>
  • </cftimer>

... This runs on average at about 250 ms. This is less than have the time of the CreateDateTime() method. Who knows what is going on underneath the ColdFusion hood, but you can see that the CreateDateTime() method uses 4 function calls where as the second solution is only two method calls. Hmmmm.

  • <cftimer label="Three" type="outline">
  • <cfloop index="intI" from="1" to="1000">
  •  
  • <cfset dtThree = (
  • DateFormat( dtNow, "yyyy-mm-dd" ) &
  • " " &
  • "18:00:00"
  • ) />
  •  
  • <cfset WriteOutput(
  • CreateODBCDateTime( dtThree )
  • ) />
  •  
  • </cfloop>
  • </cftimer>

... This runs on average at about 460 ms. First off, I am SHOCKED that the string-concatenation method runs faster than the CreateDateTime() method. SHOCKED! Especially as this one uses DateFormat() which is very slow.

Well, shock or no shock, it is clear that treating the date/time object as a number and then doing math on it is going to be the fastest solution. Math always is :) But, more than fast, you have to decide for yourself which is going to make your code most readable and therefore the most maintainable. Happy coding!




Reader Comments

There are no comments posted for this web log entry.

Post A Comment

Comment Etiquette: Please do not post spam. Please keep the comments on-topic. Please do not post unrelated questions or large chunks of code. And, above all, please be nice to each other - we're trying to have a good conversation here.

Please review the following issues:

Author Name:


Author Email:

Author Website:

Comment:

Supported HTML tags for formatting: <strong>bold</strong>   <em>italic</em>   <code>code</code>







  • Help Wanted - Find Your Next ColdFusion Job
Ben Nadel's Company - Epicenter Consulting Recent Blog Comments
May 23, 2013 at 9:52 PM
Preventing Links In Standalone iPhone Applications From Opening In Mobile Safari
@Muhmmadibn Did you figure out a solution to launching PDFs? I am running into the same issues myself. There is no way to close the PDF or go back once you launch it. Thanks in advance! ... read »
May 23, 2013 at 6:06 PM
The Girl Who Broke My Heart, And Made Me A Better Person
Good day,ladies and gentle men, my name is Dr AMADI the great spell caster in Africa, i have help so many people for different kind of problems,who say there is no solution to problems on earth, that ... read »
May 23, 2013 at 4:26 PM
ColdFusion QueryAppend( qOne, qTwo )
@Heather, Glad people are still getting value out of this! ... read »
May 23, 2013 at 3:49 PM
Strange Interaction Between DeserializeJson(), ArrayContains(), And Database Values In ColdFusion
@WebManWalking, I meant the code at the bottom (not the video). I did try to experiment with an intermediary variable, like: value = users.id[ i ]; arrayContains( userIDs, value ); ... but t ... read »
May 23, 2013 at 11:06 AM
Strange Interaction Between DeserializeJson(), ArrayContains(), And Database Values In ColdFusion
@Ben, Are you talking about As Number: YES As String: YES As Java: YES? If so, that's with 3 different ways of referencing the constant 1, not users.id[1]. Query object references(*) are what seem ... read »
May 23, 2013 at 9:55 AM
Strange Interaction Between DeserializeJson(), ArrayContains(), And Database Values In ColdFusion
@Dan, According to the CF Admin, I'm running Java "1.6.0_45". As far as the DB column, in the database it's an INT. I'll see if I can dig into what CF sees it as. @WebManWalking, But h ... read »
May 23, 2013 at 9:49 AM
Strange Interaction Between DeserializeJson(), ArrayContains(), And Database Values In ColdFusion
@Ben, I think the problem is that we're used to loose typing in ColdFusion, like JavaScript. If a value is a number but it's needed in an expression to be a string, noooo problem. I've encountered ... read »
May 23, 2013 at 9:47 AM
ColdFusion QueryAppend( qOne, qTwo )
You rock! Thank you, thank you, thank you!!! ... read »
InVision App - Prototyping Made Beautiful With Prototyping Tools