SQL Server:为什么ISO-8601格式的日期与语言有关?

10
我可以帮助你理解SQL Server中的日期格式处理。如果您尝试以下操作,它将返回正确的结果:
SET LANGUAGE English
SELECT CAST('2013-08-15' AS DATETIME)

-- 2013-08-15 00:00:00.000

然而,这将导致转换错误,因为显然SQL Server将'8'解释为天,将'15'解释为月:

SET LANGUAGE German
SELECT CAST('2013-08-15' AS DATETIME)

-- Conversion failed when converting date and/or time from character string.

我知道可以使用语言无关的(稍作修改的ISO-8601)格式YYYYMMDD(无破折号),它可以在任何语言中使用。然而,我不明白为什么YYYY-MM-DD是与语言相关的,当SQL书籍明确说明:“解释取决于字符串文字格式的组合和默认语言选项设置……某些字符串文字格式不受这些设置影响……ISO 8601格式不依赖于这些设置,是国际标准。”

http://technet.microsoft.com/en-us/library/ms180878%28v=sql.105%29.aspx

即使查看select * from sys.syslanguages返回的日期格式也没有任何指示——日期格式是dmy,因此它也不符合ISO-8601格式。所以问题是:为什么ISO-8601格式与语言有关,尽管Books Online说不是?在哪里可以找到SQL Server解析ISO-8601日期时使用的确切格式?更新:在http://technet.microsoft.com/en-us/library/ms180878%28v=sql.105%29.aspx#ISO8601Format上继续阅读,它说“要使用ISO 8601格式,必须指定格式中的每个元素。这包括T、冒号(:)、+或-和句点(.)”(例如2004-05-23T14:25:10)。

上面的表格(http://technet.microsoft.com/en-us/library/ms180878%28v=sql.105%29.aspx#StringLiteralDateandTimeFormats)显示ISO 8601数字格式不依赖于DATEFORMAT,但也不是多语言的。我不确定在哪里可以找到关于多语言部分的更多信息 - 比如每种语言使用的确切格式。


德国的格式是这样的:SET LANGUAGE German; SELECT CAST('15.08.2013' AS DATETIME)。只使用convert呢? - Brett Schneider
@Brett Schneider:我知道它是;但是我想问的是如何处理ISO-8601格式的日期。 - matk
“the exact format used in each language” is in the dateformat column in sys.syslanguages. - Mikael Eriksson
@Mikael Eriksson:看起来就是这样,我用几种不同的语言进行了测试。您是否知道任何关于此行为的官方文档? - matk
请仅返回翻译文本:在您已经找到的页面上,只有数字日期格式。它说:“12/10/08可以根据DATEFORMAT设置解释为六个日期之一”,但是“四位数年份将被解释为年份”。 - Mikael Eriksson
显示剩余2条评论
3个回答

3

1

很难回答以“为什么”开头的问题 :-)

这可能不能回答你的问题,但对于日期,有一种字符串格式可以在所有语言环境下使用:'YYYYMMDD'

尝试:

SET LANGUAGE English
SELECT CAST('20130815' AS DATETIME)

SET LANGUAGE German
SELECT CAST('20130815' AS DATETIME)

SET LANGUAGE Japanese
SELECT CAST('20130815' AS DATETIME)

这将会得到预期的结果。

1
我猜可能是为了保持向后兼容性。 SQL Server 2008中的新数据类型datetime2date不依赖于SET LANGUAGESET DATEFORMAT。这里有一个连接项,建议同样改变datetime的行为。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接