Attached is a patch to serialize and deserialize the DateTimeMode
property of DataColumn. I am not sure, but the patch might fix Bug 335464??
Also, while I was editing DataSetTest.cs I noticed that the
SerializeDataSet3() function is missing a [Test] attribute, probably it
is a bug.
John
Index: class/System.Data/Test/System.Data/DataSetTest.cs
===================================================================
--- class/System.Data/Test/System.Data/DataSetTest.cs (revision 156256)
+++ class/System.Data/Test/System.Data/DataSetTest.cs (working copy)
@@ -1176,6 +1176,95 @@
xml, XmlNodeType.Document, null));
}
+#if NET_2_0
+ [Test]
+ public void SerializeDateTimeModeTest()
+ {
+ MemoryStream ms = new MemoryStream ();
+ global::System.Runtime.Serialization.Formatters.Binary.BinaryFormatter bf =
+ new global::System.Runtime.Serialization.Formatters.Binary.BinaryFormatter();
+
+ DataTable tb1 = new DataTable ();
+ tb1.Columns.Add ("id", typeof (int));
+ tb1.Columns.Add ("Date", typeof (DateTime)).DateTimeMode = DataSetDateTime.Utc;
+
+ DateTime d1 = DateTime.Parse("2010-04-27 4:15:05 PM");
+ d1 = DateTime.SpecifyKind(d1, DateTimeKind.Utc);
+ DateTime d2 = DateTime.Parse("2010-03-15 3:53:26 AM");
+ d2 = DateTime.SpecifyKind(d2, DateTimeKind.Local);
+ DateTime d3 = DateTime.UtcNow;
+
+ tb1.Rows.Add(new object[] {1, d1});
+ tb1.Rows.Add(new object[] {2, d2});
+ tb1.Rows.Add(new object[] {3, d3});
+
+ bf.Serialize (ms,tb1);
+ byte [] serializedStream = ms.ToArray ();
+ ms.Close ();
+ //DserializeTable
+ ms = new MemoryStream (serializedStream);
+ DataTable dt = (DataTable)bf.Deserialize (ms);
+ ms.Close ();
+
+ Assert.AreEqual(3, dt.Rows.Count);
+ Assert.AreEqual(DataSetDateTime.Utc, dt.Columns["Date"].DateTimeMode);
+ for (int i = 0; i < 3; i++) {
+ Assert.AreEqual(DateTimeKind.Utc, ((DateTime)dt.Rows[i]["Date"]).Kind);
+ switch ((int)dt.Rows [i]["id"]) {
+ case 1:
+ Assert.AreEqual(d1, dt.Rows[i]["Date"]);
+ break;
+ case 2:
+ Assert.AreEqual(d2.ToUniversalTime(), dt.Rows[i]["Date"]);
+ break;
+ case 3:
+ Assert.AreEqual(d3, dt.Rows[i]["Date"]);
+ break;
+ default:
+ Assert.Fail("Unknown id");
+ break;
+ }
+ }
+
+ //Now try with local time
+ tb1.Rows.Clear();
+ tb1.Columns["Date"].DateTimeMode = DataSetDateTime.Local;
+ tb1.Rows.Add(new object[] {1, d1});
+ tb1.Rows.Add(new object[] {2, d2});
+ tb1.Rows.Add(new object[] {3, d3});
+
+ ms = new MemoryStream();
+ bf = new global::System.Runtime.Serialization.Formatters.Binary.BinaryFormatter();
+ bf.Serialize (ms,tb1);
+ serializedStream = ms.ToArray ();
+ ms.Close ();
+ //DserializeTable
+ ms = new MemoryStream (serializedStream);
+ dt = (DataTable)bf.Deserialize (ms);
+ ms.Close ();
+
+ Assert.AreEqual(3, dt.Rows.Count);
+ Assert.AreEqual(DataSetDateTime.Local, dt.Columns["Date"].DateTimeMode);
+ for (int i = 0; i < 3; i++) {
+ Assert.AreEqual(DateTimeKind.Local, ((DateTime)dt.Rows[i]["Date"]).Kind);
+ switch ((int)dt.Rows [i]["id"]) {
+ case 1:
+ Assert.AreEqual(d1.ToLocalTime(), dt.Rows[i]["Date"]);
+ break;
+ case 2:
+ Assert.AreEqual(d2, dt.Rows[i]["Date"]);
+ break;
+ case 3:
+ Assert.AreEqual(d3.ToLocalTime(), dt.Rows[i]["Date"]);
+ break;
+ default:
+ Assert.Fail("Unknown id");
+ break;
+ }
+ }
+ }
+#endif
+
/* To be added
[Test]
public void WriteDiffReadAutoWriteSchema ()
Index: class/System.Data/System.Data/XmlSchemaWriter.cs
===================================================================
--- class/System.Data/System.Data/XmlSchemaWriter.cs (revision 156256)
+++ class/System.Data/System.Data/XmlSchemaWriter.cs (working copy)
@@ -706,6 +706,16 @@
XmlConstants.MsdataNamespace,
"true");
+#if NET_2_0
+ if (col.DataType == typeof(DateTime) && col.DateTimeMode != DataSetDateTime.UnspecifiedLocal) {
+ w.WriteAttributeString (
+ XmlConstants.MsdataPrefix,
+ XmlConstants.DateTimeMode,
+ XmlConstants.MsdataNamespace,
+ col.DateTimeMode.ToString());
+ }
+#endif
+
XmlQualifiedName typeQName = null;
if (col.MaxLength < 0) {
w.WriteStartAttribute ("type", String.Empty);
@@ -800,6 +810,7 @@
XmlConstants.MsdataNamespace,
"true");
+
if (col.MaxLength < 0) {
// otherwise simpleType is written later
w.WriteStartAttribute ("type", String.Empty);
Index: class/System.Data/System.Data/DataSet.cs
===================================================================
--- class/System.Data/System.Data/DataSet.cs (revision 156256)
+++ class/System.Data/System.Data/DataSet.cs (working copy)
@@ -1251,7 +1251,14 @@
#region Private Methods
+#if NET_2_0
+ internal static string WriteObjectXml (object o) {
+ return WriteObjectXml (o, XmlDateTimeSerializationMode.Unspecified);
+ }
+ internal static string WriteObjectXml (object o, XmlDateTimeSerializationMode xmode)
+#else
internal static string WriteObjectXml (object o)
+#endif
{
switch (Type.GetTypeCode (o.GetType ())) {
case TypeCode.Boolean:
@@ -1262,7 +1269,7 @@
return XmlConvert.ToString ((Char) o);
case TypeCode.DateTime:
#if NET_2_0
- return XmlConvert.ToString ((DateTime) o, XmlDateTimeSerializationMode.Unspecified);
+ return XmlConvert.ToString ((DateTime) o, xmode);
#else
return XmlConvert.ToString ((DateTime) o);
#endif
@@ -1409,7 +1416,26 @@
throw new InvalidOperationException ();
((IXmlSerializable)rowObject).WriteXml (writer);
} else {
+
+#if NET_2_0
+ if (col.DataType == typeof(DateTime)) {
+ switch (col.DateTimeMode) {
+ case DataSetDateTime.Local:
+ writer.WriteString (WriteObjectXml (rowObject, XmlDateTimeSerializationMode.Local));
+ break;
+ case DataSetDateTime.Utc:
+ writer.WriteString (WriteObjectXml (rowObject, XmlDateTimeSerializationMode.Utc));
+ break;
+ default:
+ writer.WriteString (WriteObjectXml (rowObject));
+ break;
+ }
+ } else {
+ writer.WriteString (WriteObjectXml (rowObject));
+ }
+#else
writer.WriteString (WriteObjectXml (rowObject));
+#endif
}
writer.WriteEndElement ();
Index: class/System.Data/System.Data/XmlDataLoader.cs
===================================================================
--- class/System.Data/System.Data/XmlDataLoader.cs (revision 156256)
+++ class/System.Data/System.Data/XmlDataLoader.cs (working copy)
@@ -200,7 +200,11 @@
|| reader.NodeType != XmlNodeType.EndElement);
}
*/
+#if NET_2_0
+ internal static object StringToObject (Type type, string value, DataSetDateTime kind)
+#else
internal static object StringToObject (Type type, string value)
+#endif
{
if (type == null) return value;
@@ -209,7 +213,15 @@
case TypeCode.Byte: return XmlConvert.ToByte (value);
case TypeCode.Char: return (char)XmlConvert.ToInt32 (value);
#if NET_2_0
- case TypeCode.DateTime: return XmlConvert.ToDateTime (value, XmlDateTimeSerializationMode.Unspecified);
+ case TypeCode.DateTime:
+ switch (kind) {
+ case DataSetDateTime.Local:
+ return XmlConvert.ToDateTime (value, XmlDateTimeSerializationMode.Local);
+ case DataSetDateTime.Utc:
+ return XmlConvert.ToDateTime (value, XmlDateTimeSerializationMode.Utc);
+ default:
+ return XmlConvert.ToDateTime (value, XmlDateTimeSerializationMode.Unspecified);
+ }
#else
case TypeCode.DateTime: return XmlConvert.ToDateTime (value);
#endif
@@ -362,7 +374,12 @@
IDictionaryEnumerator enumerator = rowValue.GetEnumerator ();
while (enumerator.MoveNext ()) {
+#if NET_2_0
+ DataColumn c = table.Columns[enumerator.Key.ToString ()];
+ row [enumerator.Key.ToString ()] = StringToObject (c.DataType, enumerator.Value.ToString (), c.DateTimeMode);
+#else
row [enumerator.Key.ToString ()] = StringToObject (table.Columns[enumerator.Key.ToString ()].DataType, enumerator.Value.ToString ());
+#endif
}
if (fillRows)
Index: class/System.Data/System.Data/XmlDiffLoader.cs
===================================================================
--- class/System.Data/System.Data/XmlDiffLoader.cs (revision 156256)
+++ class/System.Data/System.Data/XmlDiffLoader.cs (working copy)
@@ -243,7 +243,11 @@
c.ColumnMapping != MappingType.Attribute) continue;
if (c.Namespace == null && reader.NamespaceURI == String.Empty ||
c.Namespace == reader.NamespaceURI) {
+#if NET_2_0
+ object data = XmlDataLoader.StringToObject (c.DataType, reader.Value, c.DateTimeMode);
+#else
object data = XmlDataLoader.StringToObject (c.DataType, reader.Value);
+#endif
if (loadType == DataRowVersion.Current)
Row [c] = data;
else
@@ -271,7 +275,12 @@
string colName = XmlHelper.Decode (reader.LocalName);
if (Table.Columns.Contains (colName))
{
+#if NET_2_0
+ DataColumn c = Table.Columns[colName];
+ object data = XmlDataLoader.StringToObject (c.DataType, reader.ReadString (), c.DateTimeMode);
+#else
object data = XmlDataLoader.StringToObject (Table.Columns[colName].DataType, reader.ReadString ());
+#endif
if (loadType == DataRowVersion.Current) Row [colName] = data;
else Row.SetOriginalValue (colName, data);
Index: class/System.Data/System.Data/XmlDataReader.cs
===================================================================
--- class/System.Data/System.Data/XmlDataReader.cs (revision 156256)
+++ class/System.Data/System.Data/XmlDataReader.cs (working copy)
@@ -228,7 +228,11 @@
DataColumn col = row.Table.Columns [XmlHelper.Decode (reader.LocalName)];
if (col == null || col.Namespace != reader.NamespaceURI)
return;
+#if NET_2_0
+ row [col] = StringToObject (col.DataType, reader.Value, col.DateTimeMode);
+#else
row [col] = StringToObject (col.DataType, reader.Value);
+#endif
}
private void ReadElementContent (DataRow row)
@@ -261,7 +265,11 @@
#if SILLY_MS_COMPATIBLE
// As to MS, "test string" and "test <!-- comment -->string" are different :P
if (simple != null && row.IsNull (simple))
+#if NET_2_0
+ row [simple] = StringToObject (simple.DataType, s, DataSetDateTime.Unspecified);
+#else
row [simple] = StringToObject (simple.DataType, s);
+#endif
#else
// But it does not mean we support "123<!-- comment -->456". just allowed for string
if (simple != null)
@@ -325,7 +333,11 @@
}
#endif
} else {
+#if NET_2_0
+ row [col] = StringToObject (col.DataType, reader.ReadElementString (), col.DateTimeMode);
+#else
row [col] = StringToObject (col.DataType, reader.ReadElementString ());
+#endif
}
if (!wasEmpty && reader.Depth > depth) {
@@ -372,8 +384,11 @@
reader.Skip ();
reader.MoveToContent ();
}
-
+#if NET_2_0
+ internal static object StringToObject (Type type, string value, DataSetDateTime kind)
+#else
internal static object StringToObject (Type type, string value)
+#endif
{
if (type == null) return value;
@@ -382,7 +397,15 @@
case TypeCode.Byte: return XmlConvert.ToByte (value);
case TypeCode.Char: return (char)XmlConvert.ToInt32 (value);
#if NET_2_0
- case TypeCode.DateTime: return XmlConvert.ToDateTime (value, XmlDateTimeSerializationMode.Unspecified);
+ case TypeCode.DateTime:
+ switch (kind) {
+ case DataSetDateTime.Local:
+ return XmlConvert.ToDateTime (value, XmlDateTimeSerializationMode.Local);
+ case DataSetDateTime.Utc:
+ return XmlConvert.ToDateTime (value, XmlDateTimeSerializationMode.Utc);
+ default:
+ return XmlConvert.ToDateTime (value, XmlDateTimeSerializationMode.Unspecified);
+ }
#else
case TypeCode.DateTime: return XmlConvert.ToDateTime (value);
#endif
Index: class/System.Data/System.Data/XmlConstants.cs
===================================================================
--- class/System.Data/System.Data/XmlConstants.cs (revision 156256)
+++ class/System.Data/System.Data/XmlConstants.cs (working copy)
@@ -106,6 +106,7 @@
public const string ReadOnly = "ReadOnly";
#if NET_2_0
public const string UseCurrentCulture = "UseCurrentCulture";
+ public const string DateTimeMode = "DateTimeMode";
#endif
public static XmlQualifiedName QnString = new XmlQualifiedName ("string", XmlSchema.Namespace);
Index: class/System.Data/System.Data/XmlSchemaDataImporter.cs
===================================================================
--- class/System.Data/System.Data/XmlSchemaDataImporter.cs (revision 156256)
+++ class/System.Data/System.Data/XmlSchemaDataImporter.cs (working copy)
@@ -809,6 +809,27 @@
break;
}
}
+#if NET_2_0
+ //DateTimeMode can only be set on DateTime columns so we need to delay
+ //parsing this attribute until the data type has been set.
+ if (col.DataType == typeof(DateTime)) {
+ foreach (XmlAttribute attr in obj.UnhandledAttributes) {
+ if (attr.NamespaceURI != XmlConstants.MsdataNamespace)
+ continue;
+ if (attr.LocalName != XmlConstants.DateTimeMode)
+ continue;
+
+ if (attr.Value == "Local")
+ col.DateTimeMode = DataSetDateTime.Local;
+ if (attr.Value == "Unspecified")
+ col.DateTimeMode = DataSetDateTime.Unspecified;
+ if (attr.Value == "UnspecifiedLocal")
+ col.DateTimeMode = DataSetDateTime.UnspecifiedLocal;
+ if (attr.Value == "Utc")
+ col.DateTimeMode = DataSetDateTime.Utc;
+ }
+ }
+#endif
}
}
_______________________________________________
Mono-devel-list mailing list
Mono-devel-list@lists.ximian.com
http://lists.ximian.com/mailman/listinfo/mono-devel-list