将复杂对象中的所有DateTime字段从本地时区转换为UTC

时间:2012-10-01 05:58:15

标签: c# datetime utc

我有一个客户对象,其中包含有关客户的所有详细信息 出生日期,加入日期等。

我想将所有日期字段转换为通用日期时间并存储在数据库中。

有人可以帮助我从客户对象获取所有日期字段并将其转换为通用日期时间吗?

我想要一种解决方案,当我调用Customer.ChangeToUTC()时,客户中的所有日期时间字段都应更改为通用时间。

4 个答案:

答案 0 :(得分:1)

这很简单:

TimeZone ltz = TimeZone.CurrentTimeZone;

DateTime t1 = DateTime.Now;

DateTime t2 = ltz.ToUniversalTime(t1);

答案 1 :(得分:1)

  

任何人都可以帮助我如何从客户对象获取所有日期字段并将其转换为通用日期时间

手动完成。但是,我不会重复使用原始Customer类型的属性。我要么在之前创建对象(当你第一次获取数据时),要么作为轻量级DTO的一部分进行数据库传输。

当你知道如何解释任何特定属性时,关于日期/时间属性的推理是很难的 - 如果你不知道某个属性是普遍的,本地的还是未指定的那么它是会变得更难。

约会这样的事情甚至没有多大意义去考虑普遍与否。为了将它们存储在数据库中,您可能希望使用DateTimeKind.Utc显式创建它们,但从根本上说,日期是一个日期。 .NET框架的一个问题是日期没有单独的数据类型。

我有一个名为Noda Time的项目,它是.NET的替代日期/时间API。一种选择当然是使用它,但假设您想要坚持BCL类型,我仍然认为值得阅读我们的conceptstype choices文档,以帮助您考虑日期和时间以正确的方式。最好找出你 使用哪种类型的模型中的每个属性,然后记录它。您需要在代码中以不同方式处理它们。

答案 2 :(得分:0)

如果你熟悉日期时间,这很简单;

customer.BirthDate = customer.BirthDate.ToUniversalTime();

只需对所有日期字段执行上述操作,然后使用客户ID编号的where子句运行更新查询。

答案 3 :(得分:0)

我遇到过同样的问题。在我的情况下,解决方案是必要的,因为我们有太多具有def Convert(file, file1) handle_input=open('file', 'rU') handle_output=open('file1', 'w') while True: s=handle_input.readline() t=handle_output.write(s, '.genbank') print(t) Convert('file.fas', 'file.genbank') 字段的不同复杂模型。 根据我的需要,我写了下一个扩展名:

DateTime

你可以非常简单地使用它:

public static class ObjectExtensions
{
    /// <summary>
    /// Convert all DateTime fields in a complex object from UTC to a destination time zone.
    /// </summary>
    /// <typeparam name="TInput">Type of an object that will be converted.</typeparam>
    /// <param name="obj">Object that will be deeply converted.</param>
    /// <param name="destTimeZone"><c>TimeZoneInfo</c> object of a destination time zone.</param>
    public static void DeepConvertFromUtc<TInput>(this TInput obj, TimeZoneInfo destTimeZone)
        where TInput : class
    {
        obj.DeepConvert(TimeZoneInfo.Utc, destTimeZone);
    }

    /// <summary>
    /// Convert all DateTime fields in a complex object from source time zone to UTC.
    /// </summary>
    /// <typeparam name="TInput">Type of an object that will be converted.</typeparam>
    /// <param name="obj">Object that will be deeply converted.</param>
    /// <param name="sourceTimeZone"><c>TimeZoneInfo</c> object of a source time zone.</param>
    public static void DeepConvertToUtc<TInput>(this TInput obj, TimeZoneInfo sourceTimeZone)
        where TInput : class
    {
        obj.DeepConvert(sourceTimeZone, TimeZoneInfo.Utc);
    }

    /// <summary>
    /// Convert all DateTime fields in a complex object from UTC to a destination time zone.
    /// </summary>
    /// <typeparam name="TInput">Type of an object that will be converted.</typeparam>
    /// <param name="obj">Object that will be deeply converted.</param>
    /// <param name="sourceTimeZone"><c>TimeZoneInfo</c> object of a source time zone.</param>
    /// <param name="destTimeZone"><c>TimeZoneInfo</c> object of a destination time zone.</param>
    public static void DeepConvertTime<TInput>(this TInput obj, TimeZoneInfo sourceTimeZone, TimeZoneInfo destTimeZone)
        where TInput : class
    {
        obj.DeepConvert(sourceTimeZone, destTimeZone);
    }

    private static void DeepConvert<TInput>(this TInput obj, TimeZoneInfo sourceTimeZone, TimeZoneInfo destTimeZone)
        where TInput : class
    {
        if (obj == null)
        {
            return;
        }

        var items = obj as ICollection;
        if (items != null)
        {
            foreach (var item in items)
            {
                item.DeepConvert(sourceTimeZone, destTimeZone);
            }

            return;
        }

        var props = obj.GetType().GetProperties();
        foreach (var prop in props.Where(prop => !IsIgnore(prop)))
        {
            if (prop.PropertyType == typeof(DateTime) || prop.PropertyType == typeof(DateTime?))
            {
                prop.ConvertDateTime(obj, sourceTimeZone, destTimeZone);
                continue;
            }

            var value = prop.GetValue(obj);
            var list = value as ICollection;
            if (list != null)
            {
                foreach (var item in list)
                {
                    item.DeepConvert(sourceTimeZone, destTimeZone);
                }

                continue;
            }

            // here I check that an object is located in one of my assemblies
            if (prop.PropertyType.Assembly.FullName.StartsWith("Should be your namespace"))
            {
                value.DeepConvert(sourceTimeZone, destTimeZone);
            }
        }
    }

    private static void ConvertDateTime<TInput>(this PropertyInfo prop, TInput obj, TimeZoneInfo sourceTimeZone, TimeZoneInfo destTimeZone)
        where TInput : class
    {
        var value = prop.GetValue(obj);
        if (value != null)
        {
            var dateTime = DateTime.SpecifyKind((DateTime)value, DateTimeKind.Unspecified);
            value = TimeZoneInfo.ConvertTime(dateTime, sourceTimeZone, destTimeZone);

            var setMethod = prop.SetMethod;
            if (setMethod != null)
            {
                setMethod.Invoke(obj, new[] { value });
            }
        }
    }

    private static bool IsIgnore(this PropertyInfo prop)
    {
        var attr = prop.GetCustomAttribute<IgnoreUtcConversionAttribute>();
        return attr != null;
    }
}

public class IgnoreUtcConversionAttribute : Attribute
{
}

您也可以从yourComplexObject.DeepConvertToUtc(TimeZoneInfo.Local); // a collection could be converted as well collection.DeepConvertToUtc(TimeZoneInfo.Local); 方法获取TimeZineInfo对象:

FindSystemTimeZoneById

如果您的模型中有双向引用,则必须使用var timeZoneInfo = TimeZoneInfo.FindSystemTimeZoneById("Belarus Standard Time"); yourComplexObject.DeepConvertToUtc(timeZoneInfo); 修饰一个引用:

[IgnoreUtcConversion]