<rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:trackback="http://madskills.com/public/xml/rss/module/trackback/" xmlns:wfw="http://wellformedweb.org/CommentAPI/" xmlns:slash="http://purl.org/rss/1.0/modules/slash/" xmlns:copyright="http://blogs.law.harvard.edu/tech/rss" xmlns:image="http://purl.org/rss/1.0/modules/image/">
    <channel>
        <title>DateTime Data</title>
        <link>http://weblogs.sqlteam.com/jeffs/category/283.aspx</link>
        <description>Covering the DateTime data type, and working with Dates and Times in general using T-SQL.  As always, remember:  Use the right data type, and let your front end do all the formatting.</description>
        <language>en-US</language>
        <copyright>Jeff Smith</copyright>
        <managingEditor>smith_jeffreyt@yahoo.com</managingEditor>
        <generator>Subtext Version 1.9.4.0</generator>
        <item>
            <title>Date Only and Time Only data types in SQL Server 2005 (without the CLR)</title>
            <link>http://weblogs.sqlteam.com/jeffs/archive/2007/10/31/sql-server-2005-date-time-only-data-types.aspx</link>
            <description>In &lt;a href="http://weblogs.sqlteam.com/jeffs/archive/2004/12/02/2959.aspx"&gt;this post&lt;/a&gt;, I showed a simple way to create simple but useful Date and Time user-defined data types in SQL Server 2000.  Here's how to do it in SQL Server 2005, without the need for CLR types or anything fancy.&lt;br /&gt;
&lt;br /&gt;
First, we must create two user defined data types:&lt;br /&gt;
&lt;br /&gt;
&lt;div style="margin-left: 40px;"&gt;&lt;span style="font-family: Courier New;"&gt;create type Date from dateTime&lt;/span&gt;&lt;br style="font-family: Courier New;" /&gt;
&lt;span style="font-family: Courier New;"&gt;create type Time from dateTime&lt;/span&gt;&lt;br /&gt;
&lt;/div&gt;
&lt;br /&gt;
So, internally (and externally to our clients), these types are really just DateTime.  But, we will apply some rules to these types so that the Date data type will always be constrained to a time exactly at midnight, and the the Time data type will always be at the "base date", or 1900-01-01:&lt;br /&gt;
&lt;br style="font-family: Courier New;" /&gt;
&lt;div style="margin-left: 40px;"&gt;&lt;span style="font-family: Courier New;"&gt;create rule DateOnlyRule as&lt;/span&gt;&lt;br style="font-family: Courier New;" /&gt;
&lt;span style="font-family: Courier New;"&gt;  dateAdd(dd,datediff(dd,0,@DateTime),0) = @DateTime&lt;/span&gt;&lt;br style="font-family: Courier New;" /&gt;
&lt;br style="font-family: Courier New;" /&gt;
&lt;span style="font-family: Courier New;"&gt;go&lt;/span&gt;&lt;br style="font-family: Courier New;" /&gt;
&lt;br style="font-family: Courier New;" /&gt;
&lt;span style="font-family: Courier New;"&gt;create rule TimeOnlyRule as&lt;/span&gt;&lt;br style="font-family: Courier New;" /&gt;
&lt;span style="font-family: Courier New;"&gt;  datediff(dd,0,@DateTime) = 0&lt;/span&gt;&lt;br style="font-family: Courier New;" /&gt;
&lt;span style="font-family: Courier New;"&gt;  &lt;/span&gt;&lt;br style="font-family: Courier New;" /&gt;
&lt;span style="font-family: Courier New;"&gt;go&lt;/span&gt;&lt;br /&gt;
&lt;/div&gt;
&lt;br /&gt;
Finally, we call sp_bindrule to bind the rules to the data types:&lt;br /&gt;
&lt;br /&gt;
&lt;div style="margin-left: 40px;"&gt;&lt;span style="font-family: Courier New;"&gt;EXEC sp_bindrule 'DateOnlyRule', 'Date'&lt;/span&gt;&lt;br style="font-family: Courier New;" /&gt;
&lt;span style="font-family: Courier New;"&gt;EXEC sp_bindrule 'TimeOnlyRule', 'Time'&lt;/span&gt;&lt;br style="font-family: Courier New;" /&gt;
&lt;/div&gt;
&lt;br /&gt;
That's it!  Now, we can create a table that uses our brand-new data types:&lt;br /&gt;
&lt;br /&gt;
&lt;div style="margin-left: 40px;"&gt;&lt;span style="font-family: Courier New;"&gt;create table Trans&lt;/span&gt;&lt;br style="font-family: Courier New;" /&gt;
&lt;span style="font-family: Courier New;"&gt;(&lt;br /&gt;
 TranID int identity primary key,&lt;/span&gt;&lt;br style="font-family: Courier New;" /&gt;
&lt;span style="font-family: Courier New;"&gt; TranAmount money not null,&lt;/span&gt;&lt;br style="font-family: Courier New;" /&gt;
&lt;span style="font-family: Courier New;"&gt; TranDate Date not null,&lt;/span&gt;&lt;br style="font-family: Courier New;" /&gt;
&lt;span style="font-family: Courier New;"&gt; TranTime Time not null&lt;br /&gt;
)&lt;/span&gt;&lt;br style="font-family: Courier New;" /&gt;
&lt;span style="font-family: Courier New;"&gt; &lt;/span&gt;&lt;br /&gt;
&lt;/div&gt;
Notice that TranDate and TranTime are two separate columns here.   If we try to insert data, our rules will ensure that our TranDate and TranTime columns only contain the appropriate data, and by doing so we can simply calculate TranDate + TranTime to get the transactions DateTime.&lt;br /&gt;
&lt;br /&gt;
The following inserts will succeed:&lt;br /&gt;
&lt;br /&gt;
&lt;div style="margin-left: 40px;"&gt;&lt;span style="font-family: Courier New;"&gt;insert into Trans (TranAmount, TranDate, TranTime)&lt;/span&gt;&lt;br style="font-family: Courier New;" /&gt;
&lt;span style="font-family: Courier New;"&gt;values (200, '2005-01-01', '09:00:00 AM')&lt;/span&gt;&lt;br style="font-family: Courier New;" /&gt;
&lt;br style="font-family: Courier New;" /&gt;
&lt;span style="font-family: Courier New;"&gt;insert into Trans (TranAmount, TranDate, TranTime)&lt;/span&gt;&lt;br style="font-family: Courier New;" /&gt;
&lt;span style="font-family: Courier New;"&gt;values (400, '2005-01-03', '7:50:30 PM')&lt;/span&gt;&lt;br /&gt;
&lt;/div&gt;
&lt;br /&gt;
But this will fail, since our rules are violated (getdate() returns the current date and the time):&lt;br /&gt;
&lt;br /&gt;
&lt;div style="margin-left: 40px;"&gt;&lt;span style="font-family: Courier New;"&gt;insert into Trans (TranAmount, TranDate, TranTime)&lt;/span&gt;&lt;br style="font-family: Courier New;" /&gt;
&lt;span style="font-family: Courier New;"&gt;values (200, getdate(), getdate())&lt;/span&gt;&lt;br /&gt;
&lt;/div&gt;
&lt;br /&gt;
&lt;div style="margin-left: 40px;"&gt;&lt;span style="font-family: Courier New;"&gt;Msg 513, Level 16, State 0, Line 1&lt;/span&gt;&lt;br style="font-family: Courier New;" /&gt;
&lt;span style="font-family: Courier New;"&gt;A column insert or update conflicts with a rule imposed by a previous CREATE RULE statement. The statement was terminated. The conflict occurred in database 'PlayGround', table 'dbo.Trans', column 'TranDate'.&lt;/span&gt;&lt;br style="font-family: Courier New;" /&gt;
&lt;span style="font-family: Courier New;"&gt;The statement has been terminated.&lt;/span&gt;&lt;br style="font-family: Courier New;" /&gt;
&lt;/div&gt;
&lt;br /&gt;
Finally, we can select from our table and simply add the two columns together to get each transaction's DateTime:&lt;br /&gt;
&lt;br /&gt;
&lt;div style="margin-left: 40px;"&gt;&lt;span style="font-family: Courier New;"&gt;select *, TranDate + TranTime as TranDateTime&lt;/span&gt;&lt;br style="font-family: Courier New;" /&gt;
&lt;span style="font-family: Courier New;"&gt;from Trans&lt;/span&gt;&lt;br style="font-family: Courier New;" /&gt;
&lt;br style="font-family: Courier New;" /&gt;
&lt;span style="font-family: Courier New;"&gt;TranID  TranAmount   TranDate            TranTime            TranDateTime&lt;/span&gt;&lt;br style="font-family: Courier New;" /&gt;
&lt;span style="font-family: Courier New;"&gt;------- -----------  ------------------- ------------------- -------------------&lt;/span&gt;&lt;br style="font-family: Courier New;" /&gt;
&lt;span style="font-family: Courier New;"&gt;1       200.00       2005-01-01 00:00:00 1900-01-01 09:00:00 2005-01-01 09:00:00&lt;/span&gt;&lt;br style="font-family: Courier New;" /&gt;
&lt;span style="font-family: Courier New;"&gt;2       400.00       2005-01-03 00:00:00 1900-01-01 19:50:30 2005-01-03 19:50:30&lt;/span&gt;&lt;br style="font-family: Courier New;" /&gt;
&lt;br style="font-family: Courier New;" /&gt;
&lt;span style="font-family: Courier New;"&gt;(2 row(s) affected)&lt;/span&gt;&lt;br /&gt;
&lt;/div&gt;
&lt;br /&gt;
The nice advantage of doing this is that you can quickly and efficiently select all transactions for a single day like this:&lt;br /&gt;
&lt;br /&gt;
&lt;div style="margin-left: 40px;"&gt;&lt;span style="font-family: Courier New;"&gt;select * from Trans&lt;/span&gt;&lt;br style="font-family: Courier New;" /&gt;
&lt;span style="font-family: Courier New;"&gt;where TranDate = '2005-01-01'&lt;/span&gt;&lt;br /&gt;
&lt;/div&gt;
&lt;br /&gt;
If we stored the Date and Time in the same column, we'd need to use a less efficient range:&lt;br /&gt;
&lt;br /&gt;
&lt;div style="margin-left: 40px;"&gt;&lt;span style="font-family: Courier New;"&gt;select * from Trans&lt;/span&gt;&lt;br style="font-family: Courier New;" /&gt;
&lt;span style="font-family: Courier New;"&gt;where TranDate &amp;gt;= '2005-01-01' and TranDate &amp;lt; '2005-01-02'&lt;/span&gt;&lt;br /&gt;
&lt;/div&gt;
&lt;br /&gt;
SQL 2008 does finally implement true Date and Time data types, but until then, I hope this gives you some ideas to play with. &lt;br /&gt;
&lt;br /&gt;
Notes:&lt;br /&gt;
&lt;ul&gt;
    &lt;li&gt;If you do wish to break apart DateTime data into two columns, another option is to simply use a single, standard DateTime column but then define two extra computed columns in your table, one that returns just the Date, another that returns just the Time.  Then, you can index those computed columns and reference them easily and efficiently.  If you truly wish to store just a date or just a time, however, these user defined data types are a great way to do it.  At the end of &lt;a target="_blank" href="http://www.sqlteam.com/article/using-indexed-computed-columns-to-improve-performance"&gt;this SQLTeam article&lt;/a&gt; there's a good example demonstrating this.&lt;br /&gt;
    &lt;br /&gt;
    &lt;/li&gt;
    &lt;li&gt;You could also just use the expressions for the rules in CHECK constrains on individual table columns, instead of creating the user defined data types and rules.  As &lt;a href="http://msdn2.microsoft.com/en-us/library/ms188064.aspx" target="_blank"&gt;Books On Line states&lt;/a&gt;, CREATE RULE will at some point be removed from future versions of SQL Server, so you may wish to avoid using it.  &lt;br /&gt;
    &lt;/li&gt;
