• subscribe
January 24, 2007 12:00 AM

DATETIME Calculations, Part 1

Trimming techniques help you return only the date or the time of a given datetime value.
SQL Server Pro
InstantDoc ID #94487
Downloads
94487.zip

Extracting Time Only
The techniques to extract only the time are based on logic that's similar to the logic used for extracting only the date. You zero the date portion, setting it to the base date. I'll start with a calculation that relies on the logic from the third technique in the previous section:

SELECT DATEADD(
  ms,
  DATEDIFF(
   ms,
   DATEADD(day,
     DATEDIFF(day, 0,
     GETDATE()), 0), --
     date only 
   GETDATE()),
  0);

Notice that the DATEDIFF function calculates the difference in terms of milliseconds between the date-only portion of the input date and the input date. Call it diff. The outer DATEADD function adds diff milliseconds to the base date (represented by the integer 0).

If you want accuracy in terms of seconds instead of milliseconds, simply specify a second datepart instead of millisecond (ms):

SELECT DATEADD(
  second,
  DATEDIFF(
     second, 
     DATEADD(day, DATEDIFF(day,
      0, GETDATE()), 0), -- date
      only 
     GETDATE()), 
  0);

Of course, you also have the option to use logic similar to the logic used in the first technique—except that here you'll convert the input value to CHAR(14) using style 114 (hh:mi:ss:mmm) if you're after an accuracy of milliseconds:

SELECT CAST( 
  CONVERT(CHAR(12), GETDATE(), 
     114) -- 'hh:mi:ss:mmm'
  AS DATETIME);

If you're after an accuracy of seconds, convert to CHAR(8). By doing so, you'll trim the milliseconds portion:

SELECT CAST( 
  CONVERT(CHAR(8), GETDATE(),
    114) -- 'hh:mi:ss:mmm'
  AS DATETIME);

Only the Beginning
I've discussed the storage format that SQL Server uses to store datetime values, focusing on challenges related to the fact that there's no separation between date and time. But this is only the beginning. There are so many more challenges related to datetime manipulation. I'll continue exploring those challenges in the coming months.



ARTICLE TOOLS

Comments
  • Koukoulidis
    2 years ago
    Apr 02, 2010

    based on the suggestion of Mike Smith :

    SELECT GETDATE(), GETDATE() - CAST(CAST(GETDATE() AS VARBINARY(4)) AS DATETIME) AS dateonly, CAST(CAST(GETDATE() AS VARBINARY(4)) AS DATETIME) AS timeonly

  • Frank
    3 years ago
    Apr 03, 2009

    Very usefull article.

    Personnally I like the following to calculate time only:

    SELECT DATEADD(DAY, DATEDIFF(DAY, GETDATE(), 0), GETDATE())

  • Jay
    3 years ago
    Apr 02, 2009

    I've always used a method similar to Ashley's only with the ROUND command instead of FLOOR. Something like "CAST( ROUND(CAST(GETDATE() AS FLOAT),0)AS DATETIME)". My syntax may be off.

  • Bob
    3 years ago
    Apr 02, 2009

    I've been wrestling with this problem for a while, but for our databases, we generally DO want to keep both time and date. So I came up with this string that I fit into my SQL string whenever I need data ranges:

    dateQuery = " ORDDate BETWEEN CAST('" & beginDate & "' AS smalldatetime) AND CAST('" & endDate & " 11:59:59 PM' AS smalldatetime)"

    then use it like this:

    theSQL = "SELECT * FROM ORDERS WHERE " & dateQuery & " AND STATUS = 'CANCELLED' ORDER BY ORDDATE DESC;"

    Works every time.

  • Greg
    3 years ago
    Apr 02, 2009

    I second the statement "it's only the beginning". Microsoft long followed the same approach of no date-only types in their other languages.

    We pass data containing dates through a web service to an iSeries (legacy) back-end where dates are stored in decimal. Zeroing the time component isn't enough, as the friendly web-service / consumer wrappers generated in visual studio take time zones into consideration; zeroing the time, transmitting, receiving, and zeroing the time, can result in losing a whole day. The datetime has to be set as not having a timezone before transmitting.
    I know, I'm talking mainly about Visual Studio, VB, and C#, but ultimately it was about trying to pass data containing dates between two database.

    I'm hoping Sql Server 2008's lead on timeless date types is followed through the rest of MS's platforms.

You must log on before posting a comment.

Are you a new visitor? Register Here
  • SP1?
    I know there is a SP1 for SQL 2008 R2 available....and there is a "feature pack" as well... ...
  • SQL database mirroring
    I have SQL Server 2008 R2 Enterprise 64bit on Windows 2008 R2 Enterprise 64bit.  Each SQL Server has...
  • Dell Compellent Disk Drive
    Does anybody has experience with Dell Compellent Disk Drive? Basically, this system manages all disk...
  • Sql server performance tuning
    I need to find a tool that help me to optimize sql server,queries,improve the performance and solve ...