This article is currently in the process of being translated into Chinese (~92% done).
Working with Dates & Time
C#包含不错的操作日期和时间的数据结构 - 这就是DateTime。这并不是一种数据类型,不过还是放在这一章里,因为经常会需要使用DateTime结构来操作日期和/或时间 - 有时这些操作与对字符串和数字的操作一样多。
就以实例化一个新的DateTime对象开始:
DateTime dt = new DateTime();
Console.WriteLine(dt.ToString());然而输出的结果完全没有意义:01-01-0001 00:00:00。这个值对应的是DateTime.MinValue字段值,不过DateTime有很多有用的属性 - 最有趣的一个是DateTime.Now:
DateTime dt = DateTime.Now;
Console.WriteLine(dt.ToString());这个属性表示当前日期与时间,是个一直在变的值 - 后续的例子中将会展示这一点。不过,多数情况下,需要的还是一个确定的日期和时间 - 幸好,DateTime有几个构造器完全可以实现这一点。例如:
DateTime dt = new DateTime(2042, 12, 24);
Console.WriteLine(dt.ToString());此构造函数参数的顺序是年,月,日,因此上例建立的是一个表示2042年圣诞前夜日期的DateTime对象。
DateTime - 包含时间吗?
不过,时间呢?其实,如果不设置时间,则会默认为00:00:00,前面例子已经展示了。要设置时间也同样简单:
DateTime dt = new DateTime(2042, 12, 24, 18, 42, 0);
Console.WriteLine(dt.ToString());现在DataTime有时间值了,18:42。注意小时值的范围是0 - 23,因为输入值是以24小时制计算的,不过如果想要使用带AM/PM的12小时制时间也不用担心 - 在输出时很容易实现,后续会介绍。
接下来的问题是:如果只需要使用日期部分要怎么办呢?最先想到的解决方案可能是使用Date类替代DateTime类,然而事实上,根本就不存在Date类。原来,DateTime有个Date属性:
DateTime dt = new DateTime(2042, 12, 24, 18, 42, 0);
DateTime date = dt.Date;
Console.WriteLine(date.ToString());不过Date属性也还是一个DateTime对象,只是把其时间部分设置为00:00:00了。这可能会有点混乱,不过细想是有道理的,因为DateTime应该只作为一个容器使用,里面存放着可以以各种方式和格式输出给用户的数据。前面例子已经使用了最基本的ToString()方法,不过DateTime对象还有很多可以从中取得输出的方式。
DateTime输出
取得输出值是使用DateTime最重要的方面,也是一项复杂的工作 - 这要看具体需求。目前为止,只演示了取得输出最基本版的方式:简单地调用ToString()方法。这会按程序当前的文化地区设置输出相应格式的日期和时间字符串,不管用户在世界上的那个地方,他们看到的都会是他们熟悉的日期和时间格式, 毕竟,时间,尤其日期格式的文化地区差异性是非常巨大的。
如果想控制输出的格式,也有不少方法可以实现。最快的方式就是调用某个To*方法,比如,ToShortDateString()方法:
Console.WriteLine(DateTime.Now.ToShortDateString());这会输出日期的一个短版本,完全没有时间部分。也可以使用ToLongDateString()方法:
Console.WriteLine(DateTime.Now.ToLongDateString());这个方法的输出结果非常的依赖于地区设置,不过通常都会是一个包括文字形式的月份名称(而非数字)的长日期。
如果想更进一步控制,以适应某个特殊地区的日期/时间格式,可以使用ToString()方法的某个重载形式,如,指定想要输出格式的特定文化/地区:
var usCulture = new System.Globalization.CultureInfo("en-US");
Console.WriteLine(DateTime.Now.ToString(usCulture.DateTimeFormat));CultureInfo类含有一整个语言的的完整信息,如,怎样书写日期和时间(CultureInfo类会在本教程的后续章节中介绍)。把这些信息传入DateTime类后,它就知道怎样按这种语言的方式把日期和时间表现出来了。不过如果想更具体地控制输出格式呢?
标准日期和时间格式字符串
要获得对输出格式进一步的控制,可以使用.NET framework提供的标准日期和时间格式字符串。这是用于表示日期和/或时间显示方式的单个字母。其完整列表请参考文档,此处只给出几个例子:
DateTime dt = new DateTime(2042, 12, 24, 18, 42, 0);
Console.WriteLine("Short date pattern (d): " + dt.ToString("d"));
Console.WriteLine("Long date pattern (D): " + dt.ToString("D"));
Console.WriteLine("Full date/time pattern (F): " + dt.ToString("F"));
Console.WriteLine("Year/month pattern (y): " + dt.ToString("y"));以上的输出象这样:
Short date pattern (d): 24-12-2042
Long date pattern (D): 24. december 2042
Full date/time pattern (F): 24. december 2042 18:42:00
Year/month pattern (y): december 2042这样对输出的控制又进了一步,不过有时这还是不够 - 有时,需要定制格式字符串。
定制日期和时间格式字符串
要实现完全控制,必需要定制自己的格式字符串。这由传入ToString()的标准格式字母及特殊字符组成,以显示所需的特定日期和/或时间格式 - 包括在何处显示日期/时间的每个部分,要怎样显示这些部分,它们之间要用什么分隔符。这就会有非常多的选项了,因此,如果想要看完整的可用格式指示符的列表,请参考文档,不过还是直接看看其工作方式吧:
DateTime dt = new DateTime(2042, 12, 24, 18, 42, 0);
Console.WriteLine(dt.ToString("MM'/'dd yyyy"));
Console.WriteLine(dt.ToString("dd.MM.yyyy"));
Console.WriteLine(dt.ToString("MM.dd.yyyy HH:mm"));
Console.WriteLine(dt.ToString("dddd, MMMM (yyyy): HH:mm:ss"));
Console.WriteLine(dt.ToString("dddd @ hh:mm tt", System.Globalization.CultureInfo.InvariantCulture));输出象这样:
12/24 2042
24.12.2042
12.24.2042 18:42
onsdag, december (2042): 18:42:00
Wednesday @ 06:42 PM通常,一个或几个d字母表示某个版本的月内日期数字,一个或几个M字母表示月份(小写m用来表示分钟),多个y字母表示年份。要全面了解这些格式指示符的意义,仍然建议参考文档,不过希望上面的例子已经充分地展示了定制格式字符串的强大功能。
日期解析
日前为止,介绍中使用的都是直接在代码中定义的日期,但也有很多情况需要使用用户输入的日期值。然而这一点却意外地很复杂,因为日期的书写格式实在是太多了。.NET framework为此提供了一些方便,因为其支持所有的文化,如前面例子演示的那样,但程序员仍然需要帮助用户按规定的格式输入日期。此外,可以使用Parse()方法来把一个用户输入的字符串转化为DateTime对象,象这样:
var usCulture = new System.Globalization.CultureInfo("en-US");
Console.WriteLine("Please specify a date. Format: " + usCulture.DateTimeFormat.ShortDatePattern);
string dateString = Console.ReadLine();
DateTime userDate = DateTime.Parse(dateString, usCulture.DateTimeFormat);
Console.WriteLine("Date entered (long date format):" + userDate.ToLongDateString());上例就处理得不错,因为此代码展现了.NET framework是怎样尽可能地帮助程序员实现其目标的,由于已经有了一个准备在后续代码中使用的CultureInfo类实例(此例中是一个US 英语的CultureInfo类实例 - 暂时不理解也没关系,后面会有一章非常详尽地讲解CultureInfo类),就顺便用其让用户清楚程序要求的数据格式。后面在第四行代码中又使用了此CultureInfo类实例,对输入值进行实际的解析。最后一行代码输出用户输入的日期时就没有指定文化参数,因此程序会使用当前系统的默认文化来输出。
需要注意的是,Parse()方法非常严格 - 如果用户输入的日期格式不正确,就会抛出异常。因此,最好换用TryParse()方法 - 此方法功能是一样的,但会先检查能否解析得出日期,并不会抛出异常。这是上例使用此方法后的修订版:
var usCulture = new System.Globalization.CultureInfo("en-US");
Console.WriteLine("Please specify a date. Format: " + usCulture.DateTimeFormat.ShortDatePattern);
string dateString = Console.ReadLine();
DateTime userDate;
if (DateTime.TryParse(dateString, usCulture.DateTimeFormat, System.Globalization.DateTimeStyles.None, out userDate))
Console.WriteLine("Valid date entered (long date format):" + userDate.ToLongDateString());
else
Console.WriteLine("Invalid date specified!");总结
在编程中使用日期和时间很重要,但也很复杂。幸好,.NET framework提供了优秀的DateTime类来帮助程序员处理几乎所有方面的问题。