&lt;/ul&gt;
&lt;span style="font-style: italic;"&gt;see also:&lt;br /&gt;
&lt;/span&gt;
&lt;ul&gt;
    &lt;li&gt;&lt;a href="../../../../jeffs/archive/2007/10/15/time-spans-durations-sql-server.aspx" title="View Entry" id="ctl00_pageContent_Editor_Results_rprSelectionList_ctl08_HyperLink1"&gt; Working with Time Spans and Durations in SQL Server&lt;/a&gt;&lt;/li&gt;
    &lt;li&gt;&lt;a href="../../../../jeffs/archive/2007/09/10/group-by-month-sql.aspx" title="View Entry"&gt;Group by Month (and other time periods)&lt;/a&gt;&lt;/li&gt;
    &lt;li&gt;&lt;a href="../../../../jeffs/archive/2007/08/29/SQL-Dates-and-Times.aspx" title="View Entry" id="ctl00_pageContent_Editor_Results_rprSelectionList_ctl08_HyperLink1"&gt;Working with Date and/or Time values in SQL Server: Don't Format, Don't Convert -- just use DATETIME&lt;/a&gt;&lt;/li&gt;
    &lt;li&gt;&lt;a href="../../../../jeffs/archive/2007/07/03/60248.aspx" title="View Entry" id="ctl00_pageContent_Editor_Results_rprSelectionList_ctl10_HyperLink1"&gt;Data Types -- The Easiest Part of Database Design&lt;/a&gt;&lt;/li&gt;
    &lt;li&gt;&lt;a href="../../../../jeffs/archive/2007/04/13/format-date-sql-server.aspx" title="View Entry" id="ctl00_pageContent_Editor_Results_rprSelectionList_ctl06_HyperLink1"&gt;How to format a Date or DateTime in SQL Server&lt;/a&gt;&lt;/li&gt;
    &lt;li&gt;&lt;a href="../../../../jeffs/archive/2004/12/02/2954.aspx" title="View Entry" id="ctl00_pageContent_Editor_Results_rprSelectionList_ctl06_HyperLink1"&gt;Breaking apart the DateTime datatype -- Separating Dates from Times in your Tables&lt;/a&gt;&lt;/li&gt;
    &lt;li&gt;&lt;a href="../../../../jeffs/archive/2007/10/31/sql-server-2005-date-time-only-data-types.aspx" title="View Entry" id="ctl00_pageContent_Editor_Results_rprSelectionList_ctl04_HyperLink1"&gt;Date Only and Time Only data types in SQL Server 2005 (without the CLR)&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;&lt;img src="http://weblogs.sqlteam.com/jeffs/aggbug/60387.aspx" width="1" height="1" /&gt;</description>
            <dc:creator>Jeff Smith</dc:creator>
            <guid>http://weblogs.sqlteam.com/jeffs/archive/2007/10/31/sql-server-2005-date-time-only-data-types.aspx</guid>
            <pubDate>Wed, 31 Oct 2007 13:13:16 GMT</pubDate>
            <wfw:comment>http://weblogs.sqlteam.com/jeffs/comments/60387.aspx</wfw:comment>
            <comments>http://weblogs.sqlteam.com/jeffs/archive/2007/10/31/sql-server-2005-date-time-only-data-types.aspx#feedback</comments>
            <slash:comments>8</slash:comments>
            <wfw:commentRss>http://weblogs.sqlteam.com/jeffs/comments/commentRss/60387.aspx</wfw:commentRss>
            <trackback:ping>http://weblogs.sqlteam.com/jeffs/services/trackbacks/60387.aspx</trackback:ping>
        </item>
        <item>
            <title> Working with Time Spans and Durations in SQL Server</title>
            <link>http://weblogs.sqlteam.com/jeffs/archive/2007/10/15/time-spans-durations-sql-server.aspx</link>
            <description>If you read this blog on a regular basis, you probably know that a frequently covered topic is &lt;a href="http://weblogs.sqlteam.com/jeffs/category/283.aspx"&gt;dates and times and the use of the DateTime data type&lt;/a&gt;.   Well, along those same lines, my latest article has just been published over at SQL Team: &lt;a style="font-weight: bold;" target="_blank" href="http://www.sqlteam.com/article/working-with-time-spans-and-durations-in-sql-server"&gt;Working with Time Spans and Durations in SQL Server&lt;/a&gt;.&lt;br /&gt;
