C# 如何序列化到日期时间

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/307433/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-03 22:31:55  来源:igfitidea点击:

How to serialize to dateTime

c#datetime.net-2.0xml-serialization

提问by david valentine

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:

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

[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'.] ...

[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 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 限制器) +8750
System.Xml.Serialization.XmlReflectionStruclportModelMapping(MemberMapping accessor) , FieldModel 模型, XmlAttributes a, String ns, RecursionLimiter 限制器) +139
System.Xml.Serialization.XmlReflectionImporter.InitializeStructMembers(StructMapping 映射,StructModel 模型,Boolean openModel,String typeName,RecursionLimiter 限制器)+1273

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

采纳答案by Jason Hymanson

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.

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

回答by user35559

David

大卫

The datatype of the property(creationTimeX) is string while the XmlSerialization datatype is "dateTime". Thats why you are getting that exception.

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

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 模式。

The steps for these are here

这些步骤在这里

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

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

Thanks -RVZ

谢谢-RVZ

回答by Asher

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.Ticksto get the value and it has a constructor that takes a long (Int64).

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

回答by jhilden

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

回答by Tony Wall

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

回答by nipunasudha

This is 2019, and I found a great single script for a custom type & property drawer UDateTimefrom 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