Utc日期在Sqlite中保存为本地日期

时间:2015-03-30 09:50:54

标签: c# sql sqlite datetime dapper

我有一个包含日期字段的Sql数据库。

我使用Dapper更新数据库,如下所示:

const string sql = "UPDATE AdminDb.Users " +
                   "SET IsLoggedOn = 1, LastLoggedOn = @LastLoggedOn " +
                   "WHERE Username = @username";
var date = DateTime.UtcNow;
DatabaseConnectionBase.DatabaseConnection.Execute(sql, new { username, LastLoggedOn = date });

我发现在实际更新之前断开时我非常烦恼,日期变量读取 30/3/2015 9:32:54 但是当我运行更新时,数据库将日期保存为 30/3/2015 10:32:54

由于英国昨天从GMT改为BST(UTC +1),我确信数据库似乎正试图弥补这个问题,因为此问题从未出现过。

我认为通过使用DateTime.UtcNow属性来保存我的日期,我避免了这类问题。

在验证用户时,这会导致严重问题。

  • 我确信这不是我的代码,因为日期是正确的进入Dapper Execute方法。
  • 我无法理解为什么Dapper会尝试弥补,因为大多数开发人员都会对这种功能感到尖叫
  • 这让我得出的结论是,它必定是Sqlite中导致此问题的原因。也许我需要运行一个pragma?

根据其他网站的建议,我尝试按如下方式格式化日期:

var date = DateTime.UtcNow.ToString("o");

意图是将日期强制为ISO-8601格式,但我没有运气。

有没有人有任何想法?

3 个答案:

答案 0 :(得分:12)

Thomas Levesque有解决方案here

// You just need to specify DateTimeKind=Utc in your connection string:
string connectionString = @"Data Source=D:\tmp\testSQLiteDate.db;DateTimeKind=Utc";

答案 1 :(得分:2)

这也发生在我身上。 在将其添加为参数之前,我所做的是将日期时间序列化为字符串。

internal const string DateTimeFormat = "yyyy-MM-dd HH:mm:ss";
cmd.Parameters.Add("@Threshold", DbType.DateTime).Value = threshold.ToString(DateTimeFormat);

答案 2 :(得分:1)

如果你使用纯ADO.NET做同样的事情,同样的事情会发生吗?我想知道这是数据库的东西还是提供者的东西,而不是库的东西。 Dapper必须ToLocalTime()ToUniversalTime()来电 - 它会不加改变地传递时间。在SQL Server上,以下在BST设置中正常工作:

    public void SO29343103_UtcDates()
    {
        const string sql = "select @date";
        var date = DateTime.UtcNow;
        var returned = connection.Query<DateTime>(sql, new { date }).Single();
        var delta = returned - date;
        Assert.IsTrue(delta.TotalMilliseconds >= -1 && delta.TotalMilliseconds <= 1);
    }