【问题标题】:How does date difference work in SQL Server 2012SQL Server 2012 中的日期差异如何工作
【发布时间】:2015-06-23 07:25:27
【问题描述】:

我在 SSMS 中运行以下查询。这个查询的结果没有任何意义。

问题:SQL Server 在确定与此查询相关的差异时究竟遵循什么逻辑?

  SELECT
  CAST('1/1/1900 11:00:00 PM' AS DATETIME) AS Date1,
  CAST('1/1/1900 7:00:00 AM' AS DATETIME) AS Date2,
  CAST('1/1/1900 7:00:00 AM' AS DATETIME) - CAST('1/1/1900 11:00:00 PM' AS DATETIME)
  AS Date2MinusDate1

此查询的结果

【问题讨论】:

    标签: datetime sql-server-2012


    【解决方案1】:

    问题是内部日期时间数据存储为 8 个字节,由 2 个整数组成:一个表示 19000101 之后的天数,另一个表示午夜之后的滴答声。所以实际上你在这里减去 2 个整数:

    Day of DT1 - Day of DT2
    Ticks of DT1 - Ticks of DT2
    

    天数为 0,因为 19000101 在内部保存为 0。所以第一个减法给你0,即19000101

    tick 的差异将为您提供16 小时,但请注意,它将是从午夜开始的滴答(16 小时),所以实际上您应该从午夜减去16 小时而不是7am。因此00:00 - 16 hours 等于08:00。当然在这里你应该减少一天的子结构的结果,即0-1=18991231

    所以你最终得到18991231 08:00,这是正确的输出。

    但是在使用运算符进行日期操作时应该非常小心,因为存在细微差别。使用本机函数进行此类操作,例如 DATEADD。你可以阅读这篇文章,尤其是从第2页http://www.devx.com/dbzone/Article/34594/0/page/2

    【讨论】:

    • 不,不是。从第 2 页阅读此内容devx.com/dbzone/Article/34594/0/page/2
    • 我认为你应该把这个事实写成你的答案的一部分,即减法对于日期时间值是不可靠的。
    【解决方案2】:

    12/31/1899 是相当于零日期的 SQL。

    这是由于日期不兼容的软件造成的遗留问题。

    看到这个答案:Why is 1899-12-30 the zero date in Access / SQL Server instead of 12/31?

    我会推荐 DATEDIFF 来寻找差异。

    SELECT
      CAST('1/1/1900 11:00:00 PM' AS DATETIME) AS Date1,
      CAST('1/1/1900 7:00:00 AM' AS DATETIME) AS Date2,
      DATEDIFF ( hh , CAST('1/1/1900 7:00:00 AM' AS DATETIME) , CAST('1/1/1900 11:00:00 PM' AS DATETIME)) AS Date2MinusDate1
    

    【讨论】:

    • 但是看起来 datetime 减法是可靠的,因为如果我们添加 Date1 + Date2MinusDate1,那么我们会得到 Date2。因此,SQL Server 2012 中的日期时间算法似乎具有一致性。
    • 这可能与日期格式有关。如果您运行: SELECT CAST('1900-01-01 23:00:00.000' AS DATETIME) AS Date1, CAST('1900-01-01 07:00:00.000' AS DATETIME) AS Date2, CAST('1900- 01-01 23:00:00.000' AS DATETIME) - CAST('1900-01-01 07:00:00.000' AS DATETIME) AS Date2MinusDate1 你得到 4:00PM 这将准确地转换为 16 小时的差异。
    猜你喜欢
    • 2018-05-09
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-03-08
    • 1970-01-01
    • 2022-08-15
    • 1970-01-01
    • 2019-11-09
    相关资源
    最近更新 更多