Миллисекунды в моем изменении DateTime при хранении в SQL Server
У меня есть дата, которое я генерирую так:
DateTime myDateTime = DateTime.Now;
Затем я сохраняю его в базе данных (в столбце DateTime
) с помощью Entity Framework. Затем я извлекаю его с помощью OData (службы данных WCF).
Когда он идет в значение TimeOfDay: 09: 30: 03.0196095
Когда он выйдет, значение TimeOfDay: 09: 30: 03.0200000
Чистый эффект от этого делает так, чтобы миллисекунды были замечены как 19 до их сохранения и 20 после перезагрузки.
Итак, когда я делаю сравнение позже в моем коде, он терпит неудачу там, где он должен быть равен.
Не имеет ли SQL Server такой точности, как .NET? Или это Entity Framework или OData, который испортил это?
Я просто усечу миллисекунды (мне они действительно не нужны). Но я хотел бы знать, почему это происходит.
Ответы
Ответ 1
Это зависит от версии используемого вами SQL-сервера.
Разрешение поля времени даты равно трем десятичным разрядам: например: 2011-06-06 23:59:59.997
и имеет значение только с точностью до 3,33 мс.
В вашем случае 09: 30: 03.0196095 округляется до 09: 30: 03.020.
Начиная с SQL 2008, были добавлены другие типы данных, чтобы обеспечить более подробную информацию, такую как datetime2, которая имеет до 7 знаков после запятой и с точностью до 100 нс.
Для получения дополнительной информации см. следующее:
http://www.karaszi.com/SQLServer/info_datetime.asp
Я считаю, что лучше всего обеспечить округление второго приоритета до его хранения на SQL-сервере, если миллисекунды несущественны.
Ответ 2
Это связано с точностью типа SQL datetime
. Согласно msdn:
Значения даты и времени округлены до приращений .000,.003 или .007 секунд
Посмотрите на Округление datetime Fractional Second Precision раздела этой страницы msdn и вы поймете, как выполняется округление.
Как указано другими, вы можете использовать datetime2
вместо datetime
для лучшей точности:
-
datetime
диапазон времени 00:00:00 through 23:59:59.997
-
datetime2
временной интервал 00:00:00 through 23:59:59.9999999
Ответ 3
Точность DateTime в SQL Server равна миллисекундам (.fff
). Таким образом, 0,0196 будет округлено до 0,020. Если вы можете использовать datetime2, вы получите более высокую точность.
Ответ 4
Для тех, у кого нет возможности использовать DateTime2 в SQL (например: например, я использую таблицы, которые генерируются отдельной системой, которые будут дорого изменены для этой отдельной проблемы), есть простая модификация кода, которая будет сделайте округление для вас.
Ссылка System.Data
и импортировать пространство имен System.Data.SqlTypes
. Затем вы можете использовать структуру SqlDateTime
для преобразования для вас:
DateTime someDate = new SqlDateTime(DateTime.Now).Value;
Это преобразует значение в тики SQL, а затем обратно в .NET ticks, включая потерю точности.:)
Слово предупреждения, это потеряет Kind
исходной структуры DateTime
(т.е. Utc
, Local
). Это преобразование также не просто округляет, есть полное преобразование, включая расчеты галочки, изменения MaxTime
и т.д. Поэтому не используйте это, если вы полагаетесь на определенные индикаторы в DateTime
, поскольку они могут быть потеряны.