Вокруг .NET DateTime миллисекунды, чтобы он мог соответствовать SQL Server миллисекунды - PullRequest
15 голосов
/ 20 мая 2010

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

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

Ответы [ 4 ]

21 голосов
/ 17 февраля 2012

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

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

public static DateTime RoundToSqlDateTime(DateTime date)
{
  return new SqlDateTime(date).Value;
}
10 голосов
/ 16 марта 2011

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

4 голосов
/ 08 декабря 2016

Рекомендовать опираться на решение @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);
}
3 голосов
/ 20 мая 2010

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

        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);
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...