简体   繁体   English

存储在SQL Server中时,我的DateTime中的毫秒数会发生变化

[英]Milliseconds in my DateTime changes when stored in SQL Server

I have a date time that I generate like this: 我有一个像这样生成的日期时间:

DateTime myDateTime = DateTime.Now;

I then store it in the database (in a DateTime typed column) with Entity Framework. 然后,我使用Entity Framework将其存储在数据库中(在DateTime类型列中)。 I then retrieve it with OData (WCF Data Services). 然后我用OData(WCF数据服务)检索它。

When it goes in the TimeOfDay value is: 09:30:03.0196095 当它进入TimeOfDay值时: 09:30:03.0196095

When it comes out the TimeOfDay value is: 09:30:03.0200000 当它出现时,TimeOfDay值为: 09:30:03.0200000

The net effect of this makes it so that the Milliseconds are seen as 19 before it is saved and 20 after it is re-loaded. 这样做的净效果使得Milliseconds在保存前被视为19,在重新加载后被视为20。

So when I do a compare later in my code, it fails where it should be equal. 因此,当我稍后在我的代码中进行比较时,它会在应该相等的地方失败。

Does SQL Server not have as much precision as .NET? SQL Server的精度不如.NET吗? Or is it Entity Framework or OData that is messing this up? 或者实体框架或OData搞砸了吗?

I will just truncate off the milliseconds (I don't really need them). 我将截断毫秒(我真的不需要它们)。 But I would like to know why this is happening. 但我想知道为什么会这样。

This really depends on the version of SQL server you are using. 这实际上取决于您使用的SQL Server的版本。

The resolution of the date time field is to 3 decimal places: For example: 2011-06-06 23:59:59.997 and is only accuracte to within 3.33 ms. 日期时间字段的分辨率为3位小数:例如: 2011-06-06 23:59:59.997并且仅在3.33 ms内精确到达。

In your case, 09:30:03.0196095 is being rounded up to 09:30:03.020 on storage. 在您的情况下, 09:30:03.0196095正在被存储到09:30:03.020

Beginning with SQL 2008, other data types were added to provide more detail, such as datetime2 which has up to 7 decimal places and is accurate to within 100ns. 从SQL 2008开始,添加了其他数据类型以提供更多详细信息,例如datetime2,其最多包含7个小数位,精确到100ns。

See the following for more information: 有关更多信息,请参阅以下内容

http://karaszi.com/the-ultimate-guide-to-the-datetime-datatypes http://karaszi.com/the-ultimate-guide-to-the-datetime-datatypes

I think your best bet is to provide the rounding to the second PRIOR to storing it in SQL server if the milliseconds is unimportant. 我认为最好的办法是在第二个PRIOR中提供舍入,以便在毫秒不重要的情况下将其存储在SQL服务器中。

This is due to the precision of the SQL datetime type. 这是由于SQL datetime类型的精确性。 According to msdn: 根据msdn:

Datetime values are rounded to increments of .000, .003, or .007 seconds 日期时间值四舍五入为.000,.003或.007秒的增量

Look at the Rounding of datetime Fractional Second Precision section of this msdn page and you'll understand how the rounding is done. 查看此msdn页面 的日期时间小数秒精度部分,您将了解舍入的完成方式。

As indicated by others, you can use datetime2 instead of datetime to have a better precision: 如其他人所示,您可以使用datetime2而不是datetime来获得更好的精度:

  • datetime time range is 00:00:00 through 23:59:59.997 datetime时间范围是00:00:00 through 23:59:59.997
  • datetime2 time range is 00:00:00 through 23:59:59.9999999 datetime2时间范围是00:00:00 through 23:59:59.9999999

For those who do not have the ability to use DateTime2 in SQL (ex: like me using tables that are generated by a separate system that would be expensive to change for this single issue), there is a simple code modification that will do the rounding for you. 对于那些无法在SQL中使用DateTime2的人(例如:像我一样使用由单独的系统生成的表,对于这个单一问题而言需要更换的代价很高),有一个简单的代码修改可以进行舍入为了你。

Reference System.Data and import the System.Data.SqlTypes namespace. 引用System.Data并导入System.Data.SqlTypes命名空间。 You can then use the SqlDateTime structure to do the conversion for you: 然后,您可以使用SqlDateTime结构为您执行转换:

DateTime someDate = new SqlDateTime(DateTime.Now).Value;

This will convert the value into SQL ticks, and then back into .NET ticks, including the loss of precision. 这会将值转换为SQL滴答,然后再转换为.NET滴答,包括精度损失。 :) :)

A word of warning, this will lose the Kind of the original DateTime structure (ie Utc , Local ). 一句警告,这将失去原始DateTime结构的Kind (即UtcLocal )。 This conversion is also not simply rounding, there is a complete conversion including tick calculations, MaxTime changes, etc.. So don't use this if you are relying on specific indicators in DateTime as they could be lost. 此转换也不仅仅是舍入,还有完整的转换,包括刻度计算, MaxTime更改等。因此,如果您依赖于DateTime特定指标,请不要使用它,因为它们可能会丢失。

The precision of DateTime in SQL Server is milliseconds ( .fff ). SQL Server中DateTime的精度是毫秒( .fff )。 So 0.0196 would round to 0.020. 所以0.0196将四舍五入到0.020。 If you can use datetime2 , you get a higher precision. 如果可以使用datetime2 ,则可以获得更高的精度。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM