如何将所有DateTime属性转换为集合中的其他TimeZone?

时间:2018-02-05 22:58:27

标签: c# .net linq datetime timezone

我有一个拥有用户的网站,我有一个API方法来显示用户的最新活动:

public List<UserActivity> GetUserActivity(Guid userId)
{
    return _dbContext.UserActivity
               .Where(ua => ua.UserId.Equals(userId))
               .OrderByDescending(ua => ua.ActivityTime)
               .Take(20)
               .ToList();
}

这些是我要归还的对象:

public class UserActivity
{        
    public Guid UserId { get; set; }
    public DateTime ActivityTime { get; set; }
    public string ActivityTitle { get; set; }
}

我在UTC中将ActivityTime的所有日期存储在我的数据库中。每个用户都可以设置他们所在的时区,因此我希望在调用此API方法时将ActivityTime转换为他们的时区,以便在前端显示。

这样的事情:

public List<UserActivity> GetUserActivity(Guid userId)
{
    MyUser user = _dbContext.MyUsers.FirstOrDefault(u => u.Id.Equals(userId));
    TimeZoneInfo userTimeZone = TimeZoneInfo.FindSystemTimeZoneById(user.TimeZoneId);

    return _dbContext.UserActivity
               .Where(ua => ua.UserId.Equals(userId))
               .OrderByDescending(ua => ua.ActivityTime)
               .Take(20)
               // somehow call TimeZoneInfo.ConvertTimeFromUtc on ActivityTime here
               .ToList();
}

但我不确定如何在集合中的属性上调用TimeZoneInfo.ConvertTimeFromUtc来转换所有属性。有没有办法做到这一点?

2 个答案:

答案 0 :(得分:1)

将所有UserActivity数据存储在内存中后,即可将其转换。

var activities = ...;
TimeZoneInfo userZone = TimeZoneInfo.FindSystemTimeZoneById(user.TimeZoneId);
foreach (var thisActivity in activities)
{
    DateTime localTime = 
       TimeZoneInfo.ConvertTimeFromUtc(thisActivity.ActivityTime, userZone);
    thisActivity.ActivityTime = localTime;
}

答案 1 :(得分:1)

您需要做的重要事情是在为您的EntityFramework DbSet调用ToList()之后转换您的DateTime实体

以下是通过投影您的实体仅使用LINQ的示例:

public List<UserActivity> GetUserActivity(Guid userId)
{
    MyUser user = _dbContext.MyUsers.FirstOrDefault(u => u.Id.Equals(userId));
    TimeZoneInfo userTimeZone = TimeZoneInfo.FindSystemTimeZoneById(user.TimeZoneId);

    var activities = _dbContext.UserActivity
                               .Where(ua => ua.UserId.Equals(userId))
                               .OrderByDescending(ua => ua.ActivityTime)
                               .Take(20)
                               .ToList();

    return activities.Select(a => new UserActivity
    {
        UserId = a.Userid,
        ActivityTitle = a.ActivityTitle,
        ActivityTime = TimeZoneInfo.ConvertTimeFromUtc(a.ActivityTime, userTimeZone)
    }).ToList();
}