请参阅http://derreckdean.wordpress.com/2013/04/24/converting-all-datetime-properties-of-an-object-graph-to-local-time-from-utc/的博客文章。我用这个代码到一个WCF响应对象图转换为具有所有本地时间:
/// <summary>
/// Since all dates in the DB are stored as UTC, this converts dates to the local time using the Windows time zone settings.
/// </summary>
public static class AllDateTimesAsUTC
{
/// <summary>
/// Specifies that an object's dates are coming in as UTC.
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="obj"></param>
/// <returns></returns>
public static T AllDatesAreUTC<T>(this T obj)
{
if (obj == null)
{
return default(T);
}
IterateDateTimeProperties(obj);
return obj;
}
private static void IterateDateTimeProperties(object obj)
{
if (obj == null)
{
return;
}
var properties = obj.GetType().GetProperties();
//Set all DaetTimeKinds to Utc
foreach (var prop in properties)
{
var t = prop.PropertyType;
if (t == typeof(DateTime) || t == typeof(DateTime?))
{
SpecifyUtcKind(prop, obj);
}
else if (t.IsEnumerable())
{
var vals = prop.GetValue(obj, null);
if (vals != null)
{
foreach (object o in (IEnumerable)vals)
{
IterateDateTimeProperties(o);
}
}
}
else
{
var val = prop.GetValue(obj, null);
if (val != null)
{
IterateDateTimeProperties(val);
}
}
}
//properties.ForEach(property => SpecifyUtcKind(property, obj));
return; // obj;
}
private static void SpecifyUtcKind(PropertyInfo property, object value)
{
//Get the datetime value
var datetime = property.GetValue(value, null);
DateTime output;
//set DateTimeKind to Utc
if (property.PropertyType == typeof(DateTime))
{
output = DateTime.SpecifyKind((DateTime)datetime, DateTimeKind.Utc);
}
else if (property.PropertyType == typeof(DateTime?))
{
var nullable = (DateTime?)datetime;
if (!nullable.HasValue) return;
output = (DateTime)DateTime.SpecifyKind(nullable.Value, DateTimeKind.Utc);
}
else
{
return;
}
Debug.WriteLine(" ***** Converted date from {0} to {1}.", datetime, output);
datetime = output.ToLocalTime();
//And set the Utc DateTime value
property.SetValue(value, datetime, null);
}
internal static Type[] ConvertibleTypes = {typeof(bool), typeof(byte), typeof(char),
typeof(DateTime), typeof(decimal), typeof(double), typeof(float), typeof(int),
typeof(long), typeof(sbyte), typeof(short), typeof(string), typeof(uint),
typeof(ulong), typeof(ushort)};
/// <summary>
/// Returns true if this Type matches any of a set of Types.
/// </summary>
/// <param name="types">The Types to compare this Type to.</param>
public static bool In(this Type type, params Type[] types)
{
foreach (Type t in types) if (t.IsAssignableFrom(type)) return true; return false;
}
/// <summary>
/// Returns true if this Type is one of the types accepted by Convert.ToString()
/// (other than object).
/// </summary>
public static bool IsConvertible(this Type t) { return t.In(ConvertibleTypes); }
/// <summary>
/// Gets whether this type is enumerable.
/// </summary>
public static bool IsEnumerable(this Type t)
{
return typeof(IEnumerable).IsAssignableFrom(t);
}
/// <summary>
/// Returns true if this property's getter is public, has no arguments, and has no
/// generic type parameters.
/// </summary>
public static bool SimpleGetter(this PropertyInfo info)
{
MethodInfo method = info.GetGetMethod(false);
return method != null && method.GetParameters().Length == 0 &&
method.GetGenericArguments().Length == 0;
}
}
(某些代码来自其他SO职位)
要使用:从任何呼叫.AllDatesAreUTC()目的。它将走图并进行本地时间转换。
void svc_ZOut_GetZOutSummaryCompleted(object sender, ZOut_GetZOutSummaryCompletedEventArgs e)
{
svc.ZOut_GetZOutSummaryCompleted -= new EventHandler<ZOut_GetZOutSummaryCompletedEventArgs>(svc_ZOut_GetZOutSummaryCompleted);
svc = null;
var whenDone = (Action<bool, ZOutResult>)e.UserState;
if (e.Error != null)
{
FireOnExceptionRaised(e.Error);
whenDone(false, null);
}
else
{
var res = e.Result.AllDatesAreUTC();
FireOnSessionReceived(res.IsError, res.Session);
if (res.IsError == true)
{
whenDone(false, null);
}
else
{
whenDone(true, res.Result);
}
}
}
通过修改SpecifyUtcKind方法,您可以更改行为以标记UTC的时间,而无需更改时间本身。
编辑:我不建议在循环引用的对象图上使用这个,根据注释中的对话。
你如何确定obj没有更新? – 2011-03-09 22:34:05
@Stefan我可以在调试器中看到它。其属性值不会被修改。 – RunnerRick 2011-03-09 22:35:49
尝试改变值不只是种类,也许加起来看看它是否改变。改变种类不应改变价值。 – Aliostad 2011-03-09 22:38:02