Ask Ben: Comparing Only Times in SQL

Posted July 11, 2006 at 9:07 AM

Tags: SQL, Ask Ben

I like what you did with getting the date part of a SQL date/time stamp. But, I need to compare just the time part of two dates. How can I get the only the time part of a date/time stamp?

Comparing times in a SQL date/time stamp has always been a bit hairy. Over time, I have found it much easier to store time outside of a date/time stamp and instead, keep it in a 5 character text field in 24-hour time format (ex. 17:30). This way, I can keep dates and time separate. Of course, that's for more simple dates where I don't need to know seconds - something I might do for an event management system. This has it's benefits but it also has limitations that I won't go into now.

But, that aside, let's say you do have your time in a date/time stamp. Getting the time portion of the date/time stamp is very similar to how we got the date portion. The difference is that this time, we only care about the post-decimal numbers, not the pre-decimal numbers. So, in order to get the time, you have to subtract the "INT" of the date/time from the FLOAT cast of the date time:

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

  • CAST(
  • (
  • -- The float cast will give us the full date
  • -- representation as a number.
  • CAST( h.date_created AS FLOAT ) -
  •  
  • -- The floor/float cast will give us just the
  • -- "date" of the date/time stamp.
  • FLOOR( CAST( h.date_created AS FLOAT ) )
  • )
  • AS DATETIME
  • )

We can't just cast the date to an INT because that will round the value. This can be confusing because in my experience, SQL does not always round when casting from FLOAT to INT... but going from DATETIME to INT, it does seem to round consistently. So that's why we do the FLOOR() of the FLOAT CAST. That equation will provide us with just the decimal part of the date/time stamp. Then, once cast back to DATETIME, you will have a date/time stamp with a constant date and the real time.

NOTE: Keep in mind that the "date" portion is still there! It's just that now, it's a constant value (whatever the zero date in the database is).

Now, before you go about casting stuff back to DATETIME, which is an extra processing step, think about what you are doing. If you are just comparing dates for greater/lesser quality, then you don't need to cast back to DATETIME since comparing the resultant decimal (from our cast-math) will yield the same outcome. Things such as selecting a record with the MAX() time or something along those lines will handle just fine using the numeric representation.

Needless to say, this is a lot of headache for a simple comparison. That is why I store my times separate when I need to utilize the time in any sort of complex fashion.

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

Pat
Apr 12, 2007 at 10:12 AM // reply »
1 Comments

F'ing Beautiful man,

I'm now able to narrow down shift info or applying the time range to each day without number crunching the app side and on top of that it decreased the number of logical reads of my stored procedure.

You rock dude. Brilliant!

Where (BL.Occurred Between @StartDate and @EndDate)
--Compare Time for Each Day
and(
--Get Time Occured Subtract Date
CAST((Cast(Occurred AS FLOAT) - FLOOR(CAST(Occurred AS FLOAT))) AS Datetime)
Between
--Get Time Only from StartDate
(CAST((Cast(@StartDate AS FLOAT) - FLOOR(CAST(@StartDate AS FLOAT)))AS Datetime))
and
--Get Time Only from EndDate
(CAST((Cast(@EndDate AS FLOAT) - FLOOR(CAST(@EndDate AS FLOAT)))AS Datetime))
)


Apr 12, 2007 at 10:16 AM // reply »
6,516 Comments

Glad that I could help :)


May 8, 2008 at 5:39 AM // reply »
1 Comments

Boomy, thanks for this mate!


Aug 27, 2009 at 1:53 AM // reply »
1 Comments

It doesn't work for some cases, try this example:

declare @endTime datetime, @selectDate datetime
set @selectDate = '2009-8-7'
set @endTime = '2009-8-9 14:30:00'
SET @endTime = CAST(cast(@selectDate as float) + (cast(@endTime as float) - FLOOR( CAST(@endTime AS FLOAT)))AS DATETIME)

It returns '2009-8-7 14:29:59.997' instead of '2009-8-7 14:30:00'


Sep 2, 2009 at 9:58 AM // reply »
6,516 Comments

@ExceptionalCase,

Yeah, it looks like you are getting a rounding error with FLOAT precision. Not sure you can do anything about that.


Post Comment  |  Ask Ben

Recent Blog Comments
Nov 21, 2009 at 6:47 PM
Hal Helms - Real World Object Oriented Development, Sarasota - Day Five
@charlie griefer, Thank you.. ... read »
Nov 21, 2009 at 5:15 PM
Using ColdFusion Structures To Remove Duplicate List Values
@Jose Galdamez, Oh heh yeah I didn't paste the whole code. I should have defined the vars -- my bad. It's fixed thou. Thanks. ... read »
Nov 21, 2009 at 4:49 PM
Styling The ColdFusion 8 WriteToBrowser CFImage Output
Great work yet again Ben! Whilst I didn't use this whole code, I copied some of your regex code for a similar problem with the lack of an alt attribute and unescaped ampersands in CFIMAGE for Railo 3 ... read »
Nov 21, 2009 at 1:13 PM
My First ColdFusion Builder Extension - Encrypting And Decrypting CFM / CFC Files
@Ben, Because I am pedantic, I just want to make sure that everyone knows there is absolutely no encryption going on. There is only encoding and obfuscation. The cfencode tool only obfuscates your C ... read »
Nov 21, 2009 at 12:28 PM
Using ColdFusion Structures To Remove Duplicate List Values
@Jody I can't seem to get your code sample to work. If you are still having problems, try this code out and see if it gets you what you wanted. <!--- Comma delimited list with various duplicates ... read »
Nov 21, 2009 at 11:03 AM
Groovy Operator Overloading Does Not Work In The ColdFusion Context
Hi Ben, Thanks for this informative post. Now I am reading ur old posts too ... read »
Nov 21, 2009 at 10:56 AM
HostMySite.com Has The Best ColdFusion Hosting
@Mehul, Yes very nice people, however several downtimes per day which was not acceptable. Hence we had to move out. I am glad you are having good luck with them so far. ... read »