1. 如果尚未运行,请先启动Microsoft Visual Studio 2010。
2. 打开Selection项目,它位于“文档”文件夹下的\Microsoft Press\Visual CSharp Step by Step\Chapter 4\Selection子文件夹中。
3. 在“调试”菜单中选择“开始执行(不调试)”。 Visual Studio 2010将生成并运行应用程序。窗体上包含两个DateTimePicker控件,分别名为first和second(这种控件将显示一个日历,便于用户通过单击下箭头来选择一个日期)。两个控件最初都被设置成今天的日期。
4. 单击Compare按钮。 在下图所示的对话框中,文本框中会显示以下内容:
first == second : False
first != second : True
first < second : False
first <= second : False
first > second : True
first >= second : True
上述结果显然有问题。布尔表达式first == second应该为true,因为first和second都被设为今天的日期。事实上,在上述结果中,似乎只有<和 >=的结果才是正确的!
5. 单击Quit按钮,返回Visual Studio 2010编程环境。
6. 在“代码和文本编辑器”窗口中显示MainWindow.xaml.cs的代码。
7. 找到compareClick方法,如下所示:
private void compareClick(object sender, RoutedEventArgs e)
{
int diff = dateCompare(first.SelectedDate.Value, second.SelectedDate.Value);
info.Text = "";
show("first == second", diff == 0);
show("first != second", diff != 0);
show("first < second", diff < 0);
show("first <= second", diff <= 0);
show("first > second", diff > 0);
show("first >= second", diff >= 0);
}
只要单击窗体上的Compare按钮,就会执行这个方法。该方法获取窗体上first和second这两个DateTimePicker控件中显示的日期值。用户在每个DateTimePicker控件中选择的日期存储在SelectedDate属性中。为了获取日期,要使用这个属性的Value属性(第15章将详细讨论属性)。Value属性的类型是DateTime。DateTime数据类型和int或float等数据类型相似,只是它包含了一些子元素,允许你访问单独的数据项,比如年、月或日。
compareClick方法向dateCompare方法传递两个DateTime值,后者对两个值进行比较。我们将在下一个步骤中具体讨论dateCompare方法。
show方法用于在info文本框控件中汇总比较结果。
8. 找到dateCompare方法,如下所示:
private int dateCompare(DateTime leftHandSide, DateTime rightHandSide)
{
// TO DO
return 42;
}
该方法目前在调用后始终返回同一个值,而不是通过比较实参来返回0,-1或+1。这解释了为什么应用程序不像我们期望的那样工作! 该方法的目的是比较传入的实参,并根据结果来返回一个整数值。如果两个实参相同,就应该返回0。如果第一个实参小于第二个参数的值,则返回-1。如果第一个实参大于第二个实参,则返回+1。日期的比较逻辑是这样的:如果按照日历顺序,一个日期在另一个日期之后,就认为前者大于后者;换言之,新日期要“大于”旧日期。现在需要在这个方法中实现这个逻辑,以便正确地比较两个日期。
9. 在dateCompare方法中删除// TO DO注释和return语句。
10. 在dateCompare方法主体中添加以下加粗的代码:
private int dateCompare(DateTime leftHandSide, DateTime rightHandSide)
{
int result;
if (leftHandSide.Year < rightHandSide.Year)
result = -1;
else if (leftHandSide.Year > rightHandSide.Year)
result = 1;
}
假如表达式leftHandSide.Year < rightHandSide.Year的值为true,则leftHandSide中的日期肯定早于rightHandSide中的日期,所以程序会把result变量设置为-1。否则,如果表达式leftHandSide.Year > rightHandSide.Year的值为true,leftHandSide中的日期肯定晚于rightHandSide中的日期,所以程序把result变量设置为+1。 假如表达式leftHandSide.Year < rightHandSide.Year的值为false,而且表达式leftHandSide.Year > rightHandSide.Year也为false,那么这两个日期的Year属性肯定一样,所以程序需要接着比较这两个日期中的月份。
11. 向dateCompare方法的主体添加以下加粗的代码,把它们添加到前一个步骤添加的代码之后:
private int dateCompare(DateTime leftHandSide, DateTime rightHandSide)
{
...
else if (leftHandSide.Month < rightHandSide.Month)
result = -1;
else if (leftHandSide.Month > rightHandSide.Month)
result = 1;
}
这些语句采用和比较年份相似的逻辑来比较月份。 如果表达式leftHandSide.Month < rightHandSide.Month的值为false,表达式leftHandSide.Month > rightHandSide.Month也为false,那么这两个日期的Month属性肯定一样,所以程序最终还需要比较这两个日期中的天数。
12. 向dateCompare方法的主体添加以下加粗显示的代码,把它们添加到前两个步骤添加的代码之后:
private int dateCompare(DateTime leftHandSide, DateTime rightHandSide)
{
...
else if (leftHandSide.Day< rightHandSide.Day)
result = -1;
else if (leftHandSide.Day > rightHandSide.Day)
result = 1;
else
result = 0;
return result;
}
现在,应该能看出这个逻辑的一些端倪了。 如果表达式leftHandSide.Day < rightHandSide.Day和表达式leftHandSide.Day > rightHandSide.Day的值均为false,表明这两个日期的Day属性肯定一样。就目前的逻辑来判断,Month的值和Year的值肯定也是一样的,所以,这两个日期肯定是一样的,因而,程序将result的值设为0。
最后一个语句返回result变量中存储的值。
13. 在“调试”菜单中,选择 “开始执行(不调试)”。 应用程序将重新生成并重新启动。同样地,两个DateTimePicker控件(first和second)被设为今天的日期。
14. 单击Compare按钮。 文本框中会显示以下内容:
first == second : True
first !=second : False
first < second : False
first <= second : True
first > second : False
first >= second : True
对于完全相同的两个日期,上述结果是正确的。
15. 单击第二个DateTimePicker控件的下箭头,单击明天的日期。
16. 单击Compare按钮。 文本框中会显示以下内容:
first == second : False
first != second : True
first < second : True
first <= second : True
first > second : False
first >= second : False
当第一个日期早于第二个日期时,上述结果是正确的。
17. 测试其他日期,验证结果都符合预期。完成后单击Quit按钮退出。
实际应用程序中的日期比较在体验了如何使用一系列相当长而且复杂的if和else语句之后,我有责任提醒大家,在实际的应用程序中,并不用这种方法来比较日期。在Microsoft .NET Framework类库中,日期是保存在一个特殊类型中的,即DateTime。回头看看前一个练习中所写的dateCompare方法,会看到两个参数,分别为leftHandSide和rightHandSide,它们都是DateTime类型的值10。我们写的程序逻辑只是比较了这两个变量的Date部分,并没有比较Time部分。两个DateTime值要想真正?相等?,不仅日期要一样,时间也必须一样。比较日期和时间是一个非常常见的操作,所以DateTime类型专门内置了一个Compare方法。Compare方法获取两个DateTime实参并对它们进行比较。如果返回小于0的值,表明第一个实参小于第二个实参;如果返回大于0的值,表明第一个实参大于第二个;如果返回0,则表明两个实参代表的是相同的日期和时间。