考虑以下方案:
DateTime dateTime = new DateTime(634546165144647370);
SqlDateTime sqlDateTime = new SqlDateTime(dateTime);
Console.WriteLine("dateTime.TimeOfDay = " + dateTime.TimeOfDay);
Console.WriteLine("sqlDateTime.TimeOfDay = " + sqlDateTime.Value.TimeOfDay);
Console.ReadLine();它将具有以下输出:
dateTime.TimeOfDay = 10:21:54.4647370
sqlDateTime.TimeOfDay = 10:21:54.4630000我觉得奇怪的是,.464737被四舍五入到了.463。那不是应该转到.464?吗?
我想我还没有在.NET代码中找到一个bug,所以问题是:
为什么这样做?,以及我如何使客户端四舍五入来完成SqlServer将要做的事情?
作为附带说明,我将此日期时间保存到Server数据库(在DateTime列中),并再次将其提取出来,结果显示为DateTime所以我真的很困惑。(我认为SqlDateTime将与Server将要做的工作相匹配。)
注:,因为我在使用OData,所以不能在Server中使用DateTime2。
发布于 2011-10-19 16:37:27
Server DATETIME的准确性为3.33ms -因此,您不可能获得所有可能的值,而且很有可能.464就是这样一个值。
在Server 2008上,您可以使用精度达到100 or的DATETIME2或TIME(x)数据类型--这对于“常规”使用应该足够了。
发布于 2011-10-19 17:22:45
Server的datetype数据类型在内部是两个32位字(整数).高阶单词是自Server使用的内部日历的纪元(零点)以来的几天内的偏移量:该时期为1900年1月1日00:00:00.000。低阶字是从一天开始(00:00:00.000/午夜)以来的偏移量(毫秒).
由于历史原因,低阶字的精度为1毫秒,精度为1/300秒(!?)。这意味着任何给定的时间点被舍入到0,3或7毫秒的增量。
若要以Server的方式进行转换,请执行以下操作:取所考虑的实际时间的毫秒部分,值为0-999,模100。这就给出了低阶数字,一个0-9的值.因此,如果当前时间为23:57:23.559,则毫秒分量为559。模100你得到9。
非常出色!或者别的什么。
参见SQLServer2005BOL下的“备注”一节:http://msdn.microsoft.com/en-us/library/ms187819(v=SQL.90).aspx
所有这些的结果是,您无法对日期范围/时间period...something进行明显的检查,比如
where myDateColumn between '1 September 2011 00:00:00.000'
and '30 September 2011 23:59:59.999'因为这可能会带来下一阶段的一小部分数据。你不能说
where myDateColumn between '1 September 2011 00:00'
and '30 September 2011 23:59:59'因为这可能不包括属于这一期间的数据。相反,你必须说
where myDateColumn >= '1 September 2011 00:00:00.000' and myDateColumn < '1 October 2011 00:00:00.000',或where myDateColumn >= '1 September 2011 00:00:00.000' and myDateColumn <= '30 September 2011 23:59:59.997'应该注意的是,精度为1分钟的smalldatetime表现出同样的假行为:如果正在考虑的时间的秒分量为29.998秒或更短,则将其舍入到最近的分钟;如果为29.999或更高,则将向上舍入到下一分钟,因此值2011年1月00: 00:00:00`。
这有各种各样的含义,特别是WRT的计费系统等。
如果精度对您很重要,请将您的日期/时间值以ISO 8601格式以字符串形式存储在Server中,类似于2011-10-30T23:59:55.1234 (或等效的“紧凑”表单(20111030T235955.1234) )。ISO 8601整理比较正确,转换方便,具有可读性.更好的做法是把它分成两列--一列表示日期(2011-10-30),另一列表示时间(23:59:55.1234)。然后添加第三个计算列,将所有内容放在一起:
create table foo
(
...
transaction_date char(10) not null ,
transaction_time char(12) not null ,
...
iso8601_transaction_datetime as transaction_date + 'T' + transaction_time ,
...
)关于ISO 8601的一个很好的总结是在http://www.cl.cam.ac.uk/~mgk25/iso-time.html。维基百科也有相当好的信息:8601。
发布于 2011-10-19 16:49:52
SqlDateTime结构
表示从1753年1月1日至12月31日9999年间的日期和时间数据,其精度为3.33毫秒,存储在数据库中或从数据库中检索。SqlDateTime结构具有与其相应的.NET框架类型DateTime不同的底层数据结构,后者可以表示12:00 AM 1/1/0001和11:59:59 PM 12/31/9999之间的任何时间,精度可达100纳秒。SqlDateTime实际上将相对差异存储到00:00:00 AM 1/1/1900。因此,从"00:00:00 AM 1/1/1900“到整数的转换将返回0。
我认为sqlDateTime在3.33ms的准确度之内。
DateTime值类型表示日期和时间,其值范围从2001年1月1日午夜12:00:00至公元999年12月31日晚上11:59:59。
作为附带说明,我将此日期时间保存到Server数据库(在DateTime列中),并再次取出它,其结果为10:21:54.4670000。所以我真的很困惑。(我认为SqlDateTime将与Server将要做的工作相匹配。)
时间值以100纳秒单位,称为滴答,一个特定的日期是从午夜12:00,0001,0001 (C.E.)在GregorianCalendar日历中(不包括将由闰秒添加的滴答)。例如,滴答值为31241376000000000L,表示日期,1月1日星期五,0100 :00:00:00午夜。DateTime值总是在显式或默认日历的上下文中表示。
和
在内部,所有DateTime值都表示为自2001年1月1日午夜12:00时起已经过去的滴答数(100纳秒间隔)。实际的DateTime值与在用户界面元素中显示或写入文件时显示该值的方式无关。DateTime值的外观是格式化操作的结果。格式设置是将值转换为其字符串表示形式的过程。 由于日期和时间值的出现取决于文化、国际标准、应用程序要求和个人偏好等因素,因此DateTime结构通过其ToString方法的重载在格式化日期和时间值方面提供了很大的灵活性。默认的DateTime.ToString()方法使用当前区域性的短日期和长时间模式返回日期和时间值的字符串表示。下面的示例使用默认的DateTime.ToString()方法来使用运行示例的计算机上运行该示例的计算机上的en-US区域性的短日期和长时间模式显示日期和时间。
看起来,DateTime在100 is内是准确的,这与您所经历的差别有关。
另外,我将这个日期时间保存到Server数据库(在DateTime列中),并再次取出它,结果为10:21:54.4670000。所以我真的很困惑。(我认为SqlDateTime将与Server将要做的工作相匹配。)
这也是在3.33毫秒的accuracy...If中,你需要比3.33ms更精确的东西,然后你必须使用Server 2008
https://stackoverflow.com/questions/7824766
复制相似问题