Почему преобразование даты и времени выходит за пределы диапазона в течение 999 миллисекунд? - PullRequest
1 голос
/ 25 июня 2019

Может кто-нибудь объяснить, почему я получаю ошибку

В результате преобразование типа данных varchar в тип данных datetime в значении вне допустимого диапазона.

при выполнении следующего кода на SQL Server 2017. Я получаю сообщение об ошибке только за 0,999 миллисекунды

SELECT CAST('9999-12-31 23:59:59.999' AS DATETIME)

Результат:

В результате преобразование типа данных varchar в тип данных datetime в значении вне допустимого диапазона.

Тогда я попробовал:

SELECT CAST('9999-12-31 23:59:59.998' AS DATETIME)

Результат: 9999-12-31 23: 59: 59,997

Тогда я попробовал:

SELECT CAST('9999-12-31 23:59:59.997' AS DATETIME)

Результат: 9999-12-31 23: 59: 59.997

Ответы [ 4 ]

3 голосов
/ 25 июня 2019

Исходя из документации, диапазон даты и времени находится между 1 января 1753 года и 31 декабря 9999 года. Также по-прежнему на основе документации диапазон времени составляет от 00 до 23: 59: 997.

Таким образом, если вы сделаете округление, в 998 оно будет округлено до 997. В 999 оно должно округляться до 01 января 10000, что находится вне диапазона.(точность datetime в sql-сервере составляет 3,33 мс)

1 голос
/ 25 июня 2019

datetime с точностью только до 1/300 секунды, поэтому он показывает только моменты с точностью до .000, .003 и .007 секунды (последняя - 2 трети секунды с округлением до 3 десятичных дробеймест).

Для вашего значения '9999-12-31 23:59:59.999' SQL-сервер не может сохранить 0,009, поэтому он округляется до ближайшего значения, в этом случае это будет следующая секунда, что делает дату '10000-12-31 00:00:00.000', чтоне может быть сохранен ни в одном из типов данных даты и времени.

Если у вас есть .998, ближайшее значение к округлению равно .997, поэтому ошибка не возникает.

Если вы используете datetime2, вы также не получите ошибку, так как она может быть с точностью до 1/10000000 в секунду: SELECT CAST('9999-12-31 23:59:59.999' AS datetime)

1 голос
/ 25 июня 2019

Иногда (я имел в виду всегда?) Очень помогает чтение документации .

В ней говорится:

Диапазон дат: 1 января 1753 г.до 31 декабря 9999

Диапазон времени: от 00:00:00 до 23: 59: 59.997

Относительно времени, действительного для 23:59:59.998, даже если допустимый диапазондо 997 мс, это все еще объясняется в документации

Время от 23:59:59.995 до 23:59:59.998 сохраняется как 23:59:59.997

Время 23:59:59.999 сохраняется как 00:00:00.000 + 1 день

Затем 9999-12-31 23:59:59.999 сохраняется как 10000-01-01 00:00:00.000, что вне диапазона

0 голосов
/ 25 июня 2019

Согласно документации , сто секунд округляются следующим образом:

  • 999 -> 000 округляется (что приводит к вашей ошибке)
  • 998, 997, 996, 995 -> 997
  • 992, 993, 994 -> 993
  • 991, 990 -> 990

Это связано с тем, что тип данных datetime недостаточно точен для хранения этих значений. Вы можете использовать datetime2, если вам нужно больше точности.

Если вы хотите понять, как дата и время хранятся в SQL Server, я рекомендую эту статью: https://www.red -gate.com / simple-talk / sql / t-sql-программирования / как получить -SQL-сервер-финики-и-раз-ужасно-неправильный /

...