&lt;br /&gt;
From the Article:&lt;br /&gt;
&lt;br /&gt;
&lt;div style="margin-left: 40px; font-style: italic;"&gt;What is the best way to return the "duration" of an event in SQL, given the start and end datetime values? How can we add up these durations to return grand totals? What data types should be used to return this data to our clients? How do we handle overflows, such as when hours go over 23 or minutes total up to over 59? Are there any T-SQL functions or other techniques that are useful in these scenarios?&lt;/div&gt;
&lt;br /&gt;
It is mostly targeted towards beginner SQL programmers, but even experienced programmers may find some of the ideas and tips useful.&lt;a style="font-weight: bold;" target="_blank" href="http://www.sqlteam.com/article/working-with-time-spans-and-durations-in-sql-server"&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;/a&gt;&lt;a style="font-weight: bold;" target="_blank" href="http://www.sqlteam.com/article/working-with-time-spans-and-durations-in-sql-server"&gt;Article link&lt;/a&gt;&lt;br /&gt;
&lt;span style="text-decoration: underline;"&gt;&lt;br /&gt;
&lt;/span&gt;&lt;span style="font-style: italic;"&gt;see also:&lt;br /&gt;
&lt;/span&gt;
&lt;ul&gt;
    &lt;li&gt;&lt;a id="ctl00_pageContent_Editor_Results_rprSelectionList_ctl08_HyperLink1" title="View Entry" href="../../../../jeffs/archive/2007/10/15/time-spans-durations-sql-server.aspx"&gt; Working with Time Spans and Durations in SQL Server&lt;/a&gt;&lt;/li&gt;
    &lt;li&gt;&lt;a title="View Entry" href="../../../../jeffs/archive/2007/09/10/group-by-month-sql.aspx"&gt;Group by Month (and other time periods)&lt;/a&gt;&lt;/li&gt;
    &lt;li&gt;&lt;a id="ctl00_pageContent_Editor_Results_rprSelectionList_ctl08_HyperLink1" title="View Entry" href="../../../../jeffs/archive/2007/08/29/SQL-Dates-and-Times.aspx"&gt;Working with Date and/or Time values in SQL Server: Don't Format, Don't Convert -- just use DATETIME&lt;/a&gt;&lt;/li&gt;
    &lt;li&gt;&lt;a id="ctl00_pageContent_Editor_Results_rprSelectionList_ctl10_HyperLink1" title="View Entry" href="../../../../jeffs/archive/2007/07/03/60248.aspx"&gt;Data Types -- The Easiest Part of Database Design&lt;/a&gt;&lt;/li&gt;
    &lt;li&gt;&lt;a id="ctl00_pageContent_Editor_Results_rprSelectionList_ctl06_HyperLink1" title="View Entry" href="../../../../jeffs/archive/2007/04/13/format-date-sql-server.aspx"&gt;How to format a Date or DateTime in SQL Server&lt;/a&gt;&lt;/li&gt;
    &lt;li&gt;&lt;a id="ctl00_pageContent_Editor_Results_rprSelectionList_ctl06_HyperLink1" title="View Entry" href="../../../../jeffs/archive/2004/12/02/2954.aspx"&gt;Breaking apart the DateTime datatype -- Separating Dates from Times in your Tables&lt;/a&gt;&lt;/li&gt;
    &lt;li&gt;&lt;a id="ctl00_pageContent_Editor_Results_rprSelectionList_ctl04_HyperLink1" title="View Entry" href="../../../../jeffs/archive/2007/10/31/sql-server-2005-date-time-only-data-types.aspx"&gt;Date Only and Time Only data types in SQL Server 2005 (without the CLR)&lt;/a&gt;&lt;/li&gt;
    &lt;li&gt;&lt;a title="View Entry" href="../../../../jeffs/archive/2007/01/02/56079.aspx"&gt;Essential SQL Server Date, Time and DateTime Functions&lt;/a&gt; 				 				&lt;/li&gt;
&lt;/ul&gt;&lt;img src="http://weblogs.sqlteam.com/jeffs/aggbug/60374.aspx" width="1" height="1" /&gt;</description>
            <dc:creator>Jeff Smith</dc:creator>
            <guid>http://weblogs.sqlteam.com/jeffs/archive/2007/10/15/time-spans-durations-sql-server.aspx</guid>
            <pubDate>Mon, 15 Oct 2007 13:28:43 GMT</pubDate>
            <wfw:comment>http://weblogs.sqlteam.com/jeffs/comments/60374.aspx</wfw:comment>
            <comments>http://weblogs.sqlteam.com/jeffs/archive/2007/10/15/time-spans-durations-sql-server.aspx#feedback</comments>
            <wfw:commentRss>http://weblogs.sqlteam.com/jeffs/comments/commentRss/60374.aspx</wfw:commentRss>
            <trackback:ping>http://weblogs.sqlteam.com/jeffs/services/trackbacks/60374.aspx</trackback:ping>
        </item>
        <item>
            <title>Filter by month (plus other time periods)</title>
            <link>http://weblogs.sqlteam.com/jeffs/archive/2007/09/14/sql-filter-by-month.aspx</link>
            <description>&lt;span style="font-weight: bold;"&gt;Introduction&lt;br /&gt;
