简体   繁体   English

Access数据库中的日期时间不匹配问题

[英]Datetime mismatch problems in Access database

I'm trying to store a datetime in an Access database using C#. 我正在尝试使用C#将日期时间存储在Access数据库中。 I'm writing the app in Visual Studio 2015. When I read the value out of the Access table it doesn't exactly match the value that I stored in there. 我正在Visual Studio 2015中编写应用程序。当我从Access表中读取值时,它与我存储在其中的值不完全匹配。 The number of ticks is different. 刻度数不同。 I've seen some posts about the differences between .NET System.DateTime and SQL server DateTimes. 我看过一些有关.NET System.DateTime和SQL Server DateTimes之间差异的帖子。 It appears that for SQL server I should use a SqlDateTime or a datetime2 . 看来对于SQL Server,我应该使用SqlDateTime或datetime2 In my case I'm using a legacy .mdb Access database file. 就我而言,我使用的是旧版.mdb Access数据库文件。 I might be able to upgrade to an accdb file. 我也许可以升级到accdb文件。

I know this may all be totally obvious, but assuming it's not a timezone difference issue, as Dai suggested in the comments, my educated guess is that it's something you both touched on -- the granularity supported by the Access data type you're using for your date/time column. 我知道这可能是完全显而易见的,但是假设这不是时区差异问题,正如Dai在评论中所建议的那样,我有根据的猜测是,这两者都涉及到-您所使用的Access数据类型支持的粒度为您的日期/时间列。

Depending on what data type you use (in any database), there may be a difference in the granularity and/or translation between the stored value and the .NET ticks value that can cause relatively small differences between what is stored and what is retrieved. 根据您使用的数据类型(在任何数据库中),存储值和.NET ticks值之间的粒度和/或转换可能有所不同,这可能导致存储的内容和检索的内容之间的差异较小。

If you only need to store the most accurate date possible (ie don't need to perform operations on that column in the DB), and have to use a legacy .mdb Access database (or any database that doesn't offer a data type with perfect fidelity for the .NET DateTime type), then I think you have two options: 如果您只需要存储最准确的日期(即不需要在数据库中的该列上执行操作),并且必须使用旧版.mdb Access数据库(或任何不提供数据类型的数据库) .NET DateTime类型具有完美的保真度),那么我认为您有两种选择:

  1. Find the best numeric data type (ideally an unsigned 64-bit integer type) offered by the database and use that to manually store the ticks count, and handle any loss of resolution. 查找数据库提供的最佳数字数据类型(最好是无符号的64位整数类型),并使用它来手动存储滴答计数,并处理任何分辨率的损失。 Even if it's not perfect, you will likely get higher granularity from one of the DB's wider numeric types than you might from its native "date/time" type. 即使它不是完美的,与数据库的本机“日期/时间”类型相比,您可能会从数据库的一种更宽泛的数字类型中获得更高的粒度。 Of course, as Dai mentioned, you should also store the timezone/offset information along with the tick count. 当然,正如Dai所述,您还应该存储时区/偏移量信息以及滴答计数。

  2. Store either the tick count or the text representation of the date and time (again, including timezone/offset) as a string, and parse it when you read it from the database. 将滴答计数或日期和时间 (再次包括时区/偏移量)的文本表示形式存储为字符串,并在从数据库中读取时进行解析。 This obviously has big downsides -- besides not being able to perform operations on the values in the DB, it's an order of magnitude slower than other methods -- but it does give you perfect resolution if that is a requirement. 这显然具有很大的缺点-除了无法对数据库中的值执行运算外,它比其他方法要慢一个数量级-但这确实为您提供了完美的解决方案。

There will only be a difference if you try to store ticks representing microseconds and nanoseconds as these may be beyond the resolution of data type Date which basically is a double. 仅当您尝试存储代表微秒和纳秒的滴答时才会有区别,因为这些滴答可能超出了数据类型Date的分辨率,而Date基本上是双精度的。 For extended values the resolution of this is one millisecond only. 对于扩展值,此分辨率仅为一毫秒。

Thus, you should round or chop the small ticks. 因此,您应该四舍五入或切碎小刻度线。 This can be done with method ToOADate() as demonstrated here: 可以使用方法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());

The result is like: 结果是这样的:

636170456284955745
42715.3984779514
636170456284950000

It can also be illustrated by the converted ticks of some VBA Date values including the extreme: 也可以通过某些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

Note please, that Office and VBA normally ignores milliseconds but actually is perfectly capable of holding these. 请注意,Office和VBA通常会忽略毫秒,但实际上完全可以保留毫秒。

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

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