【问题标题】:No milliseconds value when reading DateTime values from a SQL database in C#从 C# 中的 SQL 数据库读取 DateTime 值时没有毫秒值
【发布时间】:2010-11-30 11:11:33
【问题描述】:

我在 SQL 服务器中存储了高精度日期,例如

2009-09-15 19:43:43.910

但是,当我将该值转换为 DateTime 时,生成的 DateTime 值的毫秒值为 0:

reader["Timestamp"] = 15/09/2009 19:43:43.000

将这些 DateTime 值精确到毫秒对我来说非常重要 - 最好的方法是什么?

更新:这是执行转换的代码:

DateTime myDate = (DateTime)reader[Timestamp"];

SELECT 声明没有什么特别之处,实际上它是 SELECT * - 没有花哨的演员或任何东西

SqlDataReader 返回的 DateTime 对象似乎根本没有填充毫秒值

【问题讨论】:

  • 你是如何执行转换的?请出示您的代码。
  • 根据价值对您的重要性,您可能需要不同的存储机制。 10^-3 第二部分是四舍五入的。
  • 嗯,我现在可以看到,但是到最近的 003、005 或 007 仍然比我在 C# DateTime 中看到的最接近的精度高很多(即 1.000)跨度>
  • 如果你尝试 reader["Timestamp"].ToString() 会发生什么?
  • 我敢打赌 20 美元你的毫秒数没有被插入到数据库中。

标签: c# sql-server datetime


【解决方案1】:

我遇到了同样的问题,经过阅读后发现,当您检索日期时

DateTime myDate = (DateTime)reader["Timestamp"];

SQLDataReader 会减少毫秒数。但是,如果您使用 SQLDataReader 的 GetDateTime 方法,它会返回一个 DateTime 对象,该对象保留毫秒:

reader.GetDateTime(reader.GetOrdinal("Timestamp"));

【讨论】:

    【解决方案2】:

    【讨论】:

    • 它有点帮助,但那篇文章解释说 DateTime 类型比 SqlDateTime 类型具有更高的精度 - 这种精度在哪里丢失?
    【解决方案3】:

    这是因为 DateTime 的默认格式字符串不包括毫秒。

    如果您使用自定义格式,您将看到毫秒值。

    一个例子:

      public class Program
      {
        private static string connString = @"Data Source=(local);Initial Catalog=DBTest;Integrated Security=SSPI;";
        public static void Main(string[] args)
        {
          using (SqlConnection conn = new SqlConnection(connString))
          {
            conn.Open();
    
            using (SqlCommand cmd = new SqlCommand("SELECT * FROM MilliSeconds"))
            {
              cmd.Connection = conn;
    
              SqlDataReader reader = cmd.ExecuteReader();
              while(reader.Read())
              {
                DateTime dt = (DateTime)reader["TimeCollected"];
                int milliSeconds = dt.Millisecond;
                Console.WriteLine(dt.ToString("yyyy-MM-dd HH:mm:ss.fff"));
              }
            }
          }
    
          Console.ReadLine();
        }
      }
    

    来自具有这些值的数据库:

    1   2009-09-22 18:11:12.057 
    2   2009-09-22 18:11:28.587 
    3   2009-09-22 18:11:29.820
    

    上面代码的输出结果是:

    2009-09-22 18:11:12.057 
    2009-09-22 18:11:28.587 
    2009-09-22 18:11:29.820
    

    【讨论】:

    • 对不起,不是 Timestamp.ToString("yyyy-MM-dd HH:mm:ss.fff") 返回 19:43:43.000 - 请注意,毫秒值都是 0 时910 在数据库中。
    • 好吧,我不同意你的看法。我已经从我的示例代码中添加了结果输出。
    【解决方案4】:

    以下是我尝试解决此问题的方法:

    1. 在调试器中单步执行并查看 reader[Timestamp"] 的类型和值。如果类型不是 SqlDateTime,那会让我产生怀疑——然后我会查看查询以确定为什么该列返回另一种类型而不是 DATETIME(或 DATETIME2 等)

    2. 如果该值是 SqlDateTime 并且确实包含毫秒,那么我会将强制转换视为问题的根源。为了验证这一点,我会尝试(在调试器或代码中)SqlDataReader.GetDateTime() 和 SqlDataReader.GetSqlDateTime() 来查看是否返回正确的结果。诚然,这似乎不太可能成为问题的根源——铸造应该可以正常工作。

    3. 如果 #1 中的值是 SqlDateTime 但不包含毫秒,那么我会查看数据库中的上游问题 - 换句话说,您的查询返回的内容没有毫秒。当您在 Management Studio 中执行完全相同的查询时,您会看到毫秒吗?

    我猜这是一个与查询相关的问题。但我很想找到我们的更多。

    【讨论】:

    • 阅读器的类型["Timestamp"] 是 System.DateTime - 尝试转换为 SqlDateTime 失败。
    • 查询是一个简单的“SELECT * FROM ...” - 在这种情况下...非常复杂,但是我在 Sql Server Management Studio 中执行了完全相同的查询,然后查看毫秒值。
    • 使用 reader.GetSqlDateTime() 会得到什么?此外,另一种可能性可能是(如果您的“...”是连接)来自不同表的两个库具有相同的名称但具有不同的值。这很容易通过在查询中用一个列名替换 * 来测试。
    • 原来我的问题毕竟出在查询上——我必须捕获分析器跟踪并执行确切的查询,但毫秒值是空的。
    【解决方案5】:

    我遇到了同样的问题,我通过将 C# DateTime 持久化为 SQL bigint 并填充了 DateTime.Ticks 来解决它。这保留了完整的 DateTime 精度。当然可以使用 DateTime(long ticks) 构造函数进行反序列化。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2011-08-25
      • 1970-01-01
      • 1970-01-01
      • 2019-08-22
      • 2020-06-05
      • 1970-01-01
      • 2021-03-19
      • 2012-10-21
      相关资源
      最近更新 更多