簡體   English   中英

如何序列化到日期時間

[英]How to serialize to dateTime

努力獲取任何時區的日期時間。 我正在使用 DateTimeOffset、一個字符串和一個 XmlElement 屬性。 當我這樣做時,我收到以下錯誤:

[InvalidOperationException: 'dateTime' 是 XmlElementAttribute.DataType 屬性的無效值。 dateTime 不能轉換為 System.String。]
System.Xml.Serialization.XmlReflectionImporter.ImportTypeMapping(TypeModel 模型,字符串 ns,ImportContext 上下文,字符串數據類型,XmlAttributes a,布爾重復,布爾 openModel,RecursionLimiter 限制器)+450

[InvalidOperationException: 有一個錯誤反映類型“System.String”。]
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.ImportFieldMapping(StructModel parent, FieldModel model, XmlAttributes a, String ns, RecursionLimiter limiter) +139
System.Xml.Serialization.XmlReflectionImporter.InitializeStructMembers(StructMapping 映射,StructModel 模型,布爾型 openModel,String typeName,RecursionLimiter 限制器)+1273

[InvalidOperationException:反映屬性“creationTimeX”時出現錯誤。] ...

代碼:

 [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;
    }
}

這對我有用

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); }
}

看看這個關於序列化日期和 UTC 的 StackOverflow 問題:

.Net framework 3.5/SQL Server 2008 中 DateTime 序列化的最佳實踐

無需創建特殊屬性來完成序列化。

使用 XmlConvert.ToDateTimeOffset() 和 .ToString() 方法正確序列化和反序列化 XmlSerializer 變通方法屬性中的 DateTimeOffset。

此處 Microsoft Connect 文章中的完整示例,並確認不幸的是 Microsoft 不會修復此疏忽(XmlSerializer 作為任何原始類型本應支持它):

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

我建議您將 DateTime 序列化為 long(這是實現在內部用於存儲實際值的內容)。

您可以使用DateTime.Ticks來獲取值,它有一個需要很長時間的構造函數( Int64 )。

屬性creationTimeX的數據類型是字符串,而 XmlSerialization 數據類型是DateTime 這就是為什么你會得到那個例外。

您可以通過將數據類型更改為DateTime來解決此問題。

此外,對於任何時區的當前時間問題,您必須應用DateTime.Now.ToUniveralTime()並在其上應用適當的 DateTimeFormat 模式。

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

這是 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