C# 如何序列化到dateTime

C# 如何序列化到dateTime,c#,datetime,.net-2.0,xml-serialization,C#,Datetime,.net 2.0,Xml Serialization,努力获取任何时区的日期时间。 我使用的是DateTimeOffset、一个字符串和一个XmlElement属性。当我这样做时,我会得到以下错误: [InvalidOperationException:'dateTime' 是的无效值 XmlElementAttribute.DataType属性。 无法将日期时间转换为 System.String.] System.Xml.Serialization.XmlReflectionImporter.ImportTypeMapping(类型模型 模型,字

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

[InvalidOperationException:'dateTime' 是的无效值 XmlElementAttribute.DataType属性。 无法将日期时间转换为 System.String.]
System.Xml.Serialization.XmlReflectionImporter.ImportTypeMapping(类型模型 模型,字符串ns,导入上下文 上下文,字符串数据类型, XMLA属性,布尔值重复, 布尔openModel,递归限制器 限制器)+450

[无效操作例外:有 错误反射类型 “System.String”。]
System.Xml.Serialization.XmlReflectionImporter.ImportTypeMapping(类型模型 模型,字符串ns,导入上下文 上下文,字符串数据类型, XMLA属性,布尔值重复, 布尔openModel,递归限制器 限制器)+1621
System.Xml.Serialization.XmlReflectionImporter.ImportAccessorMapping(MemberMapping 存取器,现场模型, XMLA属性,字符串ns,类型 choiceIdentifierType,布尔rpc, 布尔openModel,递归限制器 限制器)+8750
System.Xml.Serialization.XmlReflectionImporter.ImportFieldMapping(StructModel 父项,字段模型, xmla属性,字符串ns, 递归限制器)+139
System.Xml.Serialization.XmlReflectionImporter.InitializeStructMembers(StructMapping 映射,结构模型,布尔 openModel,字符串类型名, 递归限制器)+1273

[无效操作例外:有 反映错误的属性 “creationTimeX.”

代码:


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

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

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


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


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

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


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

这就是我的工作原理

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

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

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


现在是2019年,我从中找到了一个用于自定义类型和属性抽屉的优秀脚本
UDateTime

使用系统;
#如果统一编辑器
使用UnityEditor;
#恩迪夫
使用UnityEngine;
//我们必须在课堂上使用UDateTime而不是DateTime
//我们通常仍然需要将其转换为DateTime或直接读取DateTime字段
[系统可序列化]
公共类UDateTime:ISerializationCallbackReceiver{
[HideInInstitt]公共日期时间日期时间;
//如果不想使用PropertyDrawer,请在此处删除HideInSect
[HideInInstitt][SerializeField]私有字符串\u日期时间;
公共静态隐式运算符DateTime(UDateTime udt){
返回(自定义日期时间);
}
公共静态隐式运算符UDateTime(DateTime dt){
返回新的UDateTime(){dateTime=dt};
}
反序列化()后的公共无效{
DateTime.TryParse(_DateTime,out DateTime);
}
public void OnBeforeSerialize(){
_dateTime=dateTime.ToString();
}
}
//如果我们实现这个PropertyDrawer,那么我们会将标签保留在文本字段旁边
#如果统一编辑器
[CustomPropertyDrawer(typeof(UDateTime))]
公共类UDateTimeDrawer:PropertyDrawer{
//在给定的矩形内绘制属性
public override void OnGUI(Rect位置、SerializedProperty属性、GUIContent标签){
//在父属性上使用BeginProperty/EndProperty意味着
//预设覆盖逻辑对整个属性有效。
EditorGUI.BeginProperty(位置、标签、属性);
//绘图标签
position=EditorGUI.PrefixLabel(position,GUIUtility.GetControlID(FocusType.Passive),label);
//不要使子字段缩进
var indent=EditorGUI.indentLevel;
EditorGUI.indentLevel=0;
//计算矩形
Rect AMOUNTECT=新的Rect(位置x、位置y、位置宽度、位置高度);
//绘制字段-将GUIContent.none传递给每个字段,因此绘制字段时不带标签
EditorGUI.PropertyField(amount、property.FindPropertyRelative(“\u dateTime”),GUIContent.none);
//将缩进设置回原样
EditorGUI.indentLevel=缩进;
EditorGUI.EndProperty();
}
}
#恩迪夫

不是我需要的。我想覆盖标准日期时间,这样我们就可以指定任何时间僵尸。。。。例如DateTimeOffset。为字符串指定数据类型适用于正整数、非正整数等。。。但对datetime不起作用谢谢评论说明了一切。。即使时间允许任何事情。。。如果您绝对肯定地必须知道时区本身(即,上面可能是东部标准时间或中部夏时制),则需要创建自己的数据类型,以公开这些数据段。实现iXmlSerializerUTC是旧方法(确保序列化),但没有回答序列化DateTimeOffset(与时区相关)的问题。阅读MSDN关于此主题的文章,Microsoft当前的建议是DateTimeOffset for
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); }
}