Although SQL Server 2000 has a data type called DateTime, which is very similar to the .NET DateTime data type, it is just that; similar. It is not identical because their precision is different.

 

Time values are measured in 100-nanosecond units called ticks, and a particular date is the number of ticks since 12:00 midnight, January 1, 1 A.D. (C.E.) in the GregorianCalendar calendar.

MSDN on .NET DateTime

 

Date and time data from January 1, 1753 through December 31, 9999, to an accuracy of one three-hundredth of a second (equivalent to 3.33 milliseconds or 0.00333 seconds). Values are rounded to increments of .000, .003, or .007 seconds

MSDN on .SQL Server 2000 DateTime

 

This means that a .NET DateTime will be different to the original value when saved to and loaded from SQL Server 2000. The way to get round this issue, if it is an issue for your application, is to persist a .NET DateTime’s number of ticks (100 nanosecond units) rather than the DateTime itself. This way instead of using SQL Server 2000’s DateTime, its BigInt data type can be used instead, which maps directly to a .NET’s Int64 (long).

 

By going this route your application might be happy, but your DBA probably won’t be. He doesn’t care about ticks, he just wants to use SQL’s nice operators that apply to DateTime such as BETWEEN. Thankfully, this can be arranged. SQL Server 2000 allows for tables to have calculated columns, so as long as you know how to convert ticks to DateTime, a calculated column of data type DateTime can be added for every column that stores ticks as BigInt.

 

The following is a function by Jerry Dixon that converts ticks to DateTime

 

CREATE FUNCTION dbo.udfTicksToDateTime

(

      @Ticks BIGINT

)

RETURNS DATETIME

AS

BEGIN

      DECLARE @Days  BIGINT

      DECLARE @DaysBefore1753 BIGINT

      DECLARE @TimeTicks BIGINT

      DECLARE @Seconds BIGINT

 

      SET @Days = @Ticks / CONVERT(BIGINT,864000000000)

      SET @DaysBefore1753 = CONVERT(BIGINT,639905)

      SET @TimeTicks = @Ticks % CONVERT(BIGINT,864000000000)

      SET @Seconds = @TimeTicks / CONVERT(BIGINT,10000000)

 

      RETURN DATEADD(s,@Seconds,DATEADD(d,@Days - @DaysBefore1753,CONVERT(DATETIME,'1/1/1753')))

END

 

And you can go the opposite way too if you feel like it.

 

Calculated columns can be added by doing something like the following:

CREATE TABLE Orders (

        OrderDateAsTicks BIGINT,

        OrderDate AS dbo.udfTicksToDateTime(OrderDateAsTicks)

)

 

The same effect can be achieved using an update trigger, but a calculated column should be more efficient.