SQL Server、Excel 和 MS Access 中的日期差异

Posted

技术标签:

【中文标题】SQL Server、Excel 和 MS Access 中的日期差异【英文标题】:Variance in Dates in SQL Server, Excel and MS Access 【发布时间】:2021-04-20 06:36:20 【问题描述】:

我注意到当我将日期转换为整数时,我在 SQL Server、Excel 和 MS Access 中得到不同的值。

例如,在 SQL Server 中,SELECT CONVERT(INT,CONVERT(DateTime,CONVERT(varchar, '2021-01-01'))) AS MyDate; 给我 44195。

在 Access 中,SELECT CLng(#1/1/2021#) AS MyDate; 给了我 44197。

在 Excel 中,=DATEVALUE("1/01/2021") 也给了我 44197。

为什么 SQL Server 的结果少了 2?

【问题讨论】:

为什么要将日期转换为任意整数?日期不是整数。它们如何在内部存储并不重要。 Excel 没有真正的日期类型,它存储一个 float 并根据单元格样式将其显示为日期。而且 SQL 表达式是完全错误的。 CONVERT(varchar, '2021-01-01') 什么都不做,因为字符串已经是字符串。 CONVERT(Datetime) 需要一个样式参数,否则解析会受服务器的语言环境影响。你可以写cast('2021-01-01' as datetime)cast('2021-01-01' as date) 无论如何,演员阵容毫无意义。它甚至运行的唯一方式是使用旧的datetime。如果您使用datedatetime2,您会收到错误消息cast(cast('2021-01-01' as date) as int)。不要使用这样的演员表 无论如何,在 30 年前,datetime 被存储为 float 偏移量,其中整数部分是相对于 1900-01-01 的一天偏移量,而分数表示 (不精确)一天 24 小时的值。 Excel 和 Access 也是如此,从 ....1899-12-30 开始。如果有的话,SQL Server 偏移量比 Excel 更有意义,但都不应该使用。如果要计算自基准日期以来的天数,请使用 datediff(d,...) 你为什么认为不同的系统会给你相同的价值?对于 SQL Server 1900-01-010 但对于 Excel,它是 1。另外 Excel 有一个 "bug"1900 视为闰年(继承自 Lotus)。这就是为什么有一个不同的2 这让我们回到了第一条评论——你为什么要试图产生这样一个毫无意义的价值?这背后有真正的问题吗?您是否尝试比较 Excel 和 SQL Server 之间的数据并因转换不当而遇到麻烦? 【参考方案1】:

这是因为他们使用不同的起始日期来定义日期时间。

如果您想将日期时间字段转换为整数,请始终选择您自己的原始日期。

例如,当您想使用 1970-01-01 作为参考日期时,请使用:

SELECT DATEDIFF(d, '1970-01-01', '2021-01-01');

如果你想把它转换回一个日期:

SELECT DATEADD(d, 18628, '1970-01-01')

永远不要依赖诸如默认起始日期之类的实施细节。

请注意,您可以通过使用SELECT CAST(0 AS DATETIME) for SQL server (1900-01-01) 或在 Access (1899-12-30) 中使用 SELECT FORMAT(CDATE(0), "Short Date") 轻松获取原始日期,这揭示了 2 天的差异。

【讨论】:

以上是关于SQL Server、Excel 和 MS Access 中的日期差异的主要内容,如果未能解决你的问题,请参考以下文章

为啥 MS-Access 中的 Teradata 查询比 SQL Server 更快

将数据从 MS Sql Server 存储过程导出到 excel 文件

Excel 2007 MS Query 中的多部分标识符错误,但 SQL Server 2008 中没有

使用 DAO 和 Sql Server 链接表的事务

将 MySQL 简单查询转换为 SQL Server

将 MS SQL Server 查询结果导出到 MS Access