努力获取任何时区的DateTimes。 我正在使用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 openModel,RecursionLimiter 限制器)+450[InvalidOperationException:有 反映类型的错误 'System.String'。]
System.Xml.Serialization.XmlReflectionImporter.ImportTypeMapping(TypeModel model,String ns,ImportContext context,String dataType, XmlAttributes a,布尔重复, Boolean 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模型,布尔值 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;
}
}
答案 0 :(得分: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); }
}
答案 1 :(得分:2)
请看一下有关序列化日期和UTC的StackOverflow问题:
Best practices for DateTime serialization in .Net framework 3.5/SQL Server 2008
无需仅为完成序列化而创建特殊属性。
答案 2 :(得分:1)
我建议您将DateTime序列化为long(这是实现在内部用于存储实际值的内容)。
您可以使用DateTime.Ticks
获取值,并且它有一个需要很长时间(Int64
)的构造函数。
答案 3 :(得分:1)
使用XmlConvert.ToDateTimeOffset()和.ToString()方法在XmlSerializer变通方法属性中正确序列化和反序列化DateTimeOffset。
此处的Microsoft Connect文章中的完整示例,以及不幸的是Microsoft不会修复此疏忽的确认(它本应由XmlSerializer本身支持为任何原始类型):
答案 4 :(得分:0)
大卫
属性的数据类型(creationTimeX)是字符串,而XmlSerialization数据类型是“dateTime”。这就是为什么你得到这个例外。
您可以通过将数据类型更改为DateTime
来解决此问题另外,对于您发布任何时区的当前时间,您必须申请 DateTime.Now.ToUniveralTime并在其上应用适当的DateTimeFormat模式。
这些步骤在这里
http://msdn.microsoft.com/en-us/library/k494fzbf.aspx
由于 -RVZ
答案 5 :(得分:0)
这是2019年,我从此gist中找到了一个很棒的脚本,用于自定义类型和属性抽屉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