Ответ 1
Вот что вы хотите:
using System.Data.SqlTypes; // from System.Data.dll
public static DateTime RoundToSqlDateTime(DateTime date)
{
return new SqlDateTime(date).Value;
}
Я хочу преобразовать значение datetime в значение, которое я получу из SQL Server 2008.
SQL Server усекает миллисекунды до трех цифр, поэтому я урезаю миллисекунды уже. Но проблема в том, что, как вы можете видеть здесь: Миллисекунды ошибочны при преобразовании из XML в SQL Server datetime. SQL Server также имеет проблему с высокой точностью.
Вот что вы хотите:
using System.Data.SqlTypes; // from System.Data.dll
public static DateTime RoundToSqlDateTime(DateTime date)
{
return new SqlDateTime(date).Value;
}
Немного поздно для вечеринки, но вот решение, основанное на документах SQL Server для типа данных datetime
для разных версий SQL Server:
Для любого заданного значения даты/времени это должно дать вам то же значение, что и SQL Server:
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 ;
}
}
Однако он не будет работать правильно, для smalldatetime
или новых типов данных datetime2
.
Рекомендовать здание с помощью решения @RobSiklos, так как использование SqlDateTime таким образом приводит к потере информации о часовом поясе, предоставленной аргументом "date". Найдите свою лучшую практику, чтобы обеспечить, чтобы информация о часовом поясе была согласованной в точке преобразования, добавив вызов 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);
}
Этот код должен работать:
int ticksInMillisecond = 10000;
DateTime t1 = DateTime.Now;
DateTime t2 = new DateTime(t1.Ticks / ticksInMillisecond * ticksInMillisecond);
Но учитывая проблему точности SQL Server, я предпочел бы усекать ее до двух цифр после второго:
int precisionTicks = 100000;
DateTime t1 = DateTime.Now;
DateTime t2 = new DateTime(t1.Ticks / precisionTicks * precisionTicks);