简体   繁体   English

如何序列化到日期时间

[英]How to serialize to dateTime

Working to get DateTimes for any time zone.努力获取任何时区的日期时间。 I'm using DateTimeOffset, and a string, and an XmlElement attribute.我正在使用 DateTimeOffset、一个字符串和一个 XmlElement 属性。 When I do, I get the following error:当我这样做时,我收到以下错误:

[InvalidOperationException: 'dateTime' is an invalid value for the XmlElementAttribute.DataType property. [InvalidOperationException: 'dateTime' 是 XmlElementAttribute.DataType 属性的无效值。 dateTime cannot be converted to System.String.] dateTime 不能转换为 System.String。]
System.Xml.Serialization.XmlReflectionImporter.ImportTypeMapping(TypeModel model, String ns, ImportContext context, String dataType, XmlAttributes a, Boolean repeats, Boolean openModel, RecursionLimiter limiter) +450 System.Xml.Serialization.XmlReflectionImporter.ImportTypeMapping(TypeModel 模型,字符串 ns,ImportContext 上下文,字符串数据类型,XmlAttributes a,布尔重复,布尔 openModel,RecursionLimiter 限制器)+450

[InvalidOperationException: There was an error reflecting type 'System.String'.] [InvalidOperationException: 有一个错误反映类型“System.String”。]
System.Xml.Serialization.XmlReflectionImporter.ImportTypeMapping(TypeModel model, String ns, ImportContext context, String dataType, XmlAttributes a, Boolean repeats, Boolean openModel, RecursionLimiter limiter) +1621 System.Xml.Serialization.XmlReflectionImporter.ImportTypeMapping(TypeModel 模型,字符串 ns,ImportContext 上下文,字符串数据类型,XmlAttributes a,布尔重复,布尔 openModel,RecursionLimiter 限制器)+1621
System.Xml.Serialization.XmlReflectionImporter.ImportAccessorMapping(MemberMapping accessor, FieldModel model, XmlAttributes a, String ns, Type choiceIdentifierType, Boolean rpc, Boolean openModel, RecursionLimiter limiter) +8750 System.Xml.Serialization.XmlReflectionImporter.ImportAccessorMapping(MemberMapping accessor, FieldModel model, XmlAttributes a, String ns, Type choiceIdentifierType, Boolean rpc, Boolean openModel, RecursionLimiter limiter) +8750
System.Xml.Serialization.XmlReflectionImporter.ImportFieldMapping(StructModel parent, FieldModel model, XmlAttributes a, String ns, RecursionLimiter limiter) +139 System.Xml.Serialization.XmlReflectionImporter.ImportFieldMapping(StructModel parent, FieldModel model, XmlAttributes a, String ns, RecursionLimiter limiter) +139
System.Xml.Serialization.XmlReflectionImporter.InitializeStructMembers(StructMapping mapping, StructModel model, Boolean openModel, String typeName, RecursionLimiter limiter) +1273 System.Xml.Serialization.XmlReflectionImporter.InitializeStructMembers(StructMapping 映射,StructModel 模型,布尔型 openModel,String typeName,RecursionLimiter 限制器)+1273

[InvalidOperationException: There was an error reflecting property 'creationTimeX'.] ... [InvalidOperationException:反映属性“creationTimeX”时出现错误。] ...

Code:代码:

 [System.Xml.Serialization.XmlElement(ElementName = "creationTime",
      DataType="dateTime")]
 public string creationTimeX
    {
        get
        {
            return this.creationTimeField.ToString("yyyy-MM-ddTHH:mm:sszzz");
        }
        set
        {
            DateTimeOffset.TryParse(value, out this.creationTimeField);
        }
    }

[System.Xml.Serialization.XmlIgnoreAttribute()]
public System.DateTimeOffset creationTime
{
    get {
        return this.creationTimeField;
    }
    set {
        this.creationTimeField = value;
    }
}

This is what worked for me这对我有用

private const string DateTimeOffsetFormatString = "yyyy-MM-ddTHH:mm:sszzz";
private DateTimeOffset eventTimeField;

[System.Xml.Serialization.XmlElementAttribute(Form = System.Xml.Schema.XmlSchemaForm.Unqualified, Order = 0)]
public string eventTime
{
    get { return eventTimeField.ToString(DateTimeOffsetFormatString); }
    set { eventTimeField = DateTimeOffset.Parse(value); }
}

Take a look at this StackOverflow question about serializing dates and UTC:看看这个关于序列化日期和 UTC 的 StackOverflow 问题:

