Linq2EF:使用TimeZone偏移返回DateTime

时间:2010-09-29 18:20:24

标签: datetime linq-to-sql timezone

我们的数据库所有时间都存储为UTC,我们知道用户的当前时区,所以想要相对于它返回它。因此我们希望将偏移量合并到LINQ投影中:

var users = from u in this.Context.Users
            select new UserWithCorrectedDate
            {
                Id = u.Id,
                FirstName = u.FirstName,
                LastName = u.LastName,
                RegistrationDate = u.RegistrationDate.Value.AddHours(-5)
            };

当然,Linq2EF无法将“AddHours”转换为规范函数。还有另一种方法吗?

更新:

另一种想法是,如果时区偏移量作为另一列存储在数据库中,是否有办法让数据库执行计算(日期+偏移量)?

2 个答案:

答案 0 :(得分:4)

Linq to Entities支持SqlFunctions。如果您知道偏移的小时数,您可以执行以下操作:

var users = from u in this.Context.Users
            select new UserWithCorrectedDate
            {
               Id = u.Id,
               FirstName = u.FirstName,
               LastName = u.LastName,
               RegistrationDate = SqlFunctions.DateAdd("hour", -5, u.RegistrationDate.Value)
            };

如果你想通过使用时区功能更精确,你可以做这样的事情(这是一个解决方法):

public static DateTime UtcToNewYorkTime(DateTime utcDateTime)
{
        TimeZoneInfo tzi = TimeZoneInfo.FindSystemTimeZoneById("Eastern Standard Time");

        DateTime converted = TimeZoneInfo.ConvertTimeFromUtc(utcDateTime, tzi);
        return converted;
}

然后在您的POCO UserWithCorrectedDate对象中,为Timezoned日期设置一个get only属性,即

public class UserWithCorrectDate
{
    public DateTime UTCDate {get;set;}
    public DateTime NYDate
    {
         get
        {
            return Utilities.UtcToNewYorkTime(this.UTCDate);
        }
    }
}

答案 1 :(得分:0)

快速而肮脏的方法是转换为列表,只需要linq to object来完成它:

from u in this.Context.Users.ToList()
select new { ... }