如何序列化为日期时间

发布于 2024-07-09 02:43:32 字数 1974 浏览 4 评论 0原文

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

[InvalidOperationException:'日期时间' 是一个无效值 XmlElementAttribute.DataType 属性。 日期时间无法转换为 系统.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 访问器、FieldModel 模型、 XmlAttributes a、字符串 ns、类型 选择标识符类型,布尔 rpc, 布尔 openModel、RecursionLimiter 限制器)+8750
System.Xml.Serialization.XmlReflectionImporter.ImportFieldMapping(StructModel 父级,FieldModel 模型, XmlAttributes a,字符串 ns, RecursionLimiter 限制器)+139
System.Xml.Serialization.XmlReflectionImporter.InitializeStructMembers(StructMapping 映射、StructModel 模型、布尔 openModel,字符串类型名称, 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;
    }
}

Working to get DateTimes for any time zone.
I'm using DateTimeOffset, and a string, and an XmlElement attribute. When I do, I get the following error:

[InvalidOperationException: 'dateTime'
is an invalid value for the
XmlElementAttribute.DataType property.
dateTime cannot be converted to
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: There was
an error reflecting type
'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.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
mapping, StructModel model, Boolean
openModel, String typeName,
RecursionLimiter limiter) +1273

[InvalidOperationException: There was
an error reflecting property
'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;
    }
}

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(6

愁杀 2024-07-16 02:43:32

这对我有用

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

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); }
}
一片旧的回忆 2024-07-16 02:43:32

看一下有关序列化日期和 UTC 的 StackOverflow 问题:

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

无需创建特殊属性来完成序列化。

Take a look at this StackOverflow question about serializing dates and UTC:

Best practices for DateTime serialization in .Net framework 3.5/SQL Server 2008

No need to create a special property just to accomplish the serialization.

把时间冻结 2024-07-16 02:43:32

使用 XmlConvert.ToDateTimeOffset() 和 .ToString() 方法正确序列化和反序列化 XmlSerializer 解决方法属性中的 DateTimeOffset。

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

https://connect.microsoft.com/VisualStudio/feedback/details/288349/datetimeoffset-is-未由 xmlserializer 序列化

Use the XmlConvert.ToDateTimeOffset() and .ToString() methods to correctly serialize and de-serialize a DateTimeOffset in an XmlSerializer workaround property.

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):

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

笑红尘 2024-07-16 02:43:32

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

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

I would suggest you serialize DateTime as a long (which is what the implementation uses internally to store the actual value).

You can use DateTime.Ticks to get the value and it has a constructor that takes a long (Int64).

丘比特射中我 2024-07-16 02:43:32

这是 2019 年,我发现了一个很棒的自定义类型和自定义脚本。 属性抽屉 UDateTime 来自此 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

This is 2019, and I found a great single script for a custom type & property drawer UDateTime from this 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
寂寞清仓 2024-07-16 02:43:32

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

您可以通过将数据类型更改为 DateTime 来解决此问题。

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

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

The datatype of the property creationTimeX is string while the XmlSerialization datatype is DateTime. That's why you are getting that exception.

You can fix this by changing the datatype to 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.

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

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文