使用 SQL DATETIME 规则对 DateTime 进行舍入

Posted

技术标签:

【中文标题】使用 SQL DATETIME 规则对 DateTime 进行舍入【英文标题】:Round DateTime using SQL DATETIME rules 【发布时间】:2016-04-03 00:15:12 【问题描述】:

假设有一些代码将 DateTime 对象与已从 SQL Server保存并返回、存储在 DATETIME 对象中的 DateTime 对象进行比较。

比较是在 hh:mm:ss-equality 上完成的,但 SQL Server 可能会在保存时“更改”第二个组件,这导致比较失败大约 1.5/1000 次。

这是因为当 SQL Server will round/truncate this value 作为 DATETIME 值保存在数据库中时:

日期时间值以 0.000、0.003 或 0.007 秒的增量四舍五入。

是否有(标准)C#/.NET 函数可以进行相同的舍入?

这个问题的主要目标是在保存之前标准化值,以用于比较。也就是说,F(original) == F(saved) 应该始终为真。

最终的总体目标是确保值“在正确的秒内”保存,以便将 hh:mm:01.999 存储为 hh:mm:01.997。这将允许 hh:mm:ss 相等比较是可靠的,无论是对原始 DateTime 值还是恢复值进行。在这种情况下,original.Second == F(original).Second 也应该始终为真。

无论好坏,一个广泛使用的假设是按 hh:mm:ss 进行比较,因此 2 毫秒的简单 epsilon-compare 已结束;虽然我不会反对一个强烈争论的比较函数,它也可能解决最终目标。

【问题讨论】:

【参考方案1】:

SqlDateTime structure 存储日期/时间值的方式与 SQL Server 的 datetime 类型相同。它提供与 .NET DateTime 类型之间的转换,并在执行转换时进行舍入。

请注意,您的问题中有相互矛盾的要求。您说您想要与 SQL Server 相同的舍入。您还说您希望舍入永远不会更改“第二个”组件。你不能两全其美。如果您需要不更改“第二个”组件,则可能需要自己实现。您可以在转换完成后检查第二个是否更改,然后将其恢复,或者您可以自己执行转换以始终向下舍入。

【讨论】:

是的~我只是在摸索选项。现在,我倾向于按 SQL 进行舍入,然后进行修复,这样它就不会舍入。这将使 .9985+ 的值变为 .997(在第一次四舍五入为 .0 之后),但这也意味着代码可以“保持”相同的秒数。 这确实意味着如果时间值应该均匀分布,您会得到一个统计异常,其中.997 毫秒值变得比应有的可能性更大。这可能不是问题,但您应该意识到这一点。 我们[显然]没有那么复杂:D

以上是关于使用 SQL DATETIME 规则对 DateTime 进行舍入的主要内容,如果未能解决你的问题,请参考以下文章

在 SQL DateTime 中转换字符串 (yyyy-MM-dd HH:mm TT) 时出错

mysqlbinlog命令使用

时间datetime模块

datetime

datetime处理日期和时间

datetime处理日期和时间