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

Reply via email to