&lt;br /&gt;
&lt;/span&gt;Previously, &lt;a href="http://weblogs.sqlteam.com/jeffs/archive/2007/09/10/group-by-month-sql.aspx"&gt;I wrote about grouping transactions by month&lt;/a&gt;.  Another common area of difficulty or confusion for SQL beginners is how to efficiently retrieve data just for a single month.&lt;br /&gt;
&lt;br /&gt;
There are two parts to this equation: First, what is the best way to declare parameters that will be used to indicate which month you are looking for?  Second, how can we efficiently and easily make use of those parameters to get back the data we need?&lt;br /&gt;
&lt;br /&gt;
Let's take a look at some approaches, both &lt;span style="color: rgb(0, 102, 0);"&gt;recommended &lt;/span&gt;and &lt;span style="color: rgb(128, 0, 0);"&gt;not&lt;/span&gt;.  &lt;br /&gt;
&lt;br /&gt;
And, please: if you are not using the DATETIME data type to store dates in your tables, don't even bother reading further -- fix your design first!&lt;br /&gt;
&lt;br /&gt;
&lt;span style="font-weight: bold;"&gt;Month Parameter Options &lt;/span&gt;&lt;span style="font-family: Courier New; color: rgb(128, 0, 0);"&gt; &lt;br /&gt;
&lt;br /&gt;
@YearMonth as char(6)&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
If you know me at all, you know that I will advise not to use this approach.  We’ll need to parse and validate the values passed into ensure that they are valid, and we need to somehow communicate exactly which format to use when setting the parameter values. For example, is it “MM-YY”, or “MMYYYY”, or “MM/YY”, or “YYYYMM”, etc?  It simply makes no sense to introduce string formatting conventions and parsing and validating into the equation when you simply don’t need to.  Don’t do it.&lt;br /&gt;
&lt;br /&gt;
&lt;span style="font-family: Courier New; color: rgb(0, 102, 0);"&gt; @Year as int, @Month as int&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
This approach works fine, since now we have no string parsing or ambiguity to deal with. It is very clear that Year and Month are both simply numeric values.  We can do a quick check to ensure that are @Month value is between 1 and 12, and that our @Year value is within our desired range as well.&lt;br /&gt;
&lt;br /&gt;
As we will see later, an optimal solution will require finding the first day of the month requested.  How can we do that given a @Year and a @Month value?  Simple, you can either &lt;a href="http://weblogs.sqlteam.com/jeffs/archive/2007/01/02/56079.aspx"&gt;use the Date function here&lt;/a&gt; and write:&lt;br /&gt;
&lt;br /&gt;
&lt;div style="margin-left: 40px;"&gt;&lt;span style="font-family: Courier New;"&gt;Declare @FirstDayOfMonth datetime&lt;/span&gt;&lt;br style="font-family: Courier New;" /&gt;
&lt;span style="font-family: Courier New;"&gt; Set @FirstDayOfMonth = dbo.Date(@Year,@Month,1)&lt;/span&gt;&lt;br style="font-family: Courier New;" /&gt;
&lt;/div&gt;
&lt;br /&gt;
… or you can apply the same logic using DateAdd() like this:&lt;br /&gt;
&lt;br /&gt;
&lt;div style="margin-left: 40px; font-family: Courier New;"&gt;Declare @FirstDayOfMonth datetime&lt;br /&gt;
Set @FirstDayOfMonth = dateadd(month,((@Year-1900)*12)+@Month-1,0)&lt;br /&gt;
&lt;/div&gt;
&lt;br /&gt;
Either way, the result is the same: for a given @Year and @Month, the first day of that month (at midnight) is returned.  If you aren’t sure how this formula works (or even if it will work at all), just test it out.&lt;br /&gt;
&lt;br style="color: rgb(51, 153, 102);" /&gt;
&lt;span style="color: rgb(0, 102, 0); font-family: Courier New;"&gt; @DateInMonth as datetime&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
Here, we can simply accept any datetime value, and use the year and month of that date to indicate which month should be returned.  A user can pass in the first day of the month, the last day, or any day in between – it doesn’t matter.  This works well because we know the parameter will be a valid date, and we can quickly and simply get the year/month of the @DateInMonth parameter using the Year() and Month() functions:&lt;br /&gt;
&lt;br /&gt;
&lt;div style="margin-left: 40px;"&gt;&lt;span style="font-family: Courier New;"&gt;Declare @Year int, @Month int&lt;/span&gt;&lt;br style="font-family: Courier New;" /&gt;
&lt;span style="font-family: Courier New;"&gt; Select @Year = Year(@DateInMonth), @Month = Month(@DateInMonth)&lt;/span&gt;&lt;br style="font-family: Courier New;" /&gt;
&lt;/div&gt;
&lt;br /&gt;
We can also get the first day of the month for a given @DateInMonth quite easily, using another DateAdd() trick:&lt;br /&gt;
&lt;br /&gt;
&lt;div style="margin-left: 40px;"&gt;&lt;span style="font-family: Courier New;"&gt;Declare @FirstDayOfMonth&lt;/span&gt;&lt;br style="font-family: Courier New;" /&gt;
&lt;span style="font-family: Courier New;"&gt; Set @FirstDayOfMonth = DateAdd(month, DateDiff(month,0, @DateInMonth), 0)&lt;/span&gt;&lt;br /&gt;
&lt;/div&gt;
&lt;br /&gt;
So, accepting a dateTime parameter to indicate which month you are after is also a good technique to use.&lt;br /&gt;
&lt;br /&gt;
&lt;span style="font-weight: bold;"&gt;WHERE Clause Options &lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
Now that we have the @Year, @Month and @FirstDayOfMonth values ready to go, we must decide how to use these values to write our query.   Here are some options (again, both &lt;span style="color: rgb(0, 102, 0);"&gt;good &lt;/span&gt;and &lt;span style="color: rgb(128, 0, 0);"&gt;bad&lt;/span&gt;):&lt;br /&gt;
&lt;br /&gt;
&lt;span style="font-family: Courier New; color: rgb(128, 0, 0);"&gt; where Year(TranDate) =@Year and Month(TranDate) = @Month&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
This approach will work fine, but it will not be able to use any indexes that might exist on your TranDate column.  Thus, it will not be as efficient as possible.  Every single TranDate value must be retrieved from your table, the Year() and Month() formulas must be applied, and then the results must be tested to determine if that row should be returned or not.    Overall, avoid wrapping indexable columns in functions such as these in your criteria.&lt;br /&gt;
&lt;br /&gt;
&lt;span style="font-family: Courier New; color: rgb(128, 0, 0);"&gt; where convert(varchar(6), TranDate, 112) = convert(varchar(6), @FirstDayOfMonth) &lt;/span&gt;&lt;br /&gt;
-- or --&lt;br /&gt;
&lt;span style="font-family: Courier New; color: rgb(128, 0, 0);"&gt;where convert(varchar(6), TranDate, 112) = left(@Year,4)+right('0' + left(@Month,2),2)&lt;br /&gt;
&lt;/span&gt; -- or --&lt;span style="font-family: Courier New; color: rgb(128, 0, 0);"&gt;&lt;br /&gt;
&lt;/span&gt;&lt;span style="font-family: Courier New; color: rgb(128, 0, 0);"&gt;where convert(varchar(6), TranDate, 112) = @YearMonth&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
These WHERE clauses all convert the TranDate to a VARCHAR in the format of YYYMMDD, but truncated at 6 characters, resulting in a YYYMM formatted string.  Then, using different methods, that string is compared to a YYYYMM representation of the month we'd like to return.  This is a bad approach to take because it requires that every TranDate be converted to a string in order to filter the rows, thus no indexes can be used.  Using any conversions or string manipulations to filter data when better options exist is never the way to go.   At worst, it is also very confusing to work with since it can be unclear exactly what some of these convert() functions and string expressions are doing.&lt;br /&gt;
&lt;br /&gt;
&lt;span style="font-family: Courier New; color: rgb(128, 0, 0);"&gt; where TranDate between @FirstDayOfMonth and @LastDayOfMonth&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
What if we calculate, for a given @Year and @Month, the first and last day of the month, store them in variables, and then use that range for our criteria?  This will let us use indexes, it will be clear and concise, and it makes good sense.&lt;br /&gt;
&lt;br /&gt;
However, there is a minor flaw in this logic:  Suppose @Year is 2006, and @Month is 1. If we set @LastDayOfMonth to ‘2006-01-31 12:00:00 AM’, any transactions after 12:00:00 AM on the last day of the month will not be included!  We could calculate the very last 1/300th of a millisecond on the last day of the month to use as our upper limit, but there is an even easier way ...&lt;br /&gt;
&lt;br /&gt;
&lt;span style="font-family: Courier New; color: rgb(0, 102, 0);"&gt; where TranDate &amp;gt;= @FirstDayOfMonth and TranDate &amp;lt; @FirstDayOfNextMonth&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
Here, we won’t have any issues with times other than midnight leading to missed transactions.&lt;br /&gt;
&lt;br /&gt;
We already have the @FirstDayOfMonth, all we need is the @FirstDayOfNextMonth.  That is easily obtained by using DateAdd() to add one month to the @FirstDayOfMonth, as shown:&lt;br /&gt;
&lt;br /&gt;
&lt;div style="margin-left: 40px;"&gt;&lt;span style="font-family: Courier New;"&gt;Declare @FirstDayOfNextMonth&lt;/span&gt;&lt;br style="font-family: Courier New;" /&gt;
&lt;span style="font-family: Courier New;"&gt; Set @FirstDayOfNextMonth = DateAdd(month, @FirstDayOfMonth,1)&lt;/span&gt;&lt;br /&gt;
&lt;/div&gt;
&lt;br /&gt;
With that, we are all set!  Indexes can be used and any datetime value within our range will be properly selected.  I highly recommend using this approach whenever you need to select dates for a single month; there is no need to force date computations upon all values in your table when a simple range is all you need.&lt;br /&gt;
&lt;br /&gt;
&lt;span style="font-weight: bold;"&gt;&lt;span style="font-weight: bold;"&gt;Other Time Periods&lt;br /&gt;
&lt;br /&gt;
&lt;/span&gt;&lt;/span&gt;The same approach can be applied if you need to allow for a range of months to be specified, not just a single month.  Simply calculate the first day of the&lt;span style="font-style: italic;"&gt; starting &lt;/span&gt;month, and then calculate the first day of the month &lt;span style="font-style: italic;"&gt;after &lt;/span&gt;the &lt;span style="font-style: italic;"&gt;ending &lt;/span&gt;month.  Then, you can use that date range to filter your data as shown above.  &lt;br /&gt;
&lt;br /&gt;
You should also follow these same guidelines if you'd like to filter data by a specified year, quarter, or week.  "Year-to-date" filtering will also work the exact same way.&lt;br /&gt;
&lt;span style="font-weight: bold;"&gt;&lt;span style="font-weight: bold;"&gt;&lt;/span&gt;&lt;br /&gt;
Conclusion &lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
At the end of the day, accomplishing our task is very simple:&lt;br /&gt;
&lt;br /&gt;
1.    Accept either @Year and @Month parameters or a single @DateInMonth parameter to indicate which month should be returned&lt;br /&gt;
2.    Calculate the @FirstDayOfMonth and the @FirstDayOfNextMonth using those parameters&lt;br /&gt;
3.    Select your rows with a WHERE clause that returns transaction dates equal to or greater than @FirstDayOfMonth, and less than @FirstDayOfNextMonth, to ensure that all dates at the end of your range are captured and that indexes can be used.&lt;br /&gt;
&lt;br /&gt;
Good luck, and remember: Declare your parameters to be clear and precise, and write your WHERE clauses to be as efficient and accurate as possible.&lt;br /&gt;
&lt;br /&gt;
&lt;span style="font-style: italic;"&gt;&lt;span style="font-style: italic;"&gt;see also:&lt;br /&gt;
&lt;/span&gt;
&lt;ul&gt;
    &lt;li&gt;&lt;a href="../../../../jeffs/archive/2007/10/15/time-spans-durations-sql-server.aspx" title="View Entry" id="ctl00_pageContent_Editor_Results_rprSelectionList_ctl08_HyperLink1"&gt; Working with Time Spans and Durations in SQL Server&lt;/a&gt;&lt;/li&gt;
    &lt;li&gt;&lt;a href="../../../../jeffs/archive/2007/09/10/group-by-month-sql.aspx" title="View Entry"&gt;Group by Month (and other time periods)&lt;/a&gt;&lt;/li&gt;
    &lt;li&gt;&lt;a href="../../../../jeffs/archive/2007/08/29/SQL-Dates-and-Times.aspx" title="View Entry" id="ctl00_pageContent_Editor_Results_rprSelectionList_ctl08_HyperLink1"&gt;Working with Date and/or Time values in SQL Server: Don't Format, Don't Convert -- just use DATETIME&lt;/a&gt;&lt;/li&gt;
    &lt;li&gt;&lt;a href="../../../../jeffs/archive/2007/07/03/60248.aspx" title="View Entry" id="ctl00_pageContent_Editor_Results_rprSelectionList_ctl10_HyperLink1"&gt;Data Types -- The Easiest Part of Database Design&lt;/a&gt;&lt;/li&gt;
    &lt;li&gt;&lt;a href="../../../../jeffs/archive/2007/04/13/format-date-sql-server.aspx" title="View Entry" id="ctl00_pageContent_Editor_Results_rprSelectionList_ctl06_HyperLink1"&gt;How to format a Date or DateTime in SQL Server&lt;/a&gt;&lt;/li&gt;
    &lt;li&gt;&lt;a href="../../../../jeffs/archive/2004/12/02/2954.aspx" title="View Entry" id="ctl00_pageContent_Editor_Results_rprSelectionList_ctl06_HyperLink1"&gt;Breaking apart the DateTime datatype -- Separating Dates from Times in your Tables&lt;/a&gt;&lt;/li&gt;
    &lt;li&gt;&lt;a href="../../../../jeffs/archive/2007/10/31/sql-server-2005-date-time-only-data-types.aspx" title="View Entry" id="ctl00_pageContent_Editor_Results_rprSelectionList_ctl04_HyperLink1"&gt;Date Only and Time Only data types in SQL Server 2005 (without the CLR)&lt;/a&gt;&lt;/li&gt;
    &lt;li&gt;&lt;a href="../../../../jeffs/archive/2007/01/02/56079.aspx" title="View Entry"&gt;Essential SQL Server Date, Time and DateTime Functions&lt;/a&gt; 				 				&lt;/li&gt;
