将 0 转换为 DATE 和 DATETIME

Posted

技术标签:

【中文标题】将 0 转换为 DATE 和 DATETIME【英文标题】:Casting 0 as DATE and DATETIME 【发布时间】:2017-01-13 21:08:26 【问题描述】:

我只是偶然发现了这个,找不到任何技术解释:

在 SQL Server 2014 中:

SELECT CAST('' AS DATETIME);
1900-01-01 00:00:00.000

SELECT CAST(0 AS DATETIME);
1900-01-01 00:00:00.000

SELECT CAST('' AS DATE);
1900-01-01

SELECT CAST(CAST(0 AS DATETIME) AS DATE);
1900-01-01

SELECT CAST(0 AS DATE);

消息 529,第 16 级,状态 2,第 4 行 不允许从数据类型 int 到 date 的显式转换。

为什么从空字符串到DATEDATETIMECAST 可以工作,而从0 它只能作为DATETIME 工作?

我对技术解释感兴趣

【问题讨论】:

msdn.microsoft.com/en-us/library/ms191530.aspx 【参考方案1】:

我认为这是微软选择支持什么的问题。或多或少归结为这样一个事实,即允许从数值转换为日期时间,而日期不允许从数值转换。在 SQL Server 中,它必须首先将 0 转换为数值,例如 0.000000000,然后再转换为该数字的等效日期时间。我的示例显示可以将当前日期转换为数值,然后再转换回日期时间。但是,转换为日期会引发错误。如果您尝试将值 0.5 转换为日期,我想避免可能遇到的舍入问题。在这种情况下,将编程 SQL 引擎以将 0.5 隐式转换为日期 1900-01-01 或 1900-01-02。在这种情况下,您必须就应返回的日期做出任意决定。

这行得通:

--produces a numeric value like 42746.97660799
select cast(getdate() as numeric(18,8)) 

select cast(42746.97660799 as datetime)

虽然这会引发您收到的相同错误:

select cast(42746.97660799 as date)

消息 529,第 16 级,状态 2,第 5 行 不允许将数据类型从数字显式转换为日期。

【讨论】:

好点,我没有这么想。如果您可以将 int 转换为日期,并且可以将数字转换为 int,那么您可以将数字(非 int)转换为日期,创建任意轮次。很好的答案!【参考方案2】:

您的第一个问题,为什么不能将 0 转换为 Date,这是从 Int 到 Date 的非法转换(请参阅链接文档中的矩阵)

我在找到类似代码后发现了您的问题,并想知道为什么 cast(0 as datetime) 会产生 1900-01-01。我想知道这是一个我可以信任的“标准”还是未定义的“在我们改变它之前它会一直这样工作”。我什至发现了其他建议 Epoch 是 1900 的 SO 帖子,但找不到任何官方文档。

在阅读 Cast/Convert 文档时,可以参考 Cast 将在缺少 Year 或 Time 时执行的操作(尽管在 varchar 转换部分)。未定义时,日期默认为 1900-01-01,时间默认为 00:00:00。 (参见链接文档中的下标 6)。文章中有示例代码将时间转换为日期时间,并为日期部分生成 1900-01-01。

这(谢天谢地?!)产生 0(而 1753 的最小日期产生一个很大的负数)

select cast(cast('1900-01-01' as datetime) as Int)

标题为“CAST and CONVERT (Transact-SQL)”的 Microsoft 文档

https://docs.microsoft.com/en-us/sql/t-sql/functions/cast-and-convert-transact-sql?view=sql-server-ver15

【讨论】:

【参考方案3】:

这可能来自时间戳行为。 您可以将 0 转换为日期时间,然后转换为日期。 这也是微软的规则。不是国家规定。

【讨论】:

发帖者:我对技术解释很感兴趣 您添加了一条重要信息,将 0 转换为 DATETIME,然后转换为 DATE 工作。我将把它添加到问题中。【参考方案4】:

除了 SQL Server 支持的内容之外,我不确定是否有很多干净的技术解释。 SQL Server 对其所有数据类型进行排名Data Type Precendence。隐式转换随着时间的推移而演变。 Craig Friedman 的 Microsoft 博客很好地解释了逻辑和演变More on Implicit Conversions。 @hamid_reza hobab 所指出的基本上是正确的。 SQL Server 支持将 int 转换为日期时间。日期时间的优先级高于日期,因此可以将日期时间转换为日期。 SQL Server 不支持将 int 隐式或显式转换为 date,如 @dfundako 在评论中发布的支持矩阵中所示

【讨论】:

以上是关于将 0 转换为 DATE 和 DATETIME的主要内容,如果未能解决你的问题,请参考以下文章

时间格式转换—将后台返回的/Date(1448954018000)/格式转换为正常的时间格式

将日期/时间转换为可读格式。

将Java DateTime转换为AS3 Date

将 24 小时时间转换为旋转值

将 current_date 转换为相对日期和静态时间

js中怎么将yyyy-MM-dd hh:mm:ss格式的转换为date类型