加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 编程开发 > asp.Net > 正文

谈谈你最熟悉的System.DateTime[下篇]

发布时间:2020-12-16 09:07:50 所属栏目:asp.Net 来源:网络整理
导读:在《谈谈你最熟悉的System.DateTime》一文中,我们从跨时区的角度剖析了我们熟悉的System.DateTime类型。如果你还是采用传统的ADO.NET编程方式,并使用DataSet作为数据实体,可能你会熟悉System.Data.DataSetDateTime这么一个类型。这个类型也是为实现跨时区

在《谈谈你最熟悉的System.DateTime》一文中,我们从跨时区的角度剖析了我们熟悉的System.DateTime类型。如果你还是采用传统的ADO.NET编程方式,并使用DataSet作为数据实体,可能你会熟悉System.Data.DataSetDateTime这么一个类型。这个类型也是为实现跨时区场景下对时间处理而设计的,为了对前文的补充,这篇文章就来谈谈基于DataSet的时间处理问题。

一、你是否关注过DataColumn的DateTimeMode属性

在ADO.NET编程模型中,DataColumn代表DataTable的一个数据列,大家在熟悉不过了。不过,是否有人关注过一个名称为DateTimeMode属性,该属性在DataColumn中的定义如下:

   1: public class DataColumn : MarshalByValueComponent
   3:     //Others...
   5: }

从上面的代码我们可以看出,DateTimeMode属性的类型为DataSetDateTime,这实际上是一个枚举类型。下面给出了DataSetDateTime的定义,该枚举一共包含4个枚举值:Local、Utc、Unspecified和UnspecifiedLocal。

   3:     Local = 1,
   5:     UnspecifiedLocal = 3,1)" id="lnum6">   6:     Utc = 4
static ContactDataSet CreateContact(DateTime birthday)
   4:     var row = ds.Contact.NewContactRow();
   6:     row.Name = "Foo";
   8:     ds.Contact.AddContactRow(row);
  10: }
  12: {
  14:     row.UtcBirthDay                 = birthDay;
  16:     row.UnspecifiedLocalBirthDay    = birthDay;
  18: void DispalyBirthday(ContactDataSet ds)
  20:     var row = ds.Contact[0];
  22:     Console.WriteLine("tUtc: ttt{0}",row.UtcBirthDay);
  24:     Console.WriteLine("tUnspecifiedLocal: t{0}n",row.UnspecifiedLocalBirthDay);
  26:     Console.WriteLine(  27:     Console.WriteLine(  28:     Console.WriteLine(  29:     Console.WriteLine(  30: }

我们的实例程序是这样的:分别创建基于三种不同的DateTimeKind的DateTime对象,并据此创建三个ContractDataSet对象。最后调用DisplayBirthday方法将4个基于不同DateTimeMode的字段的时间和DateTimeKind打印出来。

2: var ds2 = CreateContact( 3: var ds3 = CreateContact( 4:?
   6: DispalyBirthday(ds1);
   8: DispalyBirthday(ds2);
  10: DispalyBirthday(ds3);

最终的输出结果证实了我们上述的关于时间转换规则的结论:

2: Local: 8/24/1981 12:00:00 AM
   4:         Unspecified:            8/24/1981 12:00:00 AM
   6:? 
   8:         Utc:                    Utc
  10:         UnspecifiedLocal:       Unspecified
  12: DateTimeKind.Unspecified
  14:         Utc:                    8/24/1981 12:00:00 AM
  16:         UnspecifiedLocal:       8/24/1981 12:00:00 AM
  18:         Local:                  Local
  20:         Unspecified:            Unspecified
  22:? 
  24:         Local:                  8/24/1981 8:00:00 AM
  26:         Unspecified:            8/24/1981 12:00:00 AM
  28:? 
  30:         Utc:                    Utc
  32:         UnspecifiedLocal:       Unspecified

四、DataSetDateTime.Unspecified V.S. DataSetDateTime.UnspecifiedLocal

到不前为止,我们貌似还看不到DataSetDateTime.Unspecified和DataSetDateTime.UnspecifiedLoca的差别。实际上,它们的差别体现在序列化上面:DataSetDateTime.UnspecifiedLoca在序列化的时候会保留基于当前时区的偏移量,而DataSetDateTime.Unspecified则不会。这个结论我也可以实例来证实,为此我写了如下一段代码对ContactDataSet进行序列化,并将序列化后的XML打印出来。

2: using (MemoryStream stream = new MemoryStream(1000))
   4:     ds.WriteXml(stream);
   6: }   

从输出的结果我们可以看出UnspecifiedBirthday和UnspecifiedLocalBirday之间的差别,后者有+8的偏移量,前者没有。

2: Contact>