4

努力获取任何时区的日期时间。我正在使用 DateTimeOffset、一个字符串和一个 XmlElement 属性。当我这样做时,我收到以下错误:

[InvalidOperationException:'dateTime' 是 XmlElementAttribute.DataType 属性的无效值。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

[InvalidOperationException:反映类型“System.String”时出现错误。]
System.Xml.Serialization.XmlReflectionImporter.ImportTypeMapping(TypeModel 模型,字符串 ns,ImportContext 上下文,字符串数据类型,XmlAttributes a,布尔重复,布尔 openModel,RecursionLimiter 限制器) +1621
System.Xml.Serialization.XmlReflectionImporter.ImportAccessorMapping(MemberMapping 访问器,FieldModel 模型,XmlAttributes a,String ns,Type choiceIdentifierType,Boolean rpc,Boolean openModel,RecursionLimiter 限制器)+8750
System.Xml.Serialization.XmlReflectionImporter.ImportFieldMapping(StructModel parent , FieldModel 模型, XmlAttributes a, String ns, RecursionLimiter 限制器) +139
System.Xml.Serialization.XmlReflectionImporter.InitializeStructMembers(StructMapping 映射,StructModel 模型,Boolean 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;
    }
}
4

6 回答 6

3

这对我有用

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); }
}
于 2012-02-21T15:09:10.733 回答
2

看看这个关于序列化日期和 UTC 的 StackOverflow 问题:

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

不需要创建一个特殊的属性来完成序列化。

于 2008-11-21T01:20:46.177 回答
1

我建议您将 DateTime 序列化为 long (这是实现在内部用于存储实际值的内容)。

您可以使用DateTime.Ticks它来获取该值,它有一个构造函数,该构造函数需要很长时间(Int64)。

于 2008-11-21T20:54:46.730 回答
1

使用 XmlConvert.ToDateTimeOffset() 和 .ToString() 方法在 XmlSerializer 变通方法属性中正确序列化和反序列化 DateTimeOffset。

此处的 Microsoft Connect 文章中的完整示例,并确认不幸的是 Microsoft 不会修复此疏忽(XmlSerializer 应该本机支持它作为任何原始类型):

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

于 2014-04-10T11:07:40.600 回答
0

属性的数据类型creationTimeX是字符串,而 XmlSerialization 数据类型是DateTime。这就是为什么你得到那个例外。

您可以通过将数据类型更改为DateTime.

此外,对于任何时区的当前时间问题,您必须对其应用DateTime.Now.ToUniveralTime()并应用适当的 DateTimeFormat 模式。

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

于 2008-11-21T00:53:20.540 回答
0

UDateTime这是 2019 年,我从这个gist中找到了一个很棒的自定义类型和属性抽屉的单一脚本

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
于 2019-02-13T21:28:41.810 回答