Неправильные миллисекунды при преобразовании даты и времени из XML в SQL Server - PullRequest
11 голосов
/ 11 марта 2009

Я столкнулся с проблемой, связанной с преобразованием даты и времени из XML (ISO8601: гггг-мм-ддтч: ми: сс.ммм) в дату и время SQL Server 2005. Проблема в том, что преобразование миллисекунд неверно. Я протестировал как неявное, так и явное преобразование с помощью convert (datetime, MyDate, 126) из nvarchar, и результат тот же:

Original                Result
2009-10-29T15:43:12.990 2009-10-29 15:43:12.990
2009-10-29T15:43:12.991 2009-10-29 15:43:12.990
2009-10-29T15:43:12.992 2009-10-29 15:43:12.993
2009-10-29T15:43:12.993 2009-10-29 15:43:12.993
2009-10-29T15:43:12.994 2009-10-29 15:43:12.993
2009-10-29T15:43:12.995 2009-10-29 15:43:12.997
2009-10-29T15:43:12.996 2009-10-29 15:43:12.997
2009-10-29T15:43:12.997 2009-10-29 15:43:12.997
2009-10-29T15:43:12.998 2009-10-29 15:43:12.997
2009-10-29T15:43:12.999 2009-10-29 15:43:13.000

Мое неполное тестирование показывает, что последняя цифра равна 0, 3 или 7. Это простая проблема округления? Точность в миллисекундах важна, и потерять / получить один или два не вариант.

Ответы [ 2 ]

17 голосов
/ 11 марта 2009

Да, SQL Server время округления до 3.(3) миллисекунд:

SELECT CAST(CAST('2009-01-01 00:00:00.000' AS DATETIME) AS BINARY(8))
SELECT CAST(CAST('2009-01-01 00:00:01.000' AS DATETIME) AS BINARY(8))

0x00009B8400000000
0x00009B840000012C

Как видите, эти DATETIME отличаются на 1 секунду, а их двоичные представления отличаются на 0x12C, то есть 300 в десятичном виде.

Это потому, что SQL Server хранит time часть DATETIME в виде числа 1/300 секундных тиков с полуночи.

Если вы хотите большей точности, вам нужно сохранить деталь TIME как отдельное значение. Например, храните время, округленное до секунды, как DATETIME, и миллисекунды или любую другую точность, которая вам нужна как INTEGER, в других столбцах.

Это позволит вам использовать сложную DATETIME арифметику, такую ​​как добавление месяцев или поиск дней недели по DATETIME, и вы можете просто добавить или вычесть миллисекунды и объединить результат как .XXXXXX+HH:MM, чтобы получить действительный XML представление.

6 голосов
/ 11 марта 2009

Из-за проблем точности, упомянутых Quassnoi , если у вас есть возможность использовать SqlServer 2008, вы можете рассмотреть возможность использования datetime2 datatpe или если вас беспокоит только часть времени, которую вы можно использовать тип данных времени

Типы данных даты и времени - перечисляет все типы и их точность

В Sql Server 2005, если бы мне нужна была точность в 1 миллисекунду, я бы добавил дополнительный столбец милисекунды типа int для хранения количества миллисекунд и удалил часть милисекунд из столбца dateTime (установите его в 000). Это при условии, что вам нужна информация о дате.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...