Jay*_*len 5 c# asp.net asp.net-mvc datetime asp.net-mvc-5
我正在使用 ASP.NET MVC 5 编写一个应用程序。我要存储在数据库中的所有日期时间必须首先从本地时区转换为 UTC 时区。
我不确定在请求周期内最好的地方在哪里。
我可以在控制器中通过 ViewModel 规则后将每个字段转换为 UTC。但我觉得我必须做的代码/步骤太多了。
实体框架中是否有一种方法允许我添加一条规则,在保存更改之前自动将日期时间转换为 UTC?
这是我编写的方法,它将给定的日期时间转换为 UTC
public static DateTime? ConvertToUTC(DateTime? val, TimeZoneInfo destinationTimeZone = null)
{
if (val != null)
{
var dateTimeToConvert = ConvertToDateTime(val);
if (destinationTimeZone == null)
{
if (ConfigurationManager.AppSettings["LocalTimeZone"] != null)
{
destinationTimeZone = TimeZoneInfo.FindSystemTimeZoneById(ConfigurationManager.AppSettings["LocalTimeZone"]);
}
else
{
destinationTimeZone = TimeZoneInfo.FindSystemTimeZoneById(TimeZone.CurrentTimeZone.StandardName);
}
}
return TimeZoneInfo.ConvertTimeFromUtc(dateTimeToConvert, destinationTimeZone);
}
return null;
}
Run Code Online (Sandbox Code Playgroud)
实体框架中是否有一种方法允许我添加一条规则,在保存更改之前自动将日期时间转换为 UTC?
您可以重写 SaveChanges / SaveChangesAsync 方法并在 DbContext 上调用这些方法之前执行转换。
// on your DbContext type
public override int SaveChanges(){
DateTimeUtcHelper.SetDatesToUtc(this.ChangeTracker.Entries());
return base.SaveChanges();
}
class DateTimeUtcHelper{
internal static void SetDatesToUtc(IEnumerable<DbEntityEntry> changes) {
foreach (var dbEntry in changes.Where(x => ChangesToTrackList.Contains(new[] {EntityState.Added, EntityState.Modified}))){
foreach (var propertyName in dbEntry.CurrentValues.PropertyNames){
// using reflection add logic to determine if its a DateTime or nullable DateTime
// && if its kind = DateTimeKind.Local or Unspecified
// and then convert set the Utc value
// and write it back to the entry using dbEntry.CurrentValues[propertyName] = utcvalue;
}
}
}
}
Run Code Online (Sandbox Code Playgroud)
您需要添加自己的逻辑,以确保不会出现您在非用户更改时更改 DateTime 的情况(即,确保默认情况下您的具体化 DateTimes 设置了 DateTimeKind.Utc 标志或 .如果您为用户更改它,则为本地)。
编辑
DbContext 还需要访问其运行所在的请求上下文的用户配置文件上的时区。也许 SaveChanges 的重载会更适合,因此您可以将其传入,或者如果您正在使用 DI,也许您可以将其注入到创建的DbContext。