开发者

Round .NET DateTime milliseconds, so it can fit SQL Server milliseconds

I want to convert the datetime value to the value that I will get from SQL Server 2008.

SQL Server truncate the milliseconds to 3 digits, so I truncate the milliseconds already. But the problem is that as you can see here: Milliseconds wrong when converting from XML to SQL Ser开发者_运维问答ver datetime. SQL Server also has an precision issue.


Here's what you want:

using System.Data.SqlTypes; // from System.Data.dll

public static DateTime RoundToSqlDateTime(DateTime date)
{
  return new SqlDateTime(date).Value;
}


A little late to the party, but here's a solution, based on the SQL Server docs for the datetime datatype for different versions of SQL Server:

  • SQL Server 2000
  • SQL Server 2005
  • SQL Server 2008

For any given date/time value, this should give you exactly the same value as SQL Server will:

public static class DateTimeExtensions
{
                                   //  milliseconds modulo 10:    0    1    2    3    4    5    6    7    8    9
    private static readonly int[]    OFFSET                  = {  0 , -1 , +1 ,  0 , -1 , +2 , +1 ,  0 , -1 , +1 } ;
    private static readonly DateTime SQL_SERVER_DATETIME_MIN = new DateTime( 1753 , 01 , 01 , 00 , 00 , 00 , 000 ) ;
    private static readonly DateTime SQL_SERVER_DATETIME_MAX = new DateTime( 9999 , 12 , 31 , 23 , 59 , 59 , 997 ) ;

    public static DateTime RoundToSqlServerDateTime( this DateTime value )
    {
        DateTime dt           = new DateTime( value.Year , value.Month , value.Day , value.Hour , value.Minute , value.Second , value.Millisecond) ;
        int      milliseconds = value.Millisecond ;
        int      t            = milliseconds % 10 ;
        int      offset       = OFFSET[ t ] ;
        DateTime rounded      = dt.AddMilliseconds( offset ) ;

        if ( rounded < SQL_SERVER_DATETIME_MIN ) throw new ArgumentOutOfRangeException("value") ;
        if ( rounded > SQL_SERVER_DATETIME_MAX ) throw new ArgumentOutOfRangeException("value") ;

        return rounded ;
    }
}

It will not, however, work properly, for smalldatetime or the new datetime2 datatypes.


Recommend building upon @RobSiklos solution since use of SqlDateTime in this fashion results in the loss of timezone information that the 'date' argument provided. Find its best practice to ensure timezone info is consistent at the point of conversion by adding a call to DateTime.SpecifyKind:

using System.Data.SqlTypes; // from System.Data.dll

public static DateTime RoundToSqlDateTime(DateTime date)
{
  return DateTime.SpecifyKind( new SqlDateTime(date).Value, date.Kind);
}


This code should work:

        int ticksInMillisecond = 10000;
        DateTime t1 = DateTime.Now;
        DateTime t2 = new DateTime(t1.Ticks / ticksInMillisecond * ticksInMillisecond);

But considering SQL Server's precision issue, I would rather truncate it to two digits after second:

        int precisionTicks = 100000;
        DateTime t1 = DateTime.Now;
        DateTime t2 = new DateTime(t1.Ticks / precisionTicks * precisionTicks);
0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