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
。如果您使用date
或datetime2
,您会收到错误消息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-01
是 0
但对于 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 文件