我正在尝试使用C#在Access数据库中存储日期时间。我正在Visual Studio 2015中编写应用程序。当我从Access表中读取值时,它与我存储在那里的值不完全匹配。刻度的数量是不同的。我看过一些关于.NET System.DateTime和SQL server DateTimes之间差异的帖子。似乎对于SQL服务器,我应该使用SqlDateTime or a datetime2。在我的情况下,我正在使用遗留的.mdb Access数据库文件。我或许可以升级到accdb文件。
答案 0 :(得分:0)
我知道这可能都是非常明显的,但是假设这不是时区差异问题,正如戴在评论中提到的那样,我的有根据的猜测是,你们都触及了这一点 - 访问数据类型所支持的粒度你们'用于你的日期/时间栏。
根据您使用的数据类型(在任何数据库中),存储值与.NET ticks值之间的粒度和/或转换可能存在差异,这可能导致存储内容与内容之间的差异相对较小被检索。
如果您只需要存储最准确的日期(即不需要在数据库中对该列执行操作),并且必须使用旧的.mdb Access数据库(或任何不提供的数据库)一个具有完美保真度的.NET DateTime类型的数据类型),那么我认为你有两个选择:
找到数据库提供的最佳数值数据类型(理想情况下是无符号64位整数类型),并使用它来手动存储滴答计数,并处理任何分辨率损失。即使它并不完美,您可能会从DB的更广泛的数字类型中获得比其本机“日期/时间”类型更高的粒度。当然,正如戴提到的,你还应该存储时区/偏移信息以及刻度计数。
将滴答计数或text representation of the date and time(再次,包括时区/偏移量)存储为字符串,并在从数据库中读取时对其进行解析。这显然有很大的缺点 - 除了无法对数据库中的值执行操作外,它比其他方法慢一个数量级 - 但如果需要,它确实可以为您提供完美的分辨率。
< / LI> 醇>答案 1 :(得分:0)
如果您尝试存储代表微秒和纳秒的刻度,那么只会存在差异,因为这些可能超出数据类型Date的分辨率,这基本上是双倍的。对于扩展值,其分辨率仅为1毫秒。
因此,你应该对小刻度进行舍入或切割。这可以使用方法ToOADate()
来完成,如下所示:
DateTime dateTime = DateTime.Now;
double oleTime = dateTime.ToOADate();
DateTime convertedTime = DateTime.FromOADate(oleTime);
Console.WriteLine(dateTime.Ticks.ToString());
Console.WriteLine(oleTime.ToString());
Console.WriteLine(convertedTime.Ticks.ToString());
结果如下:
636170456284955745
42715.3984779514
636170456284950000
也可以通过某些VBA日期值的转换后的滴答来说明,包括极值:
' 100-01-01 00:00:00.000 -> 31241376000000000
' 100-01-01 00:00:00.001 -> 31241376000010000
' 100-01-01 00:00:00.002 -> 31241376000020000
' 1899-12-30 00:00:00.000 -> 599264352000000000
' 2018-08-18 03:24:47.000 -> 636701594870000000
' 2018-08-18 18:24:47.000 -> 636702134870000000
' 9999-12-31 23:59:59.000 -> 3155378975990000000
' 9999-12-31 23:59:59.998 -> 3155378975999980000
' 9999-12-31 23:59:59.999 -> 3155378975999990000
请注意,Office和VBA通常会忽略毫秒,但实际上完全有能力持有这些。