&lt;/ul&gt;
&lt;/span&gt;&lt;img src="http://weblogs.sqlteam.com/jeffs/aggbug/60326.aspx" width="1" height="1" /&gt;</description>
            <dc:creator>Jeff Smith</dc:creator>
            <guid>http://weblogs.sqlteam.com/jeffs/archive/2007/09/14/sql-filter-by-month.aspx</guid>
            <pubDate>Fri, 14 Sep 2007 16:21:07 GMT</pubDate>
            <wfw:comment>http://weblogs.sqlteam.com/jeffs/comments/60326.aspx</wfw:comment>
            <comments>http://weblogs.sqlteam.com/jeffs/archive/2007/09/14/sql-filter-by-month.aspx#feedback</comments>
            <slash:comments>5</slash:comments>
            <wfw:commentRss>http://weblogs.sqlteam.com/jeffs/comments/commentRss/60326.aspx</wfw:commentRss>
            <trackback:ping>http://weblogs.sqlteam.com/jeffs/services/trackbacks/60326.aspx</trackback:ping>
        </item>
        <item>
            <title>Group by Month (and other time periods)</title>
            <link>http://weblogs.sqlteam.com/jeffs/archive/2007/09/10/group-by-month-sql.aspx</link>
            <description>When you need to summarize transactional data by Month, there are several ways to do it, some better than others.  What to ultimately choose depends on your needs, but remember: Keep it short and simple in T-SQL, and always do all of your formatting at your presentation layer where it belongs.  &lt;a href="http://weblogs.sqlteam.com/jeffs/archive/2007/09/10/group-by-month-sql.aspx"&gt;read more...&lt;/a&gt;&lt;img src="http://weblogs.sqlteam.com/jeffs/aggbug/60324.aspx" width="1" height="1" /&gt;</description>
            <dc:creator>Jeff Smith</dc:creator>
            <guid>http://weblogs.sqlteam.com/jeffs/archive/2007/09/10/group-by-month-sql.aspx</guid>
            <pubDate>Mon, 10 Sep 2007 15:28:56 GMT</pubDate>
            <wfw:comment>http://weblogs.sqlteam.com/jeffs/comments/60324.aspx</wfw:comment>
            <comments>http://weblogs.sqlteam.com/jeffs/archive/2007/09/10/group-by-month-sql.aspx#feedback</comments>
            <slash:comments>28</slash:comments>
            <wfw:commentRss>http://weblogs.sqlteam.com/jeffs/comments/commentRss/60324.aspx</wfw:commentRss>
            <trackback:ping>http://weblogs.sqlteam.com/jeffs/services/trackbacks/60324.aspx</trackback:ping>
        </item>
        <item>
            <title>SQL Server 2008 - Enhancements in Date and Time Data Types (link)</title>
            <link>http://weblogs.sqlteam.com/jeffs/archive/2007/08/30/sql-2008-date-and-time-enhancements.aspx</link>
            <description>Speaking of &lt;a href="http://weblogs.sqlteam.com/jeffs/archive/2007/08/29/SQL-Dates-and-Times.aspx"&gt;dates and times&lt;/a&gt;, there's a nice post from &lt;a target="_blank" href="http://blogs.msdn.com/manisblog/default.aspx"&gt;Ravi. S. Maniam&lt;/a&gt; over at the &lt;a target="_blank" href="http://blogs.msdn.com"&gt;msdn blogs&lt;/a&gt; regarding the new and exciting &lt;a target="_blank" href="http://blogs.msdn.com/manisblog/archive/2007/08/28/sql-server-2008-enhancements-in-date-and-time-data-types.aspx"&gt;Enhancements in Date and Time Data Types for SQL Server 2008&lt;/a&gt;.&lt;br /&gt;
&lt;br /&gt;
It will be very interesting to see how date and time usage changes once SQL Server 2008 becomes the most commonly used edition.  Of course, since even SQL 2005 still doesn't seem to be as widely adopted as I would like, who knows when that will be!&lt;img src="http://weblogs.sqlteam.com/jeffs/aggbug/60315.aspx" width="1" height="1" /&gt;</description>
            <dc:creator>Jeff Smith</dc:creator>
            <guid>http://weblogs.sqlteam.com/jeffs/archive/2007/08/30/sql-2008-date-and-time-enhancements.aspx</guid>
            <pubDate>Fri, 31 Aug 2007 02:05:02 GMT</pubDate>
            <wfw:comment>http://weblogs.sqlteam.com/jeffs/comments/60315.aspx</wfw:comment>
            <comments>http://weblogs.sqlteam.com/jeffs/archive/2007/08/30/sql-2008-date-and-time-enhancements.aspx#feedback</comments>
            <slash:comments>1</slash:comments>
            <wfw:commentRss>http://weblogs.sqlteam.com/jeffs/comments/commentRss/60315.aspx</wfw:commentRss>
            <trackback:ping>http://weblogs.sqlteam.com/jeffs/services/trackbacks/60315.aspx</trackback:ping>
        </item>
        <item>
            <title>Working with Date and/or Time values in SQL Server: Don't Format, Don't Convert -- just use DATETIME</title>
            <link>http://weblogs.sqlteam.com/jeffs/archive/2007/08/29/SQL-Dates-and-Times.aspx</link>
            <description>&lt;span style="font-weight: bold;"&gt;The Importance of Data Types&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
