错误 – SqlDateTime溢出。 必须介于1/1/1753 12:00:00 AM和12/31/9999 11:59:59 PM之间

我一直在使用我写的这段代码,它以这种最不清晰的方式工作。 我希望在包含两列DateTime的数据库中插入一行:

myrow.ApprovalDate = DateTime.Now myrow.ProposedDate = DateTime.Now 

然而,当我更新数据库时,我收到这个错误:

SqlDateTime溢出。 必须介于1/1/1753 12:00:00 AM和12/31/9999 11:59:59 PM之间。

我甚至尝试从数据库中复制插入的值,并将其硬编码到正在更新的对象中:

 // I copied this value from the DB myrow.ApprovalDate = Convert.ToDateTime("2008-12-24 00:00:00.000"); 

还有一个相同的错误,奇怪的部分是,上面的技巧工作的第一次插入到数据库,但从那里失败。 任何想法是怎么回事?

C#中的DateTime是一个值types,而不是引用types,因此不能为空。 但是它可以是常量DateTime.MinValue ,它不在Sql Server DATETIME数据types的范围内。

值types保证始终有一个(默认)值(零),而不总是需要明确设置(在这种情况下DateTime.MinValue)。

结论是你可能有一个未设置的date时间值,你试图传递给数据库。

 DateTime.MinValue = 1/1/0001 12:00:00 AM DateTime.MaxValue = 23:59:59.9999999, December 31, 9999, exactly one 100-nanosecond tick before 00:00:00, January 1, 10000 

MSDN: DateTime.MinValue


关于Sql Server

约会时间
date和时间数据从1753年1月1日到9999年12月31日,精确到百分之一秒(相当于3.33毫秒或0.00333秒)。 数值被四舍五入到.000,.003或.007秒的增量

SMALLDATETIME
date和时间数据从1900年1月1日到2079年6月6日,准确到分钟。 小于或等于29.998秒的smalldatetime值会舍入到最接近的分钟; 29.999秒或更高的值被四舍五入到最接近的分钟。

MSDN: Sql Server的DateTime和SmallDateTime


最后,如果您发现自己将C# DateTime作为string传递给sql,则需要按照以下格式进行格式化,以保持最高精度并防止sql server发出类似的错误。

 string sqlTimeAsString = myDateTime.ToString("yyyy-MM-ddTHH:mm:ss.fff"); 

更新(8年后)

考虑使用sql DateTime2数据types,该数据types的date范围为0001-01-01 through 9999-12-31 ,时间范围为00:00:00 through 23:59:59.9999999

 string dateTime2String = myDateTime.ToString("yyyy-MM-ddTHH:mm:ss.fffffff"); 

MSDN datetime2(Transact-SQL)

我发现在很多数据库相关的错误之后,对SQL最小/最大date使用以下工作相当不错:

 DateTime rngMin = (DateTime)System.Data.SqlTypes.SqlDateTime.MinValue; DateTime rngMax = (DateTime)System.Data.SqlTypes.SqlDateTime.MaxValue; 

你有两列的代码看起来不错。 查找该映射类上的任何其他date时间列。 另外,启用datacontext上的日志logging以查看查询和参数。

 dc.Log = Console.Out; 

DateTime初始化为c#的0 – 即0001-01-01。 这是由linqtosql通过SQLstring文字“0001-01-01”传输到数据库。 Sql不能从这个dateparsingT-SQLdate时间。

有几个方法可以解决这个问题:

  • 确保使用SQL可以处理的值初始化所有date时间(如Sql的0:1900-01-01)
  • 确保可能偶尔省略的date时间是可以为空的date时间

当将.Net DateTime与SqlDateTime.MinValue或MaxValue比较时,请小心。 例如,以下将引发exception:

 DateTime dte = new DateTime(1000, 1, 1); if (dte >= SqlDateTime.MinValue) //do something 

原因是MinValue返回一个SqlDateTime,而不是DateTime。 所以.net试图将dte转换为SqlDateTime进行比较,因为它超出了可接受的SqlDateTime范围,所以会抛出exception。

对此的一个解决scheme是比较你的DateTime和SqlDateTime.MinValue。 价值

有时,为了编写更less的代码,通过将字段的缺省值设置为GETDATE()NEWID() ,SQL Server将使用SQL Server设置字段,如插入date,时间和ID。

在这种情况下,实体类中这些字段的Auto Generated Value属性应该设置为true。

这样你就不需要在代码中设置值(防止能源消耗!!!),也不会看到这个exception。

如果您尝试将DateTimetypes的variables设置为null,则会发生此错误。 声明variables为空,即DateTime? 。 这将解决问题。

这通常意味着将null发布到查询中,而不是您期望的值,您可以尝试运行SQL Profiler以准确查看从linq传递给SQL Server的内容。

我看到同样的事情。 错误不会发生在插入行上,而是发生在更新上。 我引用的表有两个不能为空的DateTime列。

我得到的情况下得到的行,并立即保存它(没有数据更改)。 得到工作正常,但更新失败。

我们使用的是NHibernate 3.3.1.4000

通常这种错误来自你做date时间转换或parsing。 检查托pipe应用程序的服务器中的日历设置,主要是时区和短date格式,并确保将其设置为位置的正确时区。 希望这可以解决这个问题。

使用扩展方法

  public static object ToSafeDbDateDBnull(this object objectstring) { try { if ((DateTime)objectstring >= SqlDateTime.MinValue) { return objectstring; } else { return DBNull.Value; } } catch (Exception) { return DBNull.Value; } } DateTime objdte = new DateTime(1000, 1, 1); dte.ToSafeDbDateDBnull(); 

如果你使用NHibernate的ORM检查你的date时间文件是可空的,并在你的NHibernate地图文件设置为空。

我有这个问题,并尝试了很多时间来检查所有的代码,并最终find它。

DateTime.MinValue和DateTime.MaxValue

 DateTime.MinValue = 1/1/0001 12:00:00 AM DateTime.MaxValue = 23:59:59.9999999, December 31, 9999, exactly one 100-nanosecond tick before 00:00:00, January 1, 10000