概述
写下本文缘于前几天博客园一位朋友发表了一篇.NET面试题的文章,其中一个关于DateTime的问题引起了大家激烈的争论,鉴于日期时间类型是大家开发中会频繁使用的一个中数据类型,这里我们有必要来对.NET Framework中的日期时间类型做一个深入的认识。
从.NET Framework 1.0开始,就提供了DateTime类型来表示一个日期时间类型,它是一个结构类型,并且不可以为空,这在一定程度上给我们在往数据库中保存数据时带来了很大的麻烦,因为我们知道,在数据库中datatime类型是可以为Null的,为了解决这个问题,不得不经常使用DateTime.MinValue来表示,但这并不是我们想要的。幸运的是到了.NET Framework 2.0中,提供了可空类型,此时我们就可以使用Nullable来表示一个日期时间类型,它是可以为Null的,这给我们带来了极大的方便。
到了.NET Framework 3.5中,又为我们提供了一个全新的日期时间类型DateTimeOffset,它通常以相对于格林威治时间(GMT,Greenwich Mean Time)的日期和时间来表示,格林威治时间又被称为国际标准时间UTC(Universal Time Code)。除此之外,在.NET Framework中还为我们提供了TimeZone类用来表示时区,到了.NET Framework 3.5中,对TimeZone类进一步增强,提供了TimeZoneInfo类来表示世界上的任何时区。
在本文中,我们将对以上日期时间类型、时区类进行详细的介绍。
DateTime和DateTimeOffset
DateTime 值类型表示值范围在公元0001 年1 月1 日午夜12:00:00 到公元9999 年12月31日晚上11:59:59 之间的日期和时间;DateTimeOffset包含一个DateTime 值以及一个名为Offset属性,该属性用于确定当前 DateTimeOffset 实例的日期和时间与UTC之间的差值,我们先来看一下这段代码的输出:
static void Main(string[] args)
{
Console.WriteLine(DateTime.Now);
Console.WriteLine(DateTimeOffset.Now);
}
输出结果为:
可以看到,DateTime输出了日期和时间,DateTimeOffset类型不仅输出了日期和时间,还给出当前时间与UTC之间的差值。接下来我们再看一段代码,如何手工构造一个DateTime和DateTimeOffset实例:
static void Main(string[] args)
{
DateTime dateA = new DateTime(2008,8,26,23,1,48);
DateTimeOffset dateB = new DateTimeOffset(2008, 8, 26, 23, 1, 48,
new TimeSpan(4,0,0));
Console.WriteLine(dateA);
Console.WriteLine(dateB);
}输出结果如下图所示:
转换DateTime为DateTimeOffset
通过上面的两个例子,大家应该对DateTimeOffset有了一个基本的认识,DateTimeOffset提供了比DateTime更高程度的时区识别能力,接下来我们看如何在DateTime和DateTimeOffset之间进行转换,开始之前我们先了解一下DateTimeKind枚举,在DateTime中提供了一个名为Kind的属性,它用来指示DateTime对象是表示本地时间、国际标准时间(UTC),还是既不指定为本地时间,也不指定为国际标准时间(UTC),DateTimeKind的定义如下:
public enum DateTimeKind
{
Unspecified,
Utc,
Local
}
对于UTC 和本地DateTime值,得到的DateTimeOffset值的Offset属性准确反映UTC 或本地时区偏移量,