Imagine that SQL Server only provided two data types:  the MONEY data type to store numeric values, and VARCHAR to store text. &lt;br /&gt;
&lt;br /&gt;
If you are designing a database in this scenario and you need to store or return integer values, which data type -- MONEY or VARCHAR -- would you use?&lt;br /&gt;
&lt;br /&gt;
Suppose I were to argue that MONEY is too complicated, and a waste of space, since all MONEY values always have 4 digits after the decimal which we don't need and it might get confusing.  Therefore, we should use VARCHAR, which is much simpler.  After all, if we use MONEY, every time we execute a SELECT, our integer data will be returned with 4 decimal places like "45.0000", which is certainly not what we want and doesn’t &lt;span style="font-style: italic;"&gt;look &lt;/span&gt;like an integer; but if we use VARCHAR we will get "45" which looks much better and is really what we want to see.  While eventually we will notice that we cannot add these VARCHAR numbers together, or sort them, or compare them, or do any kind of math with them, we can always temporarily convert those values to MONEY if we need to do these things, right?   And as for ensuring that we only store valid numbers in our VARCHAR columns, we can handle that with some complicated CHECK expressions that parses the string to ensure that it stores only valid digits.  We also need to make sure that everyone is aware of the rules for the format of integer data in our VARCHAR columns, to avoid problems as well: after all, we may wish to store values like 34934 as "34,942" so that it looks just right when the values are returned and is easier to work with.  &lt;br /&gt;
&lt;br /&gt;
Now, if I make this argument to you, what would you say?  Would you think it's a good idea?&lt;br /&gt;
&lt;br /&gt;
I think we can all agree that a much better approach would be to use MONEY. Now we can add, sort, compare, do math, and all kinds of things on our values which are stored as numeric data, not text.  We can add a quick, simple CHECK constraint to ensure that our MONEY values have nothing stored after the decimal (e.g., &lt;span style="font-family: Courier New;"&gt;CHECK round(value,0) = value&lt;/span&gt;), and we simply let our front end format those numbers without any decimal places.  In this scenario, it's probably fair to say that no reasonable programmer would argue that VARCHARs are better for working with integers than a true, numeric data type like MONEY. &lt;br /&gt;
&lt;br /&gt;
&lt;span style="font-weight: bold;"&gt;Manipulate and Return Data -- not Strings&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
If we agree to use the MONEY data type, wouldn't it make sense to keep those values as MONEY throughout our T-SQL code, and only return MONEY values to the clients?  We wouldn't want to try to convert our MONEY values to VARCHAR in our database code just so that things "look good" and we "don't see" that pesky little ".0000" after each value, right?  It means nothing to us, it doesn’t affect our data, so we simply store and work with and return MONEY in &lt;span style="font-style: italic;"&gt;all &lt;/span&gt;of our database code and we don't worry about formatting or how things "look" or the extra decimal places that we aren't using.  This keeps our code short, clear, easy to read since we are not converting things back and forth between VARCHAR and MONEY over and over to make things "look good" in one spot but to make them “work correctly” in another.&lt;br /&gt;
&lt;br /&gt;
Along those same lines, suppose we have a MONEY value like this:&lt;br /&gt;
&lt;br /&gt;
&lt;div style="margin-left: 40px;"&gt; 1846.4069&lt;br /&gt;
&lt;/div&gt;
&lt;br /&gt;
... and we need to return that value as an integer.  What should we return, a VARCHAR value or a MONEY value?  The VARCHAR value of "1846" will &lt;span style="font-style: italic;"&gt;look &lt;/span&gt;nice, but again: we cannot sort, compare or do anything with it -- it is just a picture of data, not actual data.  If we return a MONEY value of 1846.0000, we can and should ignore the decimal portion since it does not affect anything and enjoy the benefit of returning an actual numeric value that both the database and the client can sort, compare, calculate, and so on.&lt;br /&gt;
&lt;br /&gt;
If you don't agree with any of that, stop reading now and let me know in the comments.  Otherwise, let's continue on ...&lt;br /&gt;
&lt;br /&gt;
&lt;span style="font-weight: bold;"&gt;Another Obvious Example&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
What about if we want to store only values that are decimals, such as .0234 or .963?  These values will never have any digits before the decimal, but will always have one to four digits after the decimal (we only need 4 digits of precision).  That is, we are storing values from -.9999 to .9999 only.   With only MONEY and VARCHAR available, what data type should we use to store and work with these values?&lt;br /&gt;
&lt;br /&gt;
Once again, suppose I argue that VARCHAR is the way to go.  After all, if we use MONEY, every value will be preceded by "0.", which is not what we want and again a waste of space.  We don't need the integer portion, and having it returned and seeing it everywhere will be confusing.  If we use VARCHAR it will always look perfect, and we again can use CHECK constraints that parse the string to ensure we have valid data.  Things still don’t sort or compare or calculate, but we can CONVERT back and forth as needed. &lt;br /&gt;
&lt;br /&gt;
Yet once again, I would hope that you will agree that the suggestion to use VARCHAR is not a good one.  We should use a numeric data type, and therefore MONEY is the best choice.  It handles our data perfectly with the accuracy we need, we can do math, sort, and compare.  We know that it will be valid and accurate, and a simple CHECK constraint ensures that we only have values between -.9999 and .9999 as opposed to using string parsing to determine this.  And, again, even though in the T-SQL world all of our money values have an integer portion of “0” attached to them, it should make sense that we should not worry about this since our data is accurate and correct, it doesn't affect calculations, and the client can output these decimals without the preceding “0” very easily.  &lt;br /&gt;
&lt;br /&gt;
This also affects doing some math on a value like 139.592 to return only the decimal portion; for all of the reasons stated, we should all agree that the value to return is a MONEY value of 0.5920 and &lt;span style="font-style: italic;"&gt;not&lt;/span&gt; a VARCHAR value of ".5920".&lt;br /&gt;
&lt;br /&gt;
Finally, if we always store and return MONEY for&lt;span style="font-style: italic;"&gt; both&lt;/span&gt; our integer values and our decimal values, we have another huge benefit:  we can do math on both of those values &lt;span style="font-style: italic;"&gt;together &lt;/span&gt;and get accurate, consistent results.  No conversions, no string manipulation or parsing or concatenation, no worrying about how things are formatted or stored or how they look; we can do simple, efficient and accurate math on all of our data with standard mathematical operations and it just works perfectly and intuitively.&lt;br /&gt;
&lt;br /&gt;
&lt;span style="font-weight: bold;"&gt;Getting to the Point (Finally!)&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
Are we all agreed on the above?  Good.  So, then, what’s my point?&lt;br /&gt;
&lt;br /&gt;
&lt;span style="font-style: italic;"&gt;Shouldn't we follow the exact same logic and reasoning when &lt;/span&gt;&lt;span style="font-style: italic;"&gt;storing &lt;/span&gt;&lt;span style="font-style: italic;"&gt;&lt;span style="font-weight: bold;"&gt;date &lt;/span&gt;and &lt;span style="font-weight: bold;"&gt;time &lt;/span&gt;data?&lt;/span&gt;&lt;br /&gt;
&lt;span style="font-weight: bold;"&gt;&lt;br /&gt;
&lt;/span&gt;The exact same scenario happens every day, only programmers are deciding how to store or return dates without times, or times without dates.  Yet, very often we see beginners choosing to store their values as VARCHARs and/or return them and manipulate them as VARCHARs, instead of using the easiest, most obvious and appropriate data type: DATETIME.  &lt;br /&gt;
&lt;span style="font-weight: bold;"&gt;&lt;br /&gt;
Working with Date-Only Data&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
If you need to store just a date, use a DATETIME.  Don’t worry about the “extra” time that is stored, just enforce that it is always midnight and it won’t affect anything – just like forcing a decimal to be “.000” and ignoring it!  It is the &lt;span style="font-style: italic;"&gt;exact &lt;/span&gt;same logic.  And, by that same token, &lt;span style="font-style: italic;"&gt;don’t worry about that time being there and feel you need to convert everything to VARCHAR to make it “look” right. &lt;/span&gt; Just use data in the proper type throughout your SQL code, ignore the time portion, and return the DATETIME value – in the correct type – to your clients.  Don’t try to “help” them by converting those nice, accurate, and clean DATETIME values to a string to “hide” the time part – just return the value, just as you would not try to “hide” a decimal portion of “.000” in a numeric by converting it to a string.&lt;br /&gt;
&lt;br /&gt;
Luckily, many programmers do indeed use DateTime when all they want to store is dates, but of course many do obsess about “hiding” that time portion.  Don’t do it.  Leave your data in the proper type, enforce a time of only midnight with a simple check constraint (e.g., &lt;span style="font-family: Courier New;"&gt;CHECK dateAdd(dd,datediff(dd,0,yourdate),0) = yourdate&lt;/span&gt;) and now you can compare, sort, do math, and everything else you ever need on those values, and your client can do the same.  Just as you would use a MONEY data type to store numeric data, if you had to, as opposed to a VARCHAR.  It’s easier, shorter, and more efficient – it just makes sense. &lt;br /&gt;
&lt;br /&gt;
The same concept applies if you have a DATETIME value like "5/6/2007 5:00 PM" and you'd like to return just the date portion:  Should you return a VARCHAR or a DATETIME?  For all of the reasons stated, it should be clear that you simply return a DATETIME value a midnight -- "5/6/2007 12:00AM" -- knowing that the time portion is now "zero" and even though it is there and we see it, it does not affect any calculations and can easily be excluded when the client presents the data.&lt;br /&gt;
&lt;br /&gt;
To "round" a DATETIME so that the time at midnight is returned:&lt;br /&gt;
&lt;br /&gt;
&lt;div style="margin-left: 40px;"&gt;&lt;span style="font-family: Courier New;"&gt;select dateadd(dd,0, datediff(dd,0, &lt;span style="font-style: italic;"&gt;datetimeval&lt;/span&gt;)) as date_at_midnight&lt;/span&gt;&lt;/div&gt;
&lt;br /&gt;
&lt;span style="font-weight: bold;"&gt;Working with Time-Only Data&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
Now, what about storing only a Time?  Here’s where people &lt;span style="font-style: italic;"&gt;really &lt;/span&gt;get confused, but, again, &lt;span style="font-style: italic;"&gt;it is exactly the same as storing a value between -.9999 and .9999 in either MONEY or a VARCHAR&lt;/span&gt;.   We agreed to use MONEY, and simply accept the fact that our integer portion of “0” is &lt;span style="font-style: italic;"&gt;always &lt;/span&gt;there, but it doesn’t affect anything; we can simply ignore it and let our client worry about not displaying it.  Remember, when storing a true decimal value, we had no choice – that zero was always there, whether we displayed it or not, right?  Well, DATETIME values have the &lt;span style="font-style: italic;"&gt;exact &lt;/span&gt;same concept!  The decimal portion of a DATETIME is the time component, and even though we just want to store time values, a DATETIME works perfectly for us.  We simply ensure that we store a 0 value as the date portion and we &lt;span style="font-style: italic;"&gt;ignore it&lt;/span&gt;!  &lt;br /&gt;
&lt;br /&gt;
For DATETIME data, a date of “0” that doesn’t affect any calculations is “1/1/1900”, just as a time of “0” that doesn’t affect any calculations is “12:00:00 AM”.  Thus, “1/1/1900 12:00:00AM” is the equivalent to a decimal value of 0.0 -- adding or subtracting that value to other values will not have any effect. &lt;br /&gt;
&lt;br /&gt;
In fact, take a look at this:&lt;br /&gt;
&lt;br /&gt;
&lt;div style="margin-left: 40px;"&gt;&lt;span style="font-family: Courier New;"&gt;select cast(0.0 as datetime) as ZeroDateTime&lt;br /&gt;
&lt;br /&gt;
ZeroDateTime&lt;br /&gt;
-----------------------&lt;br /&gt;
1900-01-01 00:00:00.000&lt;br /&gt;
&lt;br /&gt;
(1 row(s) affected)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
select getdate() as Now, getdate() + '1/1/1900 12:00:00 AM' as NowPlusZeroDateTime&lt;br /&gt;
                        &lt;br /&gt;
