如何将UTC dateTime转换为本地日期时间

时间:2015-07-15 16:04:26

标签: c# linq entity-framework datetime

我的搜索范围功能有问题,因为我们将UTC日期时间存储在数据库中。例如用户商店记录,并且在UTC时区记录的午夜之后标记为“2015-06-23 01:05:34”。由于UTC,我的搜索范围函数会得到错误的结果列表。我尝试使用.ToLocalTime()将日期时间转换为linq中的本地时间我使用此错误

  

“LINQ to Entities无法识别方法'System.DateTime   ToLocalTime()'方法,这个方法无法翻译成一个   商店表达。“

我想询问如何在EF中将utc datetime转换为本地日期时间?

  var rrnForms = (from rrn in db.RrnForms
                            where
                                (DbFunctions.TruncateTime(rrn.RrnVisitPhoneDate) >= fromDateSearch.Date &&
                                 DbFunctions.TruncateTime(rrn.RrnVisitPhoneDate) <= toDateSearch.Date)
                            select rrn).ToList();

2 个答案:

答案 0 :(得分:2)

LINQ to Entities通过将LINQ查询转换为在数据库上执行的SQL语句来工作。 ToLocalTime()方法无法转换为SQL语句,因此您无法在LINQ to Entities查询中使用它。

相反,您需要将边界时间转换为UTC,然后再将它们传递到LINQ语句,然后将结果时间从数据库转换回本地时间(如果需要)。

答案 1 :(得分:1)

强烈敦促您反过来执行转换:在您的.NET代码中,执行从本地时间到UTC的转换(一次),确保您真正应用了正确的时区。然后,您可以将UTC值传递给LINQ查询。

除此之外,这意味着您将转换应用于一个值,而不是数据库中的每一行。

当然,你需要考虑当地时间由于DST转换而无效或模棱两可的情况 - 但这无论如何都是一个问题,只是通过转换明确的方式隐藏。实际上,我会说你最终会得到更简单易懂的结果。想象一下,您的时区是欧洲/伦敦,在2015年10月25日当地时间凌晨2点(UTC时间凌晨1点)从BST(UTC + 1)变为GMT(UTC + 0)。假设您有以下记录:

ID     Date/Time UTC          Date/Time Local (would be computed)
A      2015-10-24T23:45Z      2015-10-25T00:45 (BST)
B      2015-10-25T00:15Z      2015-10-25T01:15 (BST)
C      2015-10-25T00:45Z      2015-10-25T01:45 (BST)
D      2015-10-25T01:15Z      2015-10-25T01:15 (GMT)
E      2015-10-25T01:45Z      2015-10-25T01:45 (GMT)
F      2015-10-25T02:15Z      2015-10-25T02:15 (GMT)

请注意,它们处于严格按UTC升序排列。现在假设您有“本地日期/时间&gt; = 2015-01-25T01:20”的查询。如果您执行UTC到本地转换,那将选择记录C,E和F - 而不是D,因为那是当地时间01:15。我怀疑你想要那个。我怀疑你实际上想要C,D,E和F(如果你将2015-01-25T01:20转换为较早的出现)或者只是E和F(如果你将2015-01-25T01:20转换为后一次出现)