为什么日期时间转换超出范围 999 毫秒?
Why do I get datetime conversion out of range for 999 milliseconds?
谁能解释一下为什么我会收到错误
The conversion of a varchar data type to a datetime data type resulted
in an out-of-range value.
当我在 SQL Server 2017 上执行以下代码时。我只收到 0.999 毫秒的错误
SELECT CAST('9999-12-31 23:59:59.999' AS DATETIME)
结果:
The conversion of a varchar data type to a datetime data type resulted
in an out-of-range value.
然后我尝试了:
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
根据文档,日期时间范围介于 1753 年 1 月 1 日和 9999 年 12 月 31 日之间。同样仍然基于文档,时间范围介于 00 到 23:59:997 之间。
因此,如果您进行舍入,在 998 时它会向下舍入到 997。在 999 时它应该向上舍入到超出范围的 1 月 1 日 10000。 (sql-server中datetime的精度为3.33ms)
有时(我的意思是总是吗?)阅读 documentation 有很大帮助。
它指出:
Date range : January 1, 1753, through December 31, 9999
Time range : 00:00:00 through 23:59:59.997
关于23:59:59.998
的有效时间,即使有效范围达到997
毫秒,在documentation
中仍然有说明
从 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
,超出范围
根据 documentation,百秒四舍五入:
- 999 -> 000 四舍五入(这会导致你的错误)
- 998、997、996、995 -> 997
- 992、993、994 -> 993
- 991, 990 -> 990
这是因为日期时间数据类型不够精确,无法存储这些值。如果您需要更高的精度,可以使用 datetime2。
如果您想了解日期时间是如何存储在 SQL 服务器中的,我推荐这篇文章:https://www.red-gate.com/simple-talk/sql/t-sql-programming/how-to-get-sql-server-dates-and-times-horribly-wrong/
datetime
仅精确到 1/300 秒,因此它仅显示精确到 .000、.003 和 .007 秒的时间(最后一个是三分之二秒四舍五入到小数点后三位)。
对于您的值 '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)
谁能解释一下为什么我会收到错误
The conversion of a varchar data type to a datetime data type resulted in an out-of-range value.
当我在 SQL Server 2017 上执行以下代码时。我只收到 0.999 毫秒的错误
SELECT CAST('9999-12-31 23:59:59.999' AS DATETIME)
结果:
The conversion of a varchar data type to a datetime data type resulted in an out-of-range value.
然后我尝试了:
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
根据文档,日期时间范围介于 1753 年 1 月 1 日和 9999 年 12 月 31 日之间。同样仍然基于文档,时间范围介于 00 到 23:59:997 之间。
因此,如果您进行舍入,在 998 时它会向下舍入到 997。在 999 时它应该向上舍入到超出范围的 1 月 1 日 10000。 (sql-server中datetime的精度为3.33ms)
有时(我的意思是总是吗?)阅读 documentation 有很大帮助。
它指出:
Date range : January 1, 1753, through December 31, 9999
Time range : 00:00:00 through 23:59:59.997
关于23:59:59.998
的有效时间,即使有效范围达到997
毫秒,在documentation
从 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
,超出范围
根据 documentation,百秒四舍五入:
- 999 -> 000 四舍五入(这会导致你的错误)
- 998、997、996、995 -> 997
- 992、993、994 -> 993
- 991, 990 -> 990
这是因为日期时间数据类型不够精确,无法存储这些值。如果您需要更高的精度,可以使用 datetime2。
如果您想了解日期时间是如何存储在 SQL 服务器中的,我推荐这篇文章:https://www.red-gate.com/simple-talk/sql/t-sql-programming/how-to-get-sql-server-dates-and-times-horribly-wrong/
datetime
仅精确到 1/300 秒,因此它仅显示精确到 .000、.003 和 .007 秒的时间(最后一个是三分之二秒四舍五入到小数点后三位)。
对于您的值 '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)