Best practices for DateTime serialization in .Net framework 3.5/SQL Server 2008 .Net framework 3.5/SQL Server 2008 中 DateTime 序列化的最佳实践

No need to create a special property just to accomplish the serialization.无需创建特殊属性来完成序列化。

Use the XmlConvert.ToDateTimeOffset() and .ToString() methods to correctly serialize and de-serialize a DateTimeOffset in an XmlSerializer workaround property.使用 XmlConvert.ToDateTimeOffset() 和 .ToString() 方法正确序列化和反序列化 XmlSerializer 变通方法属性中的 DateTimeOffset。

Full sample in the Microsoft Connect article here, and confirmation that unfortunately Microsoft won't fix this oversight (it should have been supported natively by XmlSerializer as any primitive type):此处 Microsoft Connect 文章中的完整示例,并确认不幸的是 Microsoft 不会修复此疏忽(XmlSerializer 作为任何原始类型本应支持它):

https://connect.microsoft.com/VisualStudio/feedback/details/288349/datetimeoffset-is-not-serialized-by-a-xmlserializer https://connect.microsoft.com/VisualStudio/feedback/details/288349/datetimeoffset-is-not-serialized-by-a-xmlserializer

I would suggest you serialize DateTime as a long (which is what the implementation uses internally to store the actual value).我建议您将 DateTime 序列化为 long(这是实现在内部用于存储实际值的内容)。

You can use DateTime.Ticks to get the value and it has a constructor that takes a long ( Int64 ).您可以使用DateTime.Ticks来获取值,它有一个需要很长时间的构造函数( Int64 )。

The datatype of the property creationTimeX is string while the XmlSerialization datatype is DateTime .属性creationTimeX的数据类型是字符串,而 XmlSerialization 数据类型是DateTime That's why you are getting that exception.这就是为什么你会得到那个例外。

You can fix this by changing the datatype to DateTime .您可以通过将数据类型更改为DateTime来解决此问题。

Also for your issue of the current time for any timezone, you would have to apply a DateTime.Now.ToUniveralTime() and apply appropriate DateTimeFormat pattern on it.此外,对于任何时区的当前时间问题,您必须应用DateTime.Now.ToUniveralTime()并在其上应用适当的 DateTimeFormat 模式。

http://msdn.microsoft.com/en-us/library/k494fzbf.aspx http://msdn.microsoft.com/en-us/library/k494fzbf.aspx

This is 2019, and I found a great single script for a custom type & property drawer UDateTime from this gist这是 2019 年,我从这个要点中找到了一个很棒的自定义类型和属性抽屉UDateTime脚本

using System;
#if UNITY_EDITOR
using UnityEditor;
#endif
using UnityEngine;

// we have to use UDateTime instead of DateTime on our classes
// we still typically need to either cast this to a DateTime or read the DateTime field directly
[System.Serializable]
public class UDateTime : ISerializationCallbackReceiver {
    [HideInInspector] public DateTime dateTime;

    // if you don't want to use the PropertyDrawer then remove HideInInspector here
    [HideInInspector] [SerializeField] private string _dateTime;

    public static implicit operator DateTime(UDateTime udt) {
        return (udt.dateTime);
    }

    public static implicit operator UDateTime(DateTime dt) {
        return new UDateTime() {dateTime = dt};
    }

    public void OnAfterDeserialize() {
        DateTime.TryParse(_dateTime, out dateTime);
    }

    public void OnBeforeSerialize() {
        _dateTime = dateTime.ToString();
    }
}

// if we implement this PropertyDrawer then we keep the label next to the text field
#if UNITY_EDITOR
[CustomPropertyDrawer(typeof(UDateTime))]
public class UDateTimeDrawer : PropertyDrawer {
    // Draw the property inside the given rect
    public override void OnGUI(Rect position, SerializedProperty property, GUIContent label) {
        // Using BeginProperty / EndProperty on the parent property means that
        // prefab override logic works on the entire property.
        EditorGUI.BeginProperty(position, label, property);

        // Draw label
        position = EditorGUI.PrefixLabel(position, GUIUtility.GetControlID(FocusType.Passive), label);

        // Don't make child fields be indented
        var indent = EditorGUI.indentLevel;
        EditorGUI.indentLevel = 0;

        // Calculate rects
        Rect amountRect = new Rect(position.x, position.y, position.width, position.height);

        // Draw fields - passs GUIContent.none to each so they are drawn without labels
        EditorGUI.PropertyField(amountRect, property.FindPropertyRelative("_dateTime"), GUIContent.none);

        // Set indent back to what it was
        EditorGUI.indentLevel = indent;

        EditorGUI.EndProperty();
    }
}
#endif

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM