The epoch (zero point) of the SQL Server datetime
calendar is 1900-01-01T00:00:00.000
. If you do something like
select convert(datetime,'')
That is the value you will get.
SQL Server's datetime
data type is composed of 2 signed 32-bit integers. The first is the offset in days from the epoch; the second is the time-of-day expressed as an offset in milliseconds from start-of-day.
When you subtract two datetime values, say @end
and @start
it does what you'd expect it to.
- if
@end.time-of-day
is <@start.time-of-day
, carry a day's worth of milliseconds from@end.date
and decrement@end.date
. - compute the new time-of-day value by subtracting
@start.time-of-day
from@end.time-of-day
. - compute the new date by subtracting
@start.date
from @end.date`
If the resulting value is outside the domain of datetime
(1753-01-01T00:00:00.000
through 9999-12-31T23:59:59.997
) an error is raised.
You are getting the expected result...for SQL Server.
Edited to show the what's going on under the covers:
declare @x datetime = '2014-02-22 00:12:00'
declare @y datetime = '2014-02-22 00:00:00'
declare @z datetime = @x - @y
select 'end' ,
date = @x ,
description = 'days_since_epoch' ,
value = convert(int,substring( convert(varbinary(8),@x) , 1 , 4 ) ) ,
description = 'time_as_ms_offset' ,
value = convert(int,substring( convert(varbinary(8),@x) , 5 , 4 ) )
union select 'start' ,
date = @y ,
description = 'days_since_epoch' ,
value = convert(int,substring( convert(varbinary(8),@y) , 1 , 4 ) ) ,
description = 'time_as_ms_offset' ,
value = convert(int,substring( convert(varbinary(8),@y) , 5 , 4 ) )
union select 'delta' ,
date = @z ,
description = 'days_since_epoch' ,
value = convert(int,substring( convert(varbinary(8),@z) , 1 , 4 ) ) ,
description = 'time_as_ms_offset' ,
value = convert(int,substring( convert(varbinary(8),@z) , 5 , 4 ) )
produces this result, showing the math:
date description value description value
----- ----------------------- ---------------- ----- ----------------- ------
end 2014-02-22 00:12:00.000 days_since_epoch 41690 time_as_ms_offset 216000
start 2014-02-22 00:00:00.000 days_since_epoch 41690 time_as_ms_offset 0
delta 1900-01-01 00:12:00.000 days_since_epoch 0 time_as_ms_offset 216000