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

前端 未结 4 1460
孤独总比滥情好
孤独总比滥情好 2020-12-03 10:59

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 milliseco

相关标签:
4条回答
  • 2020-12-03 11:26

    Here's what you want:

    using System.Data.SqlTypes; // from System.Data.dll
    
    public static DateTime RoundToSqlDateTime(DateTime date)
    {
      return new SqlDateTime(date).Value;
    }
    
    0 讨论(0)
  • 2020-12-03 11:47

    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);
    }
    
    0 讨论(0)
  • 2020-12-03 11:47

    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 讨论(0)
  • 2020-12-03 11:50

    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.

    0 讨论(0)
提交回复
热议问题