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
Here's what you want:
using System.Data.SqlTypes; // from System.Data.dll
public static DateTime RoundToSqlDateTime(DateTime date)
{
return new SqlDateTime(date).Value;
}
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);
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:
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.