Now                     NowPlusZeroDateTime&lt;br /&gt;
----------------------- -----------------------&lt;br /&gt;
2007-08-30 20:55:48.513 2007-08-30 20:55:48.513&lt;br /&gt;
&lt;br /&gt;
(1 row(s) affected)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;/span&gt;&lt;/div&gt;
Notice that the numeric value of 0.0 is converted nicely to '1/1/1900 12:00:00 AM', and that adding '1/1/1900 12:00:00 AM' to a DATETIME value has no effect.&lt;br /&gt;
&lt;br /&gt;
So, if we want to store &lt;span style="font-style: italic;"&gt;only &lt;/span&gt;a time, without a date, we just:&lt;br /&gt;
&lt;ul&gt;
    &lt;li&gt;Use a DATETIME data type&lt;/li&gt;
    &lt;li&gt;Ensure that the date value of that time is 0 (that is, "1/1/1900") with a check constraint (e.g., &lt;span style="font-family: Courier New;"&gt;CHECK datediff(dd,0,TransTime) = 0&lt;/span&gt;)&lt;/li&gt;
    &lt;li&gt;Ignore the date in our SQL code even though we might “see it” here and there&lt;/li&gt;
    &lt;li&gt;Keep our data in the correct data type throughout our code without worrying how it “looks” and trying to “hide” the date part&lt;/li&gt;
    &lt;li&gt;Return that DATETIME value to our client and let it worry about hiding the “1/1/1900”, just as we let the client worry about hiding the preceding “0.” in a decimal value such as 0.2394.&lt;/li&gt;
&lt;/ul&gt;
Once again, let's consider what to do if we have a DATETIME value with such as "6/1/2007 5:00 PM" and we'd like to just return the time portion: Do we return a VARCHAR or a DATETIME?  By now, the answer should be clear:  we return data in the correct type, DATETIME, and we simply use the "0" date of 1/1/1900 by returning "1/1/1900 5:00 PM" knowing that the date portion will not affect the time value just as a an integer portion of 0 will not affect a decimal value.&lt;br /&gt;
&lt;br /&gt;
To return just the time portion of a DATETIME (i.e., at the base date of 1/1/1900):&lt;br /&gt;
&lt;br /&gt;
&lt;div style="margin-left: 40px;"&gt;&lt;span style="font-family: Courier New;"&gt;select &lt;span style="font-style: italic;"&gt;datetimeval &lt;/span&gt;- dateadd(dd,0, datediff(dd,0, &lt;span style="font-style: italic;"&gt;datetimeval&lt;/span&gt;)) as time_at_base_date&lt;/span&gt;&lt;br /&gt;
&lt;/div&gt;
&lt;br /&gt;
Finally, just as in our previous MONEY example,  if we exclusively work with dates and times using the correct DATETIME data type throughout our schema and our SQL code, we can simply add values together to combine a date and a time using simple math:&lt;br /&gt;
&lt;br /&gt;
  &lt;span style="font-family: Courier New;"&gt;    select &lt;span style="font-style: italic;"&gt;somedate &lt;/span&gt;+ &lt;span style="font-style: italic;"&gt;sometime &lt;/span&gt;as &lt;span style="font-style: italic;"&gt;somedatetime&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
No converting, no string manipulations or parsing, no worrying about AM or PM or time formats or anything.  If we keep our data in the correct types, and constraint it properly, everything works as it should – quickly, accurately, and intuitively.&lt;br /&gt;
&lt;br /&gt;
&lt;span style="font-weight: bold;"&gt;Conclusion&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
The next time you are working with dates and times, please remember: how would you handle things if you were working with integers and decimals?  The same logic and reasoning applies.  Be smart, let SQL do the work for you and use the right data types for the job, even if things don't always "look" right.  It's not about how good your data &lt;span style="font-style: italic;"&gt;looks&lt;/span&gt;, it's about how accurate it actually &lt;span style="font-style: italic;"&gt;is&lt;/span&gt;.&lt;br /&gt;
&lt;br /&gt;
&lt;span style="font-style: italic;"&gt;see also:&lt;br /&gt;
&lt;/span&gt;
&lt;ul&gt;
    &lt;li&gt;&lt;a href="../../../../jeffs/archive/2007/10/15/time-spans-durations-sql-server.aspx" title="View Entry" id="ctl00_pageContent_Editor_Results_rprSelectionList_ctl08_HyperLink1"&gt; Working with Time Spans and Durations in SQL Server&lt;/a&gt;&lt;/li&gt;
    &lt;li&gt;&lt;a href="../../../../jeffs/archive/2007/09/10/group-by-month-sql.aspx" title="View Entry"&gt;Group by Month (and other time periods)&lt;/a&gt;&lt;/li&gt;
    &lt;li&gt;&lt;a href="../../../../jeffs/archive/2007/08/29/SQL-Dates-and-Times.aspx" title="View Entry" id="ctl00_pageContent_Editor_Results_rprSelectionList_ctl08_HyperLink1"&gt;Working with Date and/or Time values in SQL Server: Don't Format, Don't Convert -- just use DATETIME&lt;/a&gt;&lt;/li&gt;
    &lt;li&gt;&lt;a href="../../../../jeffs/archive/2007/07/03/60248.aspx" title="View Entry" id="ctl00_pageContent_Editor_Results_rprSelectionList_ctl10_HyperLink1"&gt;Data Types -- The Easiest Part of Database Design&lt;/a&gt;&lt;/li&gt;
    &lt;li&gt;&lt;a href="../../../../jeffs/archive/2007/04/13/format-date-sql-server.aspx" title="View Entry" id="ctl00_pageContent_Editor_Results_rprSelectionList_ctl06_HyperLink1"&gt;How to format a Date or DateTime in SQL Server&lt;/a&gt;&lt;/li&gt;
    &lt;li&gt;&lt;a href="../../../../jeffs/archive/2004/12/02/2954.aspx" title="View Entry" id="ctl00_pageContent_Editor_Results_rprSelectionList_ctl06_HyperLink1"&gt;Breaking apart the DateTime datatype -- Separating Dates from Times in your Tables&lt;/a&gt;&lt;/li&gt;
    &lt;li&gt;&lt;a href="../../../../jeffs/archive/2007/10/31/sql-server-2005-date-time-only-data-types.aspx" title="View Entry" id="ctl00_pageContent_Editor_Results_rprSelectionList_ctl04_HyperLink1"&gt;Date Only and Time Only data types in SQL Server 2005 (without the CLR)&lt;/a&gt;&lt;/li&gt;
    &lt;li&gt;&lt;a href="../../../../jeffs/archive/2007/01/02/56079.aspx" title="View Entry"&gt;Essential SQL Server Date, Time and DateTime Functions&lt;/a&gt; 				 				&lt;/li&gt;
