Utc 日期保存为 Sqlite 中的本地日期
Posted
技术标签:
【中文标题】Utc 日期保存为 Sqlite 中的本地日期【英文标题】:Utc Date saving as Local date in Sqlite 【发布时间】:2015-06-03 06:50:33 【问题描述】:我有一个包含日期字段的 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 中的某些东西导致了此问题。也许我需要运行一个编译指示?根据另一个网站的建议,我尝试将日期格式化如下:
var date = DateTime.UtcNow.ToString("o");
打算将日期强制转换为 ISO-8601 格式,但我没有这样做。
有人有什么想法吗?
【问题讨论】:
这个数据库到底在哪里?在你的本地机器上?还是其他服务器?您是否调试过代码并查看DateTime.UtcNow
究竟返回了什么?
是的,我确实调试了我的代码,只要我能看到它,日期变量就会读取正确的 UTC 日期,直到它进入 Dapper Execute 方法。数据库在远程服务器上
【参考方案1】:
Thomas Levesque 有解决方案here:
// You just need to specify DateTimeKind=Utc in your connection string:
string connectionString = @"Data Source=D:\tmp\testSQLiteDate.db;DateTimeKind=Utc";
【讨论】:
【参考方案2】:这也发生在我身上。 我所做的是自己将日期时间序列化为字符串,然后再将其添加为参数。
internal const string DateTimeFormat = "yyyy-MM-dd HH:mm:ss";
cmd.Parameters.Add("@Threshold", DbType.DateTime).Value = threshold.ToString(DateTimeFormat);
【讨论】:
【参考方案3】:如果你用纯 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);
【讨论】:
以上是关于Utc 日期保存为 Sqlite 中的本地日期的主要内容,如果未能解决你的问题,请参考以下文章