因此我们了解到,我们需要更加精确的判断时间的界限。因此我们重新将代码改为如下:
Code
<!--<br /><br />Code highlighting produced by Actipro CodeHighlighter (freeware)<br />http://www.CodeHighlighter.com/<br /><br />-->staticvoidMain(string[]args)
{
DateTimeindate=newDateTime(2008,9,30);//入住时间
DateTimeoutdate=newDateTime(2008,10,5,12,15,12);//退房时间
doubledays=(outdate-indate).Days;//计算入住了几天
if(outdate.Hour<=11)//这个时间段是0:0:0到11:59:59
{
days+=0;//当天不计算房费
}
else
{//如果小时部分的值是12,且其的分秒部分的值都是0,就是12点整
if(outdate.Hour==12&&outdate.Minute==0&&outdate.Second==0)
{
days+=0;//当天也不计算房费
}
else//12:0:0以后
{
if(outdate.Hour<=17)//时间段为12:0:1到17:59:59
{
days+=0.5;//加收半天房费
}
else//18点之后
{//如果小时部分的值是18,且其的分秒部分的值都是0,就是18点整
if(outdate.Hour==18&&outdate.Minute==0&&outdate.Second==0)
{
days+=0.5;//加收半天房费
}
else
{//18点之后
days++;//加收一天房费
}
}
}
}
System.Console.WriteLine("你的入住结算信息/n入住时间{0}/n退房时间{1}/n一共入住了{2}天",indate,outdate,days);
}
上述的代码,使用了4个条件的嵌套判断,将退房的时间作了精确的判断(考虑到了分秒的临界点),同时初学的人员再次要了解到注释的重要性,以上的逻辑,如果不描写注释,估计过一个月后,你自己都不知道自己在干什么了。
现在我们运行程序,设定以下的时间段
<!--<br /><br />Code highlighting produced by Actipro CodeHighlighter (freeware)<br />http://www.CodeHighlighter.com/<br /><br />-->DateTimeindate=newDateTime(2008,9,30);//入住时间
DateTimeoutdate=newDateTime(2008,10,5,12,15,12);//退房时间
我们程序的运行结果得到了我们乐于见到的5.5天
结构化编程,还有一个重要的概念就是模块化,我们上面的代码中对整点的判断。比如12点整
outdate.Hour == 12 && outdate.Minute == 0 && outdate.Second == 0
和18点整
outdate.Hour == 18 && outdate.Minute == 0 && outdate.Second == 0
完全可以函数化,因此我们需要添加一个函数模块。
Code
<!--<br /><br />Code highlighting produced by Actipro CodeHighlighter (freeware)<br />http://www.CodeHighlighter.com/<br /><br />-->///<summary>
///判断给定的时间是否是一个整时
///</summary>
///<paramname="date">需要判断的时间</param>
///<returns>如果是整时,则返回true,否则返回false</returns>
staticboolIsZeroTime(DateTimedate)
{
if(date.Minute==0&&date.Second==0)//如果给定的时间的分秒值都是0
{
returntrue;
}
else
{
returnfalse;
}
}
我们新编写的IsZeroTime将判断整时的问题进行了函数(模块)化,不过初学的人要注意一点,如果一个if else 中仅处理一个问题的时候,我们完全可以优化成如下代码
Code
<!--<br /><br />Code highlighting produced by Actipro CodeHighlighter (freeware)<br />http://www.CodeHighlighter.com/<br /><br />-->///<summary>
///判断给定的时间是否是一个整时
///</summary>
///<paramname="date">需要判断的时间</param>
///<returns>如果是整时,则返回true,否则返回false</returns>
staticboolIsZeroTime(DateTimedate)
{
returndate.Minute==0&&date.Second==0;
}
现在我们再来修改原先的逻辑主体的代码为:
Code
<!--<br /><br />Code highlighting produced by Actipro CodeHighlighter (freeware)<br />http://www.CodeHighlighter.com/<br /><br />-->staticvoidMain(string[]args)
{
DateTimeindate=newDateTime(2008,9,30);//入住时间
DateTimeoutdate=newDateTime(2008,10,5,12,15,12);//退房时间
doubledays=(outdate-indate).Days;//计算入住了几天
if(outdate.Hour<=11)//这个时间段是0:0:0到11:59:59
{
days+=0;//当天不计算房费
}
else
{
if(outdate.Hour==12&&IsZeroTime(outdate))//如果是12点整
{
days+=0;//当天也不计算房费
}
else//12:0:0以后
{
if(outdate.Hour<=17)//时间段为12:0:1到17:59:59
{
days+=0.5;//加收半天房费
}
else
{//18点之后
if(outdate.Hour==18&&IsZeroTime(outdate))//如果是18点整
{
days+=0.5;//加收半天房费
}
else
{//18点之后
days++;//加收一天房费
}
}
}
}
System.Console.WriteLine("你的入住结算信息/n入住时间{0}/n退房时间{1}/n一共入住了{2}天",indate,outdate,days);
}
以上代码使用了IsZeroTime函数,让代码的表现能力更强更优雅。那现在是不是万事大吉呢了?我们现在看看以下的时间:
DateTime indate = new DateTime(2008, 10, 5, 2, 12, 0);//入住时间
DateTime outdate = new DateTime(2008, 10, 5, 12, 0, 0);//退房时间
我们的程序告诉我们,顾客住了0天!!!
而以下的日期
DateTime indate = new DateTime(2008, 10, 5, 19, 12, 0); //入住时间
DateTime outdate = new DateTime(2008, 10, 5, 19, 13, 0); //退房时间
我们的程序告诉我们,顾客住了1天!!!
啊,那是多么不公平的事情啊,一个住了近10个小时的人计算机竟然说他可以免费,而另一个住了才1分钟的顾客,竟然要支付整整一天的房价!
问题出在哪里呢?如果你仔细想想,就可以猜到,我们一开始的计算也许就错了。
double days = (outdate - indate).Days; //计算入住了几天
原来这个Days不是计算过了几个晚上,而是两个时间的间隔,该间隔用纳秒来计算出。所以我们要使用差值来计算用户是不是过夜的话,不能简单的进行相减。不过如果我们使用些技巧就可以来解决,比如我们把两个时间都切换到午夜时间(就是午夜凶铃那个电话铃响的时间,0:0:0),那么就可以计算机出用户是否过夜了。
double days = (outdate.Date - indate.Date).Days; //计算入住了几天
这样的话,只要顾客不是同天退房,就会得到大于0的值,如果值是0就表示用户是同天退房的。如果用户是隔夜退房的,我们的逻辑计算照旧,否则要看看用户住的时间是否超过半天。这样才合理嘛。
所以,我们需要把代码作些小的调正,先判断下顾客是否同天退房,如果是同天退房的话,计算他入住了几个小时:超过12小时算一天,否则算半天;如果顾客是隔天退房,那还继续保持我们原有的逻辑处理。
Code
<!--<br /><br />Code highlighting produced by Actipro CodeHighlighter (freeware)<br />http://www.CodeHighlighter.com/<br /><br />-->staticvoidMain(string[]args)
{
DateTimeindate=newDateTime(2008,10,5,19,12,0);//入住时间
DateTimeoutdate=newDateTime(2008,10,5,19,13,0);//退房时间
doubledays=(outdate.Date-indate.Date).Days;//计算入住了几天
if(days==0)
{//同天退房
if((outdate-indate).TotalHours<=12)//入住时间不超过12小时
{
days+=0.5;//以半天房费计算
}
else//超过12小时
{
days++;//计算一天的房费
}
}
else
{//隔夜退房
if(outdate.Hour<=11)//这个时间段是0:0:0到11:59:59
{
days+=0;//当天不计算房费
}
else
{
if(outdate.Hour==12&&IsZeroTime(outdate))//如果是12点整
{
days+=0;//当天也不计算房费
}
else//12:0:0以后
{
if(outdate.Hour<=17)//时间段为12:0:1到17:59:59
{
days+=0.5;//加收半天房费
}
else
{//18点之后
if(outdate.Hour==18&&IsZeroTime(outdate))//如果是18点整
{
days+=0.5;//加收半天房费
}
else
{//18点之后
days++;//加收一天房费
}
}
}
}
}
System.Console.WriteLine("你的入住结算信息/n入住时间{0}/n退房时间{1}/n一共入住了{2}天",indate,outdate,days);
}
现在我们可以处理同天退房和隔夜退房的不同逻辑了,我们可以看到,通过精确的控制,我们的代码可处理的能力越来越强大,不过代码也越来越复杂了,嵌套也越来越庞大。因此,我们开始反思,为了追求正确的逻辑,我们是不是走了太远了?
分享到:
相关推荐
ICS Triplex公司Trusted容错三重化冗余可编程控制系统硬件手册 是最详细的中文手册,共107页,非常难得的电子版资料 ICS Triplex是ICS (Industrial Control Service Group) 跨国集团的下属公司,其安全控制系统是...
STEP7 IO冗余编程方法zip,STEP7 IO冗余编程方法
主要内容:对西门子S7-300系列PLC冗余IO编程的详细讲解。
PCS 7下的冗余IO编程zip,PCS 7下的冗余IO编程
函数式编程(FP)是一种软件开发风格,它注重不依赖于编程状态的函数。函数式代码易于测试和复用,容易实现并发,且不容易受到bug的攻击。Scala是一种能很好支持函数式编程的新兴JVM语言。《Scala函数式编程》是针对...
PCS7 IO冗余编程方法zip,PCS7 IO冗余编程方法
西门子PCS7下冗余IO编程pdf,西门子PCS7下冗余IO编程:本文详细介绍了冗余IO的原理,模板IO冗余和通道IO冗余的区别。在PCS7V6.1和PCS7V7.0下如何对模板IO冗余和通道IO冗余进行硬件组态,冗余设置,CFC
本文详细介绍的冗余IO的原理,模板IO冗余和通道IO冗余的区别,以及组态、设置、编程等。
西门子STEP 7下冗余IO编程zip,西门子STEP 7下冗余IO编程:为了提高系统可靠性,除了使用冗余CPU,还可以使用冗余IO模板,容许某个...本文通过相应章节详细介绍了实现冗余IO功能的硬件结构和STEP 7中的软件编程 ......
5.3 逻辑结构设计 逻辑结构设计的任务就是把概念模型转换为某个具体的数据库管理系统所 支持的数据模型。 具体来讲就是从 E-R 模型到关系模型的转换。 (1)根据 E-R 模型设计关系模式; (2)选择适当的范式对所...
PROFINET 下冗余IO编程.pdf
西门子 STEP 7 下冗余IO编程zip,西门子 STEP 7 下冗余IO编程
西门子 s7 冗余编程手册 redundant IO practice under STEP7 V5.3
主要是针对matlab编程的14个案例; 案例1:一般区域二重、三重积分; 案例2:被积函数含有积分项的一类积分; 案例3:一般区域n重积分; 案例4:蒙特卡洛法计算n重积分; 案例5:第二类Fredholm积分方程; 案例6:第...
西门子STEP 7 的冗余IO编程指导,详细讲述如何设置编程IO冗余。
试验发现当保护电路结构相同时,由于故障类型的不同,双重化串联、并联冗余保护电路会产生不同的保护效果:发生类型I故障,会使串联冗余式保护电路发生误断,导致电源停止供电;发生类型II故障,会使并联冗余式保护电路不能...
绍了循环冗余校验(CRC)编码器的设计及FPGA实现过程,采用原理图输入法对整个系统进行了编译和仿真,并在芯片 EPlK30TCl44.3中对该设计的核心部分进行了测试验证。结果表明,试验数据与理论分析结果完全相符。 ...
网络通信安全:网络结构冗余能力.pptx
关系数据库系统结构化查询语言的冗余性研究.pdf
采取文档版本变化驱动产品结构树的版本变化的方法,建立了产品结构化信息树版本模型,提出了一套基于控制锁的版本控制规则,能够对产品结构化信息树的版本变化进行控制,避免了版本冗余。基于版本控制规则,论述了...