收藏 分销(赏)

用c++编写计算日期的函数.docx

上传人:s4****5z 文档编号:8753587 上传时间:2025-03-01 格式:DOCX 页数:6 大小:270.83KB
下载 相关 举报
用c++编写计算日期的函数.docx_第1页
第1页 / 共6页
用c++编写计算日期的函数.docx_第2页
第2页 / 共6页
点击查看更多>>
资源描述
14.1 分解与抽象 人类解决复杂问题采用的主要策略是“分而治之”,也就是对问题进行分解,然后分别解决各个子问题。著名的计算机科学家Parnas认为,巧妙的分解系统可以有效地系统的状态空间,降低软件系统的复杂性所带来的影响。对于复杂的软件系统,可以逐个将它分解为越来越小的组成部分,直至不能分解为止。这样在小的分解层次上,人就很容易理解并实现了。当所有小的问题解决完毕,整个大的系统也就解决完毕了。 在分解过程中会分解出很多类似的小问题,他们的解决方式是一样的,因而可以把这些小问题,抽象出来,只需要给出一个实现即可,凡是需要用到该问题时直接使用即可。 案例 日期运算 给定日期由年、月、日(三个整数,年的取值在1970-2050之间)组成,完成以下功能: (1)判断给定日期的合法性; (2)计算两个日期相差的天数; (3)计算一个日期加上一个整数后对应的日期; (4)计算一个日期减去一个整数后对应的日期; (5)计算一个日期是星期几。 针对这个问题,很自然想到本例分解为5个模块,如图14.1所示。 图14.1 日期计算功能分解图 仔细分析每一个模块的功能的具体流程: 1. 判断给定日期的合法性: 首先判断给定年份是否位于1970到2050之间。然后判断给定月份是否在1到12之间。最后判定日的合法性。判定日的合法性与月份有关,还涉及到闰年问题。当月份为1、3、5、7、8、10、12时,日的有效范围为1到31;当月份为4、6、9、11时,日的有效范围为1到30;当月份为2时,若年为闰年,日的有效范围为1到29;当月份为2时,若年不为闰年,日的有效范围为1到28。 图14.2 日期合法性判定盒图 判断日期合法性要要用到判断年份是否为闰年,在图14.2中并未给出实现方法,在图14.3中给出。 图14.3 闰年判定盒图 2. 计算两个日期相差的天数 计算日期A(yearA、monthA、dayA)和日期B(yearB、monthB、dayB)相差天数,假定A小于B并且A和B不在同一年份,很自然想到把天数分成3段: 2.1 A日期到A所在年份12月31日的天数; 2.2 A之后到B之前的整年的天数(A、B相邻年份这部分没有); 2.3 B日期所在年份1月1日到B日期的天数。 图14.4 日期差分段计算图 若A小于B并且A和B在同一年份,直接在年内计算。 2.1和2.3都是计算年内的一段时间,并且涉及到闰年问题。2.2计算整年比较容易,但是也要涉及到闰年问题。这里先不讨论具体流程,分析完下面几个模块后再讨论。 3. 计算一个日期加上一个整数天数后对应的日期 计算日期A(yearA、monthA、dayA)加上一个整数天数days对应的日期, 若days小于A日期到A所在年份12月31日的天数 则 对应结果日期在本年中计算,yearA不变。 否则 yearA加days。 若天数剩下的的部分够整年(闰年问题),则循环 yearA加days; days去掉一年天数; 对days剩下的不够一年的天数,在该年计算对应日期。 图14.5 日期加整数分段计算图 4. 计算一个日期减去一个整数天数后对应的日期 计算日期A(yearA、monthA、dayA)减去一个整数天数days对应的日期, 若days小于A所在年份1月1日到A日期的天数 则 对应结果日期在本年中计算,yearA不变。 否则 yearA减1。 若days剩下的的部分够整年(闰年问题),则循环 yearA减1; days去掉一年天数; 对days剩下的不够一年的天数,在该年计算对应日期。 图14.6 日期减整数分段计算图 5. 计算一个日期是星期几 计算日期A(yearA、monthA、dayA)为星期几,需要找到一个参照的日期B,只需要知道日期B为星期几,然后计算出A和B相差的天数,就很容易计算出A为星期几。此处又需要用到计算两个日期的差。 通过上述分析,发现到处都在计算一段日期天数,这种一段日期天数分为3种:年内1月1日到某日期的天数(年内的前半段);年内某日期到12月31日的天数(年内的后半段);整年的天数。只有整年天数容易计算,其他两种较为复杂,能不能回避呢? 对于日期A和B的差,可以选定日期C(1970年1月1日),计算C到A的天数CA,再计算C到B的天数CB,则CB减CA为A到B的天数。而对C到A,只需要计算整年(因为C为1月1日)加上A的年内前半段,C到B同理。这样就回避掉了计算年内后半段的问题。把从选定日期C(1970年1月1日)到某日期A的天数用函数dateToDays(A)来描述,有了该函数,则问题2和5都很容易解决了。对于问题3和4,可以把日期A通过dateToDays函数转化为天数,再加减一个整数,变成一个新的天数,只需要再定义一个函数daysToDate(days)把天数转换为从1970年1月1日经过该天数对应的日期即可。daysToDate函数也只需要处理若干整年(因为从1970年1月1日起)和结果年份内的前半段。 总结一下,本例共抽象出3个公用的函数: leap:判断闰年函数。 dateToDays:把一个日期转换成从1970年1月1日到该日期的天数。 daysToDate:把天数转换成从1970年1月1日经过该天数所到的日期。 有了这几个函数,解决本例中的问题可以这样做: 模块2. 计算日期A(yearA、monthA、dayA)和日期B(yearB、monthB、dayB)相差天数: dateToDays(B)- dateToDays(A) 模块3. 计算日期A(yearA、monthA、dayA)加上一个整数天数days对应的日期: daysToDate (dateToDays(A)+ days) 模块4. 计算日期A(yearA、monthA、dayA)减去一个整数天数days对应的日期: daysToDate (dateToDays(A)- days) 模块5. 计算日期A(yearA、monthA、dayA)为星期几: (dateToDays(A)+Offset-2)%7+1 Offset是1970年1月1日星期值,值为4。 dateToDays函数用来计算1970年1月1日到A(yearA、monthA、dayA)的天数,结果存放在sum中。二维数组m的0行和1行分别存放闰年和平年每个月的天数。计算过程分为3部分: (1) 1970年到yearA-1年循环,把每年的天数累加到sum中。注意,闰年时leap返回1,古润年时多加一天。 (2) 在yearA年份,从1月到monthA-1月循环,把每月的天数累加到sum中。注意,闰年时,每月天数在数组m的0行中,平年时,每月天数在数组m的1行中。 (3) 把dayA累加到sum中。 例如对日期1972年2月5日。第一步把从1970年到1971每年的天数累加到sum中,sum的值为730;第二步把从1972年1月到1972年1月每月的天数累加到sum中,sum的值为761;第三步把5日累加到sum中,sum的值为766。详细流程如盒图14.7所示。 图14.7 日期转换为天数NS盒图 daysToDate函数用来计算从1970年1月1日起经过days天后对应的日期A(yearA、monthA、dayA)。二维数组m的0行和1行分别存放闰年和平年每个月的天数。计算过程分为3部分: (1) 结果年份yearA的计算,yearA初值为1970,当days大于yearA年的天数时循环:在days中减去yearA的天数,并且把yearA增加1。其中,yearA的天数要考虑闰年问题。 (2) 结果月份monthA的计算,monthA初值为1,此时days已经小于yearA年的天数。days大于monthA月的天数时循环:在days中减去monthA月的天数,并且把monthA增加1。其中,闰年时,每月天数在数组m的0行中,平年时,每月天数在数组m的1行中。 (3)结果日dayA的计算,此时days已经小于yearA年month月的天数。dayA的值即为days。 例如把天数days(766)转为日期,yearA的初值为1970,monthA的初值为1。 第一步,days减去1970年的365天days变为401,yearA变为1971;days再减去1971年的365天days变为36,yearA变为1972;此时days的36不够1972年的天数,故年份结果为1972。 第二步,days减去1972年1月的31天days变为5,monthA变为2;此时days的5不够1972年2月的天数,故月份结果为2。 第三步,日的值即为day,也就是dayA的值为5。 详细流程如盒图14.8所示。 图14.8 天数转换为日期NS盒图
展开阅读全文

开通  VIP会员、SVIP会员  优惠大
下载10份以上建议开通VIP会员
下载20份以上建议开通SVIP会员


开通VIP      成为共赢上传
相似文档                                   自信AI助手自信AI助手

当前位置:首页 > 百科休闲 > 其他

移动网页_全站_页脚广告1

关于我们      便捷服务       自信AI       AI导航        抽奖活动

©2010-2025 宁波自信网络信息技术有限公司  版权所有

客服电话:4009-655-100  投诉/维权电话:18658249818

gongan.png浙公网安备33021202000488号   

icp.png浙ICP备2021020529号-1  |  浙B2-20240490  

关注我们 :微信公众号    抖音    微博    LOFTER 

客服