improve.dk
Just another mindless drone looking for the perfect stack
posts - 217, comments - 454

SQL Server datetime rounding made easy

Written on December 13, 2006 by Mark S. Rasmussen in SQL Server: Tricks

Update: As noted in the comments, this method does not actually round, it truncates the datetime value.

As feature complete as MS SQL Server may be, it really lacks some simple datetime rounding functions. Here is a simple trick to easily round of datetimes at any precision you wish.

We will be using two builtin functions, namely the DATEADD and the DATEDIFF function.

We can round off at nearly any precision that SQL Server itself supports, for instance: Minute, Day, Hour, Day, Month, Year and so forth.

In this example I'll select the original "Created" column from the table tblHits, as well as a rounding of the Created column by the day:

SELECT Created,
	DATEADD(Day, DATEDIFF(Day, 0, Created), 0) AS CreatedDay
FROM tblHits

It'll return the following original / rounded values:
19-11-2006 22:39:27 -> 19-11-2006 00:00:00
20-11-2006 02:27:31 -> 20-11-2006 00:00:00
...

And naturally we can do the same, this time rounded by the hour:

SELECT Created,
	DATEADD(Hour, DATEDIFF(Hour, 0, Created), 0) AS CreatedHour
FROM tblHits

It'll return the following:
19-11-2006 22:39:27 -> 19-11-2006 22:39:00
20-11-2006 02:27:31 -> 20-11-2006 02:27:00
...

You could of course also do the rounding on the webserver after you've selected the database results. Sometimes though, we have to do it at the database level. For instance, if I want to know how many visitors I have per day on my blog:

SELECT COUNT(1) AS Visitors,
	DATEADD(Day, DATEDIFF(Day, 0, Created), 0) AS Date
FROM tblHits
GROUP BY DATEADD(Day, DATEDIFF(Day, 0, Created), 0)
ORDER BY Date DESC

Now, I know that this is not optimal in terms of performance since we're doing the DATEADD(DATEDIFF()) trick twice to both select it and group by it, but I've kept it this way to follow the KISS principle.

Feedback

Gravatar

ashish desai wrote on 12/15/2006 4:42 PM

Try this, its faster
today:
declare @date datetime
set @date = floor(convert(float,getdate()))
RETURN @date
yesterday:
declare @date datetime
set @date = floor(convert(float,getdate()))
set @date = dateadd(d,-1,@date)
RETURN @date
Gravatar

Mark S. Rasmussen wrote on 12/16/2006 5:42 AM

Thanks for the tip. To use it inline I guess we'd do like so:

SELECT DATEADD(d,0,FLOOR(CONVERT(float, getDate())))

But, does this allow us to round by any other parameters than days? If for instance I want the dates to be rounded by the month?
Gravatar

Will Shaver wrote on 12/18/2008 6:51 PM

None of these scripts actually ROUND, they all TRUNCATE. There's a large difference between the two.
12:55pm -> ROUND -> 1:00 pm
12:55pm -> TRUNCATE -> 12:00pm

-Will
Gravatar

Manu wrote on 8/28/2009 4:56 PM

thanks for the tip Mark, just a note the second example (rounded by the hour) should return:

19-11-2006 22:39:27 -> 19-11-2006 22:00:00
20-11-2006 02:27:31 -> 20-11-2006 02:00:00

minus the minutes, right?
Gravatar

Greg wrote on 12/17/2009 7:43 PM

These are truncating, not rounding. But I was looking for truncation anyway, so - Thanks!
Gravatar

Syed wrote on 2/11/2010 11:33 PM

Great post! I was looking for an easy truncate function. Thanks!
Gravatar

Michel wrote on 8/4/2010 3:18 PM

Nice post. Like Greg noted, it's a truncate, not a round.
I use this to find events within an interval, e.g. searching 2 minutes before the field value:

@Search > DATEADD(Minute, DATEDIFF(Minute, 0, Created) - 2, 0)

Post Comment

Name  
Email
Url
Comment
Please add 6 and 2 and type the answer here: