【问题标题】:SQL Server: Why are dates in ISO-8601 format language dependent?SQL Server:为什么 ISO-8601 格式的日期取决于语言?
【发布时间】:2014-02-13 16:19:01
【问题描述】:

我需要一些帮助来理解 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)。只使用转换呢?
  • @Brett Schneider:我知道它是;但是我问的是 ISO-8601 格式日期的处理。
  • “每种语言使用的确切格式”在dateformatsys.syslanguages 列中。
  • @Mikael Eriksson:dateformat 列中的值是德语的 dmy,但 ISO 格式是 YYYY-MM-DD。有些不匹配。
  • 是的,这是因为在dmyYYYY-MM-DD 中,天早于月份,而在YYYY-MM-DD 中,月份早于天。 SQL Server 足够聪明,可以找到一个四位数的年份,即使它与dmy 中的位置不匹配,但是在查找月份和日期时,它使用SET DATEFORMAT 中的dm 的顺序来找出什么是月份和星期几。

标签: sql sql-server date datetime iso


【解决方案1】:

我的猜测是保持向后兼容性。 SQL Server 2008 中的新数据类型datetime2date 不依赖于SET LANGUAGESET DATEFORMAT。这是一个connect item,它建议也改变datetime 的行为。

【讨论】:

    【解决方案2】:

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

    这可能无法回答您的问题,但对于 日期,有一种适用于所有语言环境的字符串格式:'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)
    

    这将给出预期的结果。

    【讨论】:

      【解决方案3】:

      这个相关问题可能对语言和 ISO-8601 日期格式有所帮助。 Why is SQL Server misinterpreting this ISO 8601 format date?

      有关 SQL Server 使用的日期时间类型的更多信息,请参阅文章The ultimate guide to the datetime datatypes,该文章也在答案中链接。

      【讨论】:

        猜你喜欢
        • 2013-11-03
        • 2016-03-06
        • 1970-01-01
        • 1970-01-01
        • 2013-05-22
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2010-10-06
        相关资源
        最近更新 更多