Login or Sign Up to become a member!

EXPERTS, INFORMATION, IDEAS & KNOWLEDGE

Social bookmarker Add this

Your profile

Search

January 2009
Mon Tue Wed Thu Fri Sat Sun
 << <   > >>
      1 2 3 4
5 6 7 8 9 10 11
12 13 14 15 16 17 18
19 20 21 22 23 24 25
26 27 28 29 30 31  

XML Feeds

Authors

« Getting The Percentage Of NULLS And Values In A SQL Server TableHow Does Between Work With Dates In SQL Server? »
The Data Management Journal

How Are Dates Stored In SQL Server?

by SQLDenis


Permalink 04 Aug 2008 09:57 , Categories: Data Modelling & Design

Internally dates are stored as 2 integers. The first integer is the number of dates before or after the base date (1900/01/01). The second integer stores the number of clock ticks after midnight, each tick is 1/300 of a second.

So if we run the following code for the base date (1900/01/01)

  1. DECLARE @d DATETIME
  2. SELECT @d = ‘1900-01-01 00:00:00.000′
  3.  
  4.  
  5. SELECT CONVERT(INT,SUBSTRING(CONVERT(VARBINARY(8),@d),1,4)) AS DateInt,
  6. SUBSTRING(CONVERT(VARBINARY(8),@d),1,4) AS DateBinary
  7. SELECT CONVERT(INT,SUBSTRING(CONVERT(VARBINARY(8),@d),5,4)) AS TimeInt, SUBSTRING(CONVERT(VARBINARY(8),@d),5,4) AS TimeBinary
  8. Go

The results are

DateInt DateBinary
———– ———-
0 0x00000000

TimeInt TimeBinary
———– ———-
0 0x00000000

If we use the max date 9999/12/31

  1. DECLARE @d DATETIME
  2. SELECT @d = ‘9999-12-31 23:59:59.997′
  3.  
  4.  
  5. SELECT CONVERT(INT,SUBSTRING(CONVERT(VARBINARY(8),@d),1,4)) AS DateInt,
  6. SUBSTRING(CONVERT(VARBINARY(8),@d),1,4) AS DateBinary
  7. SELECT CONVERT(INT,SUBSTRING(CONVERT(VARBINARY(8),@d),5,4)) AS TimeInt, SUBSTRING(CONVERT(VARBINARY(8),@d),5,4) AS TimeBinary
  8. Go

we get the following result

DateInt DateBinary
———– ———-
2958463 0x002D247F

TimeInt TimeBinary
———– ———-
25919999 0x018B81FF

If you take binary values and convert to datetime you get the following results

  1. SELECT CONVERT(DATETIME,0x0000000000000001) –1 Tick 1/300 of a second

——————————————————
–1900-01-01 00:00:00.003

  1. SELECT CONVERT(DATETIME,0x000000000000012C) – 1 minute = 300 ticks

——————————————————
–1900-01-01 00:00:01.000

  1. SELECT CONVERT(INT,0x12C) –= 300
  2. SELECT CONVERT(VARBINARY(3),300) –= 0x00012C
  3.  
  4. SELECT CONVERT(DATETIME,0x0000000100000000) –add 1 day

——————————————————
–1900-01-02 00:00:00.000

For smalldatetime the time is stored as the number of minutes after midnight

Now here is some fun stuff

  1. DECLARE @d DATETIME
  2. SELECT @d = .0
  3. SELECT @d
  4. GO

——————————————————
–1900-01-01 00:00:00.000

  1. DECLARE @d DATETIME
  2. SELECT @d = .1
  3. SELECT @d
  4. GO

——————————————————
–1900-01-01 02:24:00.000

  1. DECLARE @d DATETIME
  2. SELECT @d = .12
  3. SELECT @d
  4. GO

——————————————————
–1900-01-01 02:52:48.000

  1. DECLARE @d DATETIME
  2. SELECT @d = ‘0′
  3. SELECT @d
  4. GO

Server: Msg 241, Level 16, State 1, Line 2
Syntax error converting datetime from character string.

  1. DECLARE @d DATETIME
  2. SELECT @d = 0
  3. SELECT @d
  4. GO

——————————————————
–1900-01-01 00:00:00.000

So there is no implicit conversion, o is fine ‘o’ is not

  1. DECLARE @d DATETIME
  2. SELECT @d = 20061030
  3. SELECT @d
  4. GO

Server: Msg 8115, Level 16, State 2, Line 2
Arithmetic overflow error converting expression to data type datetime.

  1. DECLARE @d DATETIME
  2. SELECT @d = ‘20061030′
  3. SELECT @d
  4. GO

——————————————————
–2006-10-30 00:00:00.000

Here we have the reverse, the varchar value is fine but the int is not.
This happens because the max integer value that a datetime can take is 36523
If we run the following we are okay

  1. DECLARE @d DATETIME
  2. SELECT @d = 2958463
  3. SELECT @d
  4. GO

——————————————————
–9999-12-31 00:00:00.000

Leave a comment »Send a trackback » 1435 views

Trackback address for this post

Trackback URL (right click and copy shortcut/link location)

No feedback yet

Leave a comment


Your email address will not be revealed on this site.

Your URL will be displayed.
PoorExcellent
(Line breaks become <br />)
(Name, email & website)
(Allow users to contact you through a message form (your email will not be revealed.)