不要序列化或从序列化的DateTime对象中删除TimeZone [英] Don't Serialize, or Remove, TimeZone from Serialized DateTime objects

查看:89
本文介绍了不要序列化或从序列化的DateTime对象中删除TimeZone的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我得到的奇怪任务是使用XML序列化序列化LARGE对象。该对象包含多个嵌套的UserDefined类以及多个DateTime字段。 DateTime数据的要求是,它必须始终显示在最初创建和设置数据的用户的时区中。因此,我无法使用UTC或本地时间,因为在反序列化时,它们与以前的时间不同。我也无法以UTC显示值,它们必须以本地时间显示。我需要的是一种奇怪的序列化格式,它表示绝对本地时间的概念...那就是没有TimeZone的本地时间。

The odd task that I have been given is to serialize a LARGE object using XML Serialization. This object contains multiple Nested UserDefined classes, with multiple DateTime fields. The Requirement for the DateTime data is that it must ALWAYS be displayed in the TimeZone of the user who initially created and set the data. Thus, I Cannot use UTC OR Local times because when de-serialized, they wouldn't be the same as they were. I also cannot display the values in UTC, they must be displayed in Local Time. What I need is some odd serialization format that represents the concept of "Absolute Local Time"...that would be "Local Time without TimeZone".

我可以剥离使用正则表达式从日期字符串中进行TZ,这很容易。但是我要处理的对象的绝对大小意味着我经常会收到OutOfMemoryException。我看到它运行一次无需调试,并且在操作期间我的使用内存从100k猛增到800k。不是很好。

I can strip the TZ from the date string using Regex, that's easy. but the sheer size of the object I'm dealing with means that more often than not I get an OutOfMemoryException. I watched it run without debug once and my used memory spiked from 100k to 800k during the operation. Not nice. And that was one of the smaller files.

Doc.DocumentElement.InnerXML = Regex.Replace(Doc.DocumentElement.InnerXML, "(\\d{4}-\\d{2}-\\d{2}T\\d{2}:\\d{2}:\\d{2})(\\+|-)(\\d{2}:\\d{2})", "$1")

到目前为止,我唯一看到的选择是创建所有dateTime字段的重复项,将DT字段本身设置为 XmlIgnore(),然后然后在重新加载文档后手动从序列化的字符串数据中恢复所有日期。这也是不切实际的。
请参见自定义DateTime XML序列化

So far, the only option I have seen is to create duplicates of ALL the dateTime fields, set the DT fields themselves as "XmlIgnore()", and then manually restore all the dates from the serialized string data after the doc is re-loaded. This is also not practical. See Custom DateTime XML Serialization

是否有任何方法可以强制序列化引擎在没有其TimeZone数据的情况下序列化DateTime对象?最好不要将某个泛型对象单独应用于对象中的每个DT属性?

Is there any way to force the serialization engine to serialize DateTime objects without their TimeZone data? Preferably something generic that doesn't have to be individually applied to every DT property in the object?

!! EDIT !!

!!EDIT!!

我可能找到了部分解决方案。这至少可能有助于前进。 DateTimeKind.Unspecified,在序列化后似乎没有附加任何TimeZone数据。这是我正在寻找的解决方案。强制使用DateTime.SpecifyKind强制转换我的所有DateTime数据?

I may have found a partial solution. It might at least help moving forward. DateTimeKind.Unspecified, when serialized, doesn't seem to have any TimeZone data attached to it. Is this the solution I'm looking for. Forcefully cast all my DateTime data using DateTime.SpecifyKind?

public DateTime? StartDate
    {
        get 
        { return _StartDate; }
        set
        {
            if (_StartDate == value)
                return;

            if (value != null)
                _StartDate = DateTime.SpecifyKind(value.Value, DateTimeKind.Unspecified);
            else
                _StartDate = value;

            OnPropertyChanged("StartDate");
        }
    }


推荐答案

已找到一个答案。

private static readonly Regex DTCheck = new Regex(@"(\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2})([\+|-]\d{2}:\d{2})");

    /// <summary>
    /// Removes any instances of the TimeZoneOffset from the RigX after it has been serialized into an XMLString ++ Called from the "Save" process
    /// </summary>
    /// <param name="rigx"></param>
    /// <returns>StringReader referencing the re-formatted XML String</returns>
    private static StringReader RemoveTZOffsetFromRigX(RigX rigx)
    {
        StringBuilder sb = new StringBuilder();
        StringWriter sw = new StringWriter(sb);
        XmlSerializer ser = new XmlSerializer(typeof(RigX));

        ser.Serialize(sw, rigx);

        string xmlText = sb.ToString();

        if (DTCheck.IsMatch(xmlText))
            xmlText = DTCheck.Replace(xmlText, "$1");

        StringReader Sreader = new StringReader(xmlText);

        return Sreader;
    }

    /// <summary>
    /// Removes the TimeZone offset from a RigX as referenced by stream.  Returns a reader linked to the new stream  ++ Called from the "Load" process
    /// </summary>
    /// <param name="stream">stream containing the initial RigX XML String</param>
    /// <returns>StringReader referencing the re-formatted XML String</returns>
    private StringReader RemoveTZOffsetFromXML(MemoryStream stream)
    {
        stream.Position = 0;
        StreamReader reader = new StreamReader(stream, Encoding.UTF8);

        string xmlText = reader.ReadToEnd();
        reader.Close();
        stream.Close();

        if (DTCheck.IsMatch(xmlText))
            xmlText = DTCheck.Replace(xmlText, "$1");

        StringReader Sreader = new StringReader(xmlText);

        return Sreader;
    }

从文件中读取XML之后,并在通过序列化程序运行之前,对裸XML文本运行Regex以删除偏移量。该函数返回针对修改后的XML字符串运行的字符串读取器,然后可以通过反序列化将其运行到对象中。

After reading in the XML From the file, and before running it through the serializer, run the Regex on the bare XML Text to remove the offset. The function returns a string reader running against the modified XML string, which can then be run through a de-serialization into the object.

而不是使用序列化程序来保存xml直接输出到输出流中,可以使用stringBuilder截获序列化的xml。然后,使用与加载过程相同的过程,通过RegularExpression删除TimeZone偏移,然后返回一个链接到修改后的文本的StringReader,然后将其用于将数据写回到文件中。

Rather than using the serializer to save the xml directly to the output stream, you can use a stringBuilder to intercept the serialized xml. Then using the same process as during the loading procedure, you remove the TimeZone offset via RegularExpression, then return a StringReader linked to the modified text, which is then used to write the data back out into a file.

有点麻木的感觉,但是很有效。不过,这会占用大量内存,因此请避免直接调试函数,或者如果有必要,请不要尝试不对字符串求值,这是我上次尝试将其完全破坏VS实例。

Slightly hackish feeling, but effective. Very memory intensive though, avoid debugging the functions directly if you can, or if you have to, try not to evaluate the strings, last time I tried that it crashed my VS instance completely.

这篇关于不要序列化或从序列化的DateTime对象中删除TimeZone的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