SQL Server为何将23:59:59.999转为次日0点?EF+C#场景疑问
问题原因与解决方案
核心原因:SQL Server datetime 类型的精度限制
SQL Server的datetime类型不支持任意毫秒值,它的最小时间单位是1/300秒(约3.333毫秒),因此只能存储毫秒部分为000、003、007、010……997这类符合n*3.333规则的时间点。
当你传入2023-01-01 23:59:59.999时,这个值距离下一个合法精度点2023-01-02 00:00:00.000的差距(0.001毫秒),比距离前一个合法精度点2023-01-01 23:59:59.997的差距(2.333毫秒)更小,所以SQL Server会自动将其四舍五入到最近的合法时间点,也就是第二天的0点。
而2023-01-01 23:59:59.997本身就是datetime支持的合法精度值,因此能被准确存储。
解决方案
- 改用
datetime2类型:如果需要精确存储任意毫秒(甚至纳秒)的时间,将数据库表中的LastDate字段类型改为datetime2(默认精度是7位,支持到100纳秒),这样C#中传入的DateTime值会被完整保留,不会出现舍入问题。 - 适配
datetime的精度规则:如果必须保留datetime类型,确保传入的毫秒值是000、003、007等符合3.333毫秒间隔的数值,避免触发自动舍入。
补充说明
这个问题不是Entity Framework导致的——EF只是将C#的DateTime值传递给数据库,真正的舍入逻辑是SQL Server对datetime类型的处理规则。
内容的提问来源于stack exchange,提问作者Gulfam
相关产品推荐
相关产品推荐

