为什么 DotNet XmlReadMode.InferTypedSchema 将 DateTimeOffset 视为 DateTime?
Why does DotNet XmlReadMode.InferTypedSchema treat DateTimeOffset as a DateTime?
我有一个 XML 元素,其值 2099-12-31T23:59:58.576+13:00
来自 DateTimeOffset。
当我 运行 myDS.ReadXml(myStream, XmlReadMode.InferTypedSchema)
我得到 Specified cast is not valid.Couldn't store <2019-12-31 23:59:58> in MyColDTO Column. Expected type is DateTimeOffset.
附加的偏移量应明确指示 DateTimeOffset 而不是 DateTime。
为什么DotNet (FW 4.6.2) 识别不正确?
有简单的修复方法吗?
====自包含vb.net单元测试===
<TestMethod()> Public Sub THC2398_ReadXml_Bug()
Dim ds1 As DataSet, ds2 As DataSet, dt1 As DataTable, dt2 As DataTable, dr As DataRow, dtoAt As DateTimeOffset = DateTimeOffset.Parse("2019-12-31T23:59:58.576+13:00")
Assert.AreEqual("v4.0.30319", GetType(String).Assembly.ImageRuntimeVersion, "Version check")
Assert.AreEqual("mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089", GetType(String).Assembly.FullName, "Version check")
ds1 = New DataSet("ds")
dt1 = New DataTable("dt")
ds1.Tables.Add(dt1)
dt1.Columns.Add(New DataColumn("MyColDTO", GetType(DateTimeOffset)))
dr = dt1.NewRow
dr("MyColDTO") = dtoAt
dt1.Rows.Add(dr)
Assert.AreEqual(1, dt1.Rows.Count)
Assert.AreEqual("DateTimeOffset", dt1.Rows(0)(0).GetType.Name)
Dim tw As IO.TextWriter = New StringWriter, tr As TextReader
dt1.WriteXml(tw, XmlWriteMode.IgnoreSchema)
System.Console.WriteLine(tw.ToString)
tr = New StringReader(tw.ToString)
ds2 = New DataSet("ds")
ds2.ReadXml(tr, XmlReadMode.InferTypedSchema)
dt2 = ds2.Tables("dt")
Assert.AreEqual(1, dt2.Rows.Count)
'Assert.AreEqual("DateTimeOffset", dt2.Rows(0)(0).GetType.Name, "this was expected")
Assert.AreEqual("DateTime", dt2.Rows(0)(0).GetType.Name, "*BUG* WHAT?! how can you tell me that 2099-12-31T23:59:58.576+13:00 is a DateTime?")
For Each item As DataRow In dt2.Rows
dr = dt1.NewRow
Try
dr.ItemArray = item.ItemArray
Catch ex As ArgumentException
Assert.AreEqual("Specified cast is not valid.Couldn't store <2019-12-31 23:59:58> in MyColDTO Column. Expected type is DateTimeOffset.", ex.Message, "Confirm that the bug is giving its bad message")
Assert.Fail("This should not have happened")
End Try
dt1.Rows.Add(dr)
Next
End Sub
控制台输出:
<ds>
<dt>
<MyColDTO>2019-12-31T23:59:58.576+13:00</MyColDTO>
</dt>
</ds>
答案是..因为数据集不支持 DateTimeOffset DataColumn.DataType Property. But .. SQL Server does datetimeoffset (Transact-SQL)
好像是微软软件本身不兼容
我有一个 XML 元素,其值 2099-12-31T23:59:58.576+13:00
来自 DateTimeOffset。
当我 运行 myDS.ReadXml(myStream, XmlReadMode.InferTypedSchema)
我得到 Specified cast is not valid.Couldn't store <2019-12-31 23:59:58> in MyColDTO Column. Expected type is DateTimeOffset.
附加的偏移量应明确指示 DateTimeOffset 而不是 DateTime。
为什么DotNet (FW 4.6.2) 识别不正确? 有简单的修复方法吗?
====自包含vb.net单元测试===
<TestMethod()> Public Sub THC2398_ReadXml_Bug()
Dim ds1 As DataSet, ds2 As DataSet, dt1 As DataTable, dt2 As DataTable, dr As DataRow, dtoAt As DateTimeOffset = DateTimeOffset.Parse("2019-12-31T23:59:58.576+13:00")
Assert.AreEqual("v4.0.30319", GetType(String).Assembly.ImageRuntimeVersion, "Version check")
Assert.AreEqual("mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089", GetType(String).Assembly.FullName, "Version check")
ds1 = New DataSet("ds")
dt1 = New DataTable("dt")
ds1.Tables.Add(dt1)
dt1.Columns.Add(New DataColumn("MyColDTO", GetType(DateTimeOffset)))
dr = dt1.NewRow
dr("MyColDTO") = dtoAt
dt1.Rows.Add(dr)
Assert.AreEqual(1, dt1.Rows.Count)
Assert.AreEqual("DateTimeOffset", dt1.Rows(0)(0).GetType.Name)
Dim tw As IO.TextWriter = New StringWriter, tr As TextReader
dt1.WriteXml(tw, XmlWriteMode.IgnoreSchema)
System.Console.WriteLine(tw.ToString)
tr = New StringReader(tw.ToString)
ds2 = New DataSet("ds")
ds2.ReadXml(tr, XmlReadMode.InferTypedSchema)
dt2 = ds2.Tables("dt")
Assert.AreEqual(1, dt2.Rows.Count)
'Assert.AreEqual("DateTimeOffset", dt2.Rows(0)(0).GetType.Name, "this was expected")
Assert.AreEqual("DateTime", dt2.Rows(0)(0).GetType.Name, "*BUG* WHAT?! how can you tell me that 2099-12-31T23:59:58.576+13:00 is a DateTime?")
For Each item As DataRow In dt2.Rows
dr = dt1.NewRow
Try
dr.ItemArray = item.ItemArray
Catch ex As ArgumentException
Assert.AreEqual("Specified cast is not valid.Couldn't store <2019-12-31 23:59:58> in MyColDTO Column. Expected type is DateTimeOffset.", ex.Message, "Confirm that the bug is giving its bad message")
Assert.Fail("This should not have happened")
End Try
dt1.Rows.Add(dr)
Next
End Sub
控制台输出:
<ds>
<dt>
<MyColDTO>2019-12-31T23:59:58.576+13:00</MyColDTO>
</dt>
</ds>
答案是..因为数据集不支持 DateTimeOffset DataColumn.DataType Property. But .. SQL Server does datetimeoffset (Transact-SQL)
好像是微软软件本身不兼容