&lt;/ul&gt;&lt;img src="http://weblogs.sqlteam.com/jeffs/aggbug/60309.aspx" width="1" height="1" /&gt;</description>
            <dc:creator>Jeff Smith</dc:creator>
            <guid>http://weblogs.sqlteam.com/jeffs/archive/2007/08/29/SQL-Dates-and-Times.aspx</guid>
            <pubDate>Wed, 29 Aug 2007 14:04:02 GMT</pubDate>
            <wfw:comment>http://weblogs.sqlteam.com/jeffs/comments/60309.aspx</wfw:comment>
            <comments>http://weblogs.sqlteam.com/jeffs/archive/2007/08/29/SQL-Dates-and-Times.aspx#feedback</comments>
            <slash:comments>18</slash:comments>
            <wfw:commentRss>http://weblogs.sqlteam.com/jeffs/comments/commentRss/60309.aspx</wfw:commentRss>
            <trackback:ping>http://weblogs.sqlteam.com/jeffs/services/trackbacks/60309.aspx</trackback:ping>
        </item>
        <item>
            <title>Data Types -- The Easiest Part of Database Design</title>
            <link>http://weblogs.sqlteam.com/jeffs/archive/2007/07/03/60248.aspx</link>
            <description>I see it time and time again in forums -- "dates" that don't sort properly, "numbers" that don't add correctly, "boolean" data with 10 different values, and so on ... Since we are rarely provided any DDL to review, it often takes many posts going back and forth until we finally realize: "wait ... you aren't using a datetime data type to store these dates?!"  &lt;a href="http://weblogs.sqlteam.com/jeffs/archive/2007/07/03/60248.aspx"&gt;read more...&lt;/a&gt;&lt;img src="http://weblogs.sqlteam.com/jeffs/aggbug/60248.aspx" width="1" height="1" /&gt;</description>
            <dc:creator>Jeff Smith</dc:creator>
            <guid>http://weblogs.sqlteam.com/jeffs/archive/2007/07/03/60248.aspx</guid>
            <pubDate>Tue, 03 Jul 2007 14:13:12 GMT</pubDate>
            <wfw:comment>http://weblogs.sqlteam.com/jeffs/comments/60248.aspx</wfw:comment>
            <comments>http://weblogs.sqlteam.com/jeffs/archive/2007/07/03/60248.aspx#feedback</comments>
            <slash:comments>8</slash:comments>
            <wfw:commentRss>http://weblogs.sqlteam.com/jeffs/comments/commentRss/60248.aspx</wfw:commentRss>
            <trackback:ping>http://weblogs.sqlteam.com/jeffs/services/trackbacks/60248.aspx</trackback:ping>
        </item>
        <item>
            <title>SQL Data Modeling: Entities versus Attributes</title>
            <link>http://weblogs.sqlteam.com/jeffs/archive/2007/06/19/60238.aspx</link>
            <description>There’s a handy little rule of thumb I use when developing my database models.  It comes up often in situations like this:  If we are storing phone numbers in the database, should AreaCode be a “free-form” char(3) column?  Or should it be a foreign key reference to an AreaCodes table?  &lt;a href="http://weblogs.sqlteam.com/jeffs/archive/2007/06/19/60238.aspx"&gt;read more...&lt;/a&gt;&lt;img src="http://weblogs.sqlteam.com/jeffs/aggbug/60238.aspx" width="1" height="1" /&gt;</description>
            <dc:creator>Jeff Smith</dc:creator>
            <guid>http://weblogs.sqlteam.com/jeffs/archive/2007/06/19/60238.aspx</guid>
            <pubDate>Tue, 19 Jun 2007 15:47:37 GMT</pubDate>
            <wfw:comment>http://weblogs.sqlteam.com/jeffs/comments/60238.aspx</wfw:comment>
            <comments>http://weblogs.sqlteam.com/jeffs/archive/2007/06/19/60238.aspx#feedback</comments>
            <slash:comments>2</slash:comments>
            <wfw:commentRss>http://weblogs.sqlteam.com/jeffs/comments/commentRss/60238.aspx</wfw:commentRss>
            <trackback:ping>http://weblogs.sqlteam.com/jeffs/services/trackbacks/60238.aspx</trackback:ping>
        </item>
        <item>
            <title>SQL Challenge Response: Finding Consecutive Available Blocks in a Schedule</title>
            <link>http://weblogs.sqlteam.com/jeffs/archive/2007/05/15/60207.aspx</link>
            <description>Here's my response to a SQL Challenge, regarding how to find consecutive free time slots in a schedule.  This can sometimes be tricky to solve in SQL, but using either of the two techniques shown here, it is actually pretty easy.  &lt;b&gt;(Updated to show 2 possible solutions)&lt;/b&gt;
&lt;br&gt;
&lt;br&gt;&lt;a href="http://weblogs.sqlteam.com/jeffs/archive/2007/05/15/60207.aspx"&gt;read more...&lt;/a&gt;&lt;img src="http://weblogs.sqlteam.com/jeffs/aggbug/60207.aspx" width="1" height="1" /&gt;</description>
            <dc:creator>Jeff Smith</dc:creator>
            <guid>http://weblogs.sqlteam.com/jeffs/archive/2007/05/15/60207.aspx</guid>
            <pubDate>Tue, 15 May 2007 13:52:20 GMT</pubDate>
            <comments>http://weblogs.sqlteam.com/jeffs/archive/2007/05/15/60207.aspx#feedback</comments>
            <slash:comments>5</slash:comments>
            <wfw:commentRss>http://weblogs.sqlteam.com/jeffs/comments/commentRss/60207.aspx</wfw:commentRss>
            <trackback:ping>http://weblogs.sqlteam.com/jeffs/services/trackbacks/60207.aspx</trackback:ping>
        </item>
        <item>
            <title>How to format a Date or DateTime in SQL Server</title>
            <link>http://weblogs.sqlteam.com/jeffs/archive/2007/04/13/format-date-sql-server.aspx</link>
            <description>Everything you ever wanted to know about how to use SQL Server's advanced features to format Dates into any format that you need!  Here, for the first time, all in one place, is the secret that no one wants you know about how easy it is to format data in T-SQL! &lt;br&gt;&lt;br&gt;&lt;a href="http://weblogs.sqlteam.com/jeffs/archive/2007/04/13/format-date-sql-server.aspx"&gt;read more...&lt;/a&gt;&lt;img src="http://weblogs.sqlteam.com/jeffs/aggbug/60175.aspx" width="1" height="1" /&gt;</description>
            <dc:creator>Jeff Smith</dc:creator>
            <guid>http://weblogs.sqlteam.com/jeffs/archive/2007/04/13/format-date-sql-server.aspx</guid>
            <pubDate>Fri, 13 Apr 2007 20:45:16 GMT</pubDate>
            <comments>http://weblogs.sqlteam.com/jeffs/archive/2007/04/13/format-date-sql-server.aspx#feedback</comments>
            <slash:comments>25</slash:comments>
            <wfw:commentRss>http://weblogs.sqlteam.com/jeffs/comments/commentRss/60175.aspx</wfw:commentRss>
            <trackback:ping>http://weblogs.sqlteam.com/jeffs/services/trackbacks/60175.aspx</trackback:ping>
        </item>
    </channel>
</rss>