Круглые миллисекунды .NET DateTime, поэтому он может соответствовать миллисекундам SQL Server

Я хочу преобразовать значение datetime в значение, которое я получу из SQL Server 2008.

SQL Server усекает миллисекунды до трех цифр, поэтому я урезаю миллисекунды уже. Но проблема в том, что, как вы можете видеть здесь: Миллисекунды ошибочны при преобразовании из XML в SQL Server datetime. SQL Server также имеет проблему с высокой точностью.

Ответы

Ответ 1

Вот что вы хотите:

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

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

Ответ 2

Немного поздно для вечеринки, но вот решение, основанное на документах 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.

Ответ 3

Рекомендовать здание с помощью решения @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);
}

Ответ 4

Этот код должен работать:

        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);