【问题标题】:Datetime mismatch problems in Access databaseAccess数据库中的日期时间不匹配问题
【发布时间】:2016-12-11 02:31:52
【问题描述】:

我正在尝试使用 C# 将日期时间存储在 Access 数据库中。我正在 Visual Studio 2015 中编写应用程序。当我从 Access 表中读取值时,它与我存储在其中的值不完全匹配。滴答数不同。我看过一些关于 .NET System.DateTime 和 SQL server DateTimes 之间差异的帖子。看来,对于 SQL 服务器,我应该使用SqlDateTime or a datetime2。就我而言,我使用的是旧版 .mdb Access 数据库文件。我也许可以升级到 accdb 文件。

【问题讨论】:

  • Access(MDB 和 AccDB)支持直接存储 DateTime 值。如果您观察到差异,可能是由于时区转换。您应该在所有持久性介质中将 UTC 值存储为 DateTimeOffset,而不仅仅是数据库。
  • ...所以我的观点是,您不应该天真地将 Ticks 存储在数据库中(因为并非每个消费系统都使用相同的 tick 时期和分辨率)。但如果这样做,请确保使用足够大的整数列类型(即至少 64 位)。请注意,Access 默认使用 4 字节整数,而不是 8 字节。
  • 那么基本上在数据库中保存一个DateTimeOffSet(myDateTime)?
  • 您如何使用您的数据库?您是否使用“原始”ADO.NET(OleDbReaderOdbcDataReader?)、DataTables?实体框架? NHibernate?

标签: c# .net datetime ms-access


【解决方案1】:

我知道这可能很明显,但假设这不是时区差异问题,正如 Dai 在 cmets 中所建议的那样,我有根据的猜测是,这是你们俩都接触过的东西——你们的 Access 数据类型支持的粒度'用于您的日期/时间列。

根据您使用的数据类型(在任何数据库中),存储的值和 .NET 刻度值之间的粒度和/或转换可能存在差异,这可能会导致存储的内容和存储的内容之间存在相对较小的差异已检索。

如果您只需要尽可能存储最准确的日期(即不需要对数据库中的该列执行操作),并且必须使用旧的 .mdb Access 数据库(或任何不提供.NET DateTime 类型具有完美保真度的数据类型),那么我认为您有两个选择:

  1. 找到数据库提供的最佳数字数据类型(理想情况下是无符号 64 位整数类型),并使用它手动存储滴答计数,并处理任何分辨率损失。即使它不完美,您也可能从数据库的一种更广泛的数字类型中获得比从其本机“日期/时间”类型获得的粒度更高的粒度。当然,正如戴所说,您还应该将时区/偏移信息与滴答计数一起存储。

  2. 将滴答计数或text representation of the date and time(同样,包括时区/偏移量)存储为字符串,并在从数据库中读取时对其进行解析。这显然有很大的缺点——除了不能对数据库中的值执行操作之外,它比其他方法慢一个数量级——但如果需要,它确实可以为您提供完美的解决方案。

【讨论】:

    【解决方案2】:

    只有当您尝试存储表示微秒和纳秒的刻度时才会有所不同,因为这些可能超出数据类型 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 通常会忽略毫秒,但实际上完全能够容纳这些。

    【讨论】:

      猜你喜欢
      • 2017-05-17
      • 2013-04-13
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-05-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多