Created
August 13, 2012 23:27
-
-
Save carolynvs/3344800 to your computer and use it in GitHub Desktop.
Utility for dynamically converting all DateTime properties on an object to UTC
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
using System; | |
using System.Data; | |
using System.Data.Entity; | |
using System.Data.Entity.Infrastructure; | |
using System.Data.Entity.ModelConfiguration; | |
using System.Data.Objects; | |
using System.Linq; | |
using Carolynvs.Model; // Contains Carolynvs.UtcDateTimeConverter which provides UtcDateTimeConverter.Convert(object model) | |
namespace Carolynvs.DAL | |
{ | |
public class MyDataContext : DbContext | |
{ | |
public MyDataContext() | |
{ | |
ObjectContext.ObjectMaterialized += ObjectMaterialized; | |
ObjectContext.SavingChanges += SavingChanges; | |
} | |
protected ObjectContext ObjectContext | |
{ | |
get { return ((IObjectContextAdapter)this).ObjectContext; } | |
} | |
/// <summary> | |
/// Convert all DateTime properties on models saved to the database | |
/// </summary> | |
/// <param name="sender"></param> | |
/// <param name="e"></param> | |
private void SavingChanges(object sender, EventArgs e) | |
{ | |
var context = sender as ObjectContext; | |
if (context == null) | |
return; | |
foreach (ObjectStateEntry entry in context.ObjectStateManager.GetObjectStateEntries(EntityState.Added | EntityState.Modified)) | |
{ | |
UtcDateTimeConverter.Convert(entry.Entity); | |
} | |
} | |
/// <summary> | |
/// Convert all DateTime properties on models retrieved from the database | |
/// </summary> | |
private void ObjectMaterialized(object sender, ObjectMaterializedEventArgs e) | |
{ | |
object model = e.Entity; | |
if (model == null) | |
return; | |
UtcDateTimeConverter.Convert(model); | |
} | |
} | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
using System; | |
using System.Collections.Generic; | |
using System.Linq; | |
using System.Reflection; | |
using Carolynvs.Extensions; // Contains Carolynvs.ObjectExtensions which provides object.Get<T>(string property) and object.Set(string property, T value) | |
namespace Carolynvs.Model | |
{ | |
/// <summary> | |
/// Utility for converting DateTime properties to UTC | |
/// </summary> | |
public static class UtcDateTimeConverter | |
{ | |
private static volatile object _lock = new object(); | |
// Cache of the DateTime properties on each type | |
private static readonly Dictionary<Type, IEnumerable<PropertyInfo>> _typesWithDateTimeProperties = new Dictionary<Type, IEnumerable<PropertyInfo>>(); | |
/// <summary> | |
/// Converts each DateTime property on the specified model to Utc | |
/// </summary> | |
public static void Convert(object model) | |
{ | |
Type modelType = model.GetType(); | |
IEnumerable<PropertyInfo> dateTimeProperties; | |
if (!_typesWithDateTimeProperties.ContainsKey(modelType)) | |
{ | |
lock(_lock) | |
{ | |
if(!_typesWithDateTimeProperties.ContainsKey(modelType)) | |
{ | |
dateTimeProperties = modelType.GetProperties().Where(p => p.PropertyType.GetTypeFromNullable() == typeof(DateTime)); | |
_typesWithDateTimeProperties.Add(modelType, dateTimeProperties); | |
} | |
} | |
} | |
dateTimeProperties = _typesWithDateTimeProperties[modelType]; | |
foreach (PropertyInfo dateTimeProperty in dateTimeProperties) | |
{ | |
DateTime? dateTime; | |
if (dateTimeProperty.PropertyType.IsGenericType) | |
{ | |
dateTime = model.Get<DateTime?>(dateTimeProperty.Name); | |
} | |
else | |
{ | |
dateTime = model.Get<DateTime>(dateTimeProperty.Name); | |
} | |
if (dateTime == null) | |
continue; | |
model.Set(dateTimeProperty.Name, ConvertToUtc(dateTime.Value)); | |
} | |
} | |
/// <summary> | |
/// Converts a DateTime to Utc based on its DateTimeKind, Unspecified is assumed to be UTC | |
/// </summary> | |
public static DateTime ConvertToUtc(DateTime dateTime) | |
{ | |
switch (dateTime.Kind) | |
{ | |
case DateTimeKind.Unspecified: | |
return DateTime.SpecifyKind(dateTime, DateTimeKind.Utc); | |
case DateTimeKind.Local: | |
return dateTime.ToUniversalTime(); | |
default: | |
return dateTime; | |
} | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Read my post on Working with DateTime in ASP.NET Web API