与其说是问题,不如说是警告:
今天早上我们解决了一个非常令人费解的错误。我们有各种报告,允许用户输入他们想要运行的日期范围。假设是,如果您要求提供 2010 年 8 月 1 日至 2010 年 8 月 10 日的报告,您的意思是include2010 年 8 月 10 日,因此报告的结束日期不是 8 月 10 日,而是在那之后。
它不可能是 2010 年 8 月 11 日,因为其中一些报告汇总了一天中发生的所有情况,并按当天午夜进行分组,因此每日汇总将包括额外的一天 - 这不是我们想要的。
为了避免在接近一天结束时遗漏任何项目的可能性,我们将结束日期计算为比明天少“一个刻度”:
public static DateTime EndOfDay(DateTime day)
{
return day.Date.AddDays(1).AddTicks(-1);
}
在内部,这最终类似于 8/10/2010 12:59:59.9999PM
那么,当您将此 DateTime 传递给 SQL Server 中的 DATETIME 参数时,它会将值向上舍入为 8/11/2010 00:00:00!由于我们的查询使用
DateField BETWEEN @FromDate AND @ToDate
代替
DateField >= @FromDate AND DateField < @ToDate
我们看到 2010 年 8 月 1 日至 2010 年 8 月 10 日的报告包含 2010 年 8 月 11 日的项目。
我们发现真正问题的唯一方法是通过字符串来回传递日期。 DateTime.ToString() 也会进行舍入,因此我们最终得到 SQL Server 满意的 8/1/2010 12:59:59PM。
现在我们的“一天结束”方法如下所示:
public static DateTime EndOfDay(DateTime day)
{
// Cant' subtract anything smaller (like a tick) because SQL Server rounds UP! Nice, eh?
return day.Date.AddDays(1).AddSeconds(-1);
}
抱歉,这不是一个问题 - 只是认为有人可能会发现它有用。