为什么此转换为 DATETIME2 包含额外的粒度?
Why does this cast to DATETIME2 contain extra granularity?
我正在尝试将以下 DATETIME
转换为 DATETIME2
:
DECLARE @x DATETIME = '2021-12-10 19:58:41.333'
SELECT CAST(@x AS DATETIME2)
结果是2021-12-10 19:58:41.3333333
。为什么 cast 添加 0.0003333s?
这实际上是由于DATETIME
的粒度。您会注意到 datetime
中的毫秒只有 3 个可能值:0,333 或 667。这是因为它的粒度是三分之一秒。当转换为 datetime2
时,这会扩展小数位以正确表示分数。
与某些人理解的相反,datetime
并不精确到 1/1000 秒,而是精确到 1/300 秒。这就是为什么 datetime
的最后一位总是 0
、3
或 7
,因为它们分别代表第 0/300、1/300 和 2/300一秒(3/300 又是 0
)。
然而,对于 datetime2
,数据类型的精度可以为 0
- 7
。 0
表示精确到 1 秒,7
表示 100 纳秒或 1/10 微秒。
当您将 datetime
转换为 datetime2
时,datetime
仅精确到 1/300 秒这一事实反映在转换值中(请注意,对于较旧的SQL 服务器的版本这不是真的),因此将以新的准确度显示 1/300。
让我们取你的值 2021-12-10 19:58:41.333
。这里的 .333
是无限的,更多的是 .3333333333~
。这是因为您不能用 10 进制数准确表示 1/3(或 1/300)。然后,您将 (CAST
) 您的值转换为 datetime2
。您省略了精度,因此默认精度为 7
。这给你 2021-12-10T19:58:41.3333333
,因为现在显示的 1/300 精度高达 7(请注意,上面的精度为 100 纳秒, 而不是 100/3 纳秒) .
如果你有像 2021-12-10 19:58:41.357
这样的时间并将其转换为 datetime2(4)
你会得到 2021-12-10 19:58:41.3567
。如果您随后将其转换为 datetime2(7)
,您将得到 2021-12-10 19:58:41.3567000
,因为在将其转换为 datetime2(4)
.[=44= 时,“1/300th-ness”精度丢失了]
如前所述,在旧版本的 SQL 服务器 (2014 or prior) 中,上述情况并非如此。在这些旧版本中,datetime
值 2021-12-10 19:58:41.333
转换为 datetime2(7)
值 2021-12-10 19:58:41.3330000
的准确度较低。如果您使用的是旧版本并依赖于此行为,则需要明确 convert/cast 您的 datetime
值到 datetime2(3)
以避免可能的破坏性更改。
我正在尝试将以下 DATETIME
转换为 DATETIME2
:
DECLARE @x DATETIME = '2021-12-10 19:58:41.333'
SELECT CAST(@x AS DATETIME2)
结果是2021-12-10 19:58:41.3333333
。为什么 cast 添加 0.0003333s?
这实际上是由于DATETIME
的粒度。您会注意到 datetime
中的毫秒只有 3 个可能值:0,333 或 667。这是因为它的粒度是三分之一秒。当转换为 datetime2
时,这会扩展小数位以正确表示分数。
与某些人理解的相反,datetime
并不精确到 1/1000 秒,而是精确到 1/300 秒。这就是为什么 datetime
的最后一位总是 0
、3
或 7
,因为它们分别代表第 0/300、1/300 和 2/300一秒(3/300 又是 0
)。
然而,对于 datetime2
,数据类型的精度可以为 0
- 7
。 0
表示精确到 1 秒,7
表示 100 纳秒或 1/10 微秒。
当您将 datetime
转换为 datetime2
时,datetime
仅精确到 1/300 秒这一事实反映在转换值中(请注意,对于较旧的SQL 服务器的版本这不是真的),因此将以新的准确度显示 1/300。
让我们取你的值 2021-12-10 19:58:41.333
。这里的 .333
是无限的,更多的是 .3333333333~
。这是因为您不能用 10 进制数准确表示 1/3(或 1/300)。然后,您将 (CAST
) 您的值转换为 datetime2
。您省略了精度,因此默认精度为 7
。这给你 2021-12-10T19:58:41.3333333
,因为现在显示的 1/300 精度高达 7(请注意,上面的精度为 100 纳秒, 而不是 100/3 纳秒) .
如果你有像 2021-12-10 19:58:41.357
这样的时间并将其转换为 datetime2(4)
你会得到 2021-12-10 19:58:41.3567
。如果您随后将其转换为 datetime2(7)
,您将得到 2021-12-10 19:58:41.3567000
,因为在将其转换为 datetime2(4)
.[=44= 时,“1/300th-ness”精度丢失了]
如前所述,在旧版本的 SQL 服务器 (2014 or prior) 中,上述情况并非如此。在这些旧版本中,datetime
值 2021-12-10 19:58:41.333
转换为 datetime2(7)
值 2021-12-10 19:58:41.3330000
的准确度较低。如果您使用的是旧版本并依赖于此行为,则需要明确 convert/cast 您的 datetime
值到 datetime2(3)
以避免可能的破坏性更改。