C# 程序想要选择数据 <= 23:59:59,但最终也会选择时间戳为 00:00:00 的数据

本文关键字:数据 选择 时间戳 程序 | 更新日期: 2023-09-27 18:33:36

这是我的第一个问题,所以请原谅可能发生的任何错误:)

我制作了一个 C# 程序,它使用数据表从 SQL Server 数据库收集数据,然后使用 Interop 将结果导出到 Excel 电子表格。程序本身运行良好并按预期运行;但是,当它尝试选择Date列小于或等于的数据时,我发现了一些错误,即 2014-05-31 23:59:59 .

假设我试图获取截至 2014 年 5 月 1 日的所有数据。

我的代码首先启动 SQL 命令的"开始日期"参数,稍后使用如下:

var firstDay = new DateTime(today.Year, today.Month, 1); //2014-05-01 00:00:00`

基于firstDay,它启动参数的日期

var periodTo = firstDay.AddSeconds(-1);`

调试并得到了我想要的时间:2014-04-30 23:59:59

为数据条件添加更多参数后,它将执行该方法以使用提供的参数运行查询。

queryResult = medicore.GenerateRegister(ConfigurationManager.AppSettings["queryDir"], ConfigurationManager.AppSettings["queryName"]);`

periodTo参数将映射到 SQL 脚本中的@EDate变量。 @EDate声明为 Datetime@Edate在这里发挥作用:

Select columns
From tables
Where Voucher.Date <= @EDate

我想,脚本看起来像Where Voucher.Date <= '2014-04-30 23:59:59'

问题是,生成的 Excel 文件中的结果还包括来自 '2014-05-01' 的数据,这些数据不应该存在......至少基于我设定的标准。

C# 和 SQL Server 之间是否发生了某种舍入?

谢谢!

C# 程序想要选择数据 <= 23:59:59,但最终也会选择时间戳为 00:00:00 的数据

这样做的原因可能是Voucher.Date是一个SMALLDATETIME,因此你隐式地将'2014-04-30 23:59:59'转换为SMALLDATETIME

SET DATEFORMAT MDY;
SELECT  CONVERT(SMALLDATETIME, '2014-04-30 23:59:59')

这给出了"2014-05-01"。

为什么不只使用小于运算符,而不是小于或等于?

SET DATEFORMAT MDY;
SELECT  ...
WHERE   Voucher.Date < '2014-05-01';

注意,我已经明确说明了DATEFORMAT,因为yyyy-MM-dd(尽管是 ISO 标准(对于 SQL Server 中的DATETIMESMALLDATETIME数据类型不是文化不变的,如果(像我一样(您位于默认日期格式为 DMY 的国家/地区,那么SELECT CONVERT(SMALLDATETIME, '2014-04-30')会给您一个转换错误。 yyyyMMdd 是这两种类型的唯一区域性固定日期格式。

一篇非常相关且非常相关的文章是 Aaron Bertrand 的 坏习惯踢:处理日期/范围查询不当