为什么 SQL Server 会误解这个 ISO 8601 格式的日期?

Nic*_*ckG 2 sql t-sql sql-server datetime

为什么 SQL Server (2005) 会误解这个 ISO 8601 格式的日期?(YYYY-MM-DD)

DECLARE @FromDate DATETIME
SET @FromDate = '2013-01-05'
PRINT @FromDate
-- Prints: May  1 2013 12:00AM
Run Code Online (Sandbox Code Playgroud)

文本格式的日期显然是 1 月 5 日,但出于某种原因,SQL Server 将其解释为 5 月 1 日。世界上没有 YYYY-DD-MM 的日期格式,为什么会发生这种情况?我多年来一直使用这种格式,以前从未遇到过问题,所以我不确定在这种情况下有什么不同。

即使我使用 CONVERT 将其强制转换为 ISO8601,它仍然会出错:

DECLARE @FromDate DATETIME
SET @FromDate = CONVERT(VARCHAR, '2013-01-05', 126) 
PRINT @FromDate
-- Still prints: May  1 2013 12:00AM
Run Code Online (Sandbox Code Playgroud)

编辑:哎呀 - 我正在使用 'CONVERT(VARCHAR 以上我真正的意思是 CONVERT(DATETIME),所以这就是为什么没有任何效果。谢谢@RBarryYoung

但是,如果我在不同的服务器(SQL 2012)上运行上述两个示例中的任何一个,它们都会正确打印“Jan 5 2013 12:00AM”

这里发生了什么事?我认为在 SQL Server 中使用 ISO 格式的主要原因之一是它使月份和日期明确无误?

Mar*_*ith 5

它只会使较新的数据类型(date/ datetime2)变得明确

为了向后兼容,这仍然依赖于日期格式datetime

在 SQL Server 2012 上

SET DATEFORMAT DMY

SELECT CAST('2013-01-05' AS DATETIME),   /*May*/
       CAST('2013-01-05' AS DATETIME2),  /*Jan*/
       CAST('20130105' AS DATETIME),     /*Jan*/
       CAST('20130105' AS DATETIME2)     /*Jan*/
Run Code Online (Sandbox Code Playgroud)

yyyymmdd在处理这些数据类型时,您可以将其用作明确的格式。

请参阅日期时间数据类型的最终指南(这unseparated在该文章中称为格式)

  • @NickG 实际上,您的表达式 `CONVERT(VARCHAR, '2013-01-05', 126)` 不起作用的原因是您没有将日期转换为 CONVERT() 中的字符串,您是将字符串转换为字符串,因此它实际上并没有改变任何东西。试试像 `CONVERT(DATETIME, '2013-01-05', 126)` 代替。我现在没有时间测试它,但我认为这是有效的,因为现在它正在将字符串转换为日期时间。 (3认同)
  • @NickG - 从 SQL Server 2008 开始,情况已修复。旧的数据类型和行为是为了向后兼容而保留的,他们为新工作推荐新的数据类型。对于以前的版本,您只需要接受它不能按您想要的方式工作并使用中性格式。我只是告诉你它是怎么回事,所以我不确定你为什么向我抱怨它。 (2认同)