Utc 日期在 Sqlite 中保存为本地日期
Utc Date saving as Local date in Sqlite
我有一个 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/201510:32:54
由于英国昨天从 GMT 更改为 BST (UTC +1),我确信数据库似乎正在尝试对此进行补偿,因为这个问题以前从未出现过。
我以为我已经通过使用 DateTime.UtcNow 属性 来保存我的约会避免了这类问题。
这会在验证用户时导致严重问题。
- 我确定这不是我的代码,因为进入 Dapper Execute 方法的日期是正确的。
- 我不明白为什么 Dapper 会尝试补偿,因为大多数开发人员都会对此类功能大喊大叫
- 这让我得出结论,一定是 Sqlite 中的某些东西导致了这个问题。也许我需要一个 pragma 运行?
根据另一个网站的建议,我尝试按如下方式格式化日期:
var date = DateTime.UtcNow.ToString("o");
目的是将日期强制转换为 ISO-8601 格式,但我没有成功。
有人有什么想法吗?
如果你用 pure ADO.NET 做同样的事情,会发生同样的事情吗?我想知道这是数据库的事情还是提供者的事情,而不是图书馆的事情。 Dapper 必须 ToLocalTime()
或 ToUniversalTime()
调用 - 它会原封不动地传递时间。在 SQL 服务器上,以下在 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);
}
我也遇到过这种情况。
我所做的是在将日期时间添加为参数之前自己将其序列化为一个字符串。
internal const string DateTimeFormat = "yyyy-MM-dd HH:mm:ss";
cmd.Parameters.Add("@Threshold", DbType.DateTime).Value = threshold.ToString(DateTimeFormat);
Thomas Levesque 有解决方案 here:
// You just need to specify DateTimeKind=Utc in your connection string:
string connectionString = @"Data Source=D:\tmp\testSQLiteDate.db;DateTimeKind=Utc";
我有一个 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/201510:32:54
由于英国昨天从 GMT 更改为 BST (UTC +1),我确信数据库似乎正在尝试对此进行补偿,因为这个问题以前从未出现过。
我以为我已经通过使用 DateTime.UtcNow 属性 来保存我的约会避免了这类问题。
这会在验证用户时导致严重问题。
- 我确定这不是我的代码,因为进入 Dapper Execute 方法的日期是正确的。
- 我不明白为什么 Dapper 会尝试补偿,因为大多数开发人员都会对此类功能大喊大叫
- 这让我得出结论,一定是 Sqlite 中的某些东西导致了这个问题。也许我需要一个 pragma 运行?
根据另一个网站的建议,我尝试按如下方式格式化日期:
var date = DateTime.UtcNow.ToString("o");
目的是将日期强制转换为 ISO-8601 格式,但我没有成功。
有人有什么想法吗?
如果你用 pure ADO.NET 做同样的事情,会发生同样的事情吗?我想知道这是数据库的事情还是提供者的事情,而不是图书馆的事情。 Dapper 必须 ToLocalTime()
或 ToUniversalTime()
调用 - 它会原封不动地传递时间。在 SQL 服务器上,以下在 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);
}
我也遇到过这种情况。 我所做的是在将日期时间添加为参数之前自己将其序列化为一个字符串。
internal const string DateTimeFormat = "yyyy-MM-dd HH:mm:ss";
cmd.Parameters.Add("@Threshold", DbType.DateTime).Value = threshold.ToString(DateTimeFormat);
Thomas Levesque 有解决方案 here:
// You just need to specify DateTimeKind=Utc in your connection string:
string connectionString = @"Data Source=D:\tmp\testSQLiteDate.db;DateTimeKind=Utc";