返回首页
当前位置: 主页 > Excel教程 > Excel函数教程 >

Excel Datedif函数全面解析及BUG分析(2)

时间:2013-12-09 01:44来源:Office教程学习网 www.office68.com编辑:麦田守望者


4,=Datedif(A2,B2,"MD")
此参数含义为返回时间段内的天数,忽略月和年。
虽然说“忽略”月和年,但实际上当B2的day小于A2的day时,两者的日期差为负数,需要借位相减才能得到正数。如何借位,向谁借位就涉及到了两个日期的所在月份及其年份。
此参数算法包含以下几部分:
1)当B2的day大于等于A2的day时,可直接将两者的day相减得到结果。
例如A2为2003年3月4日,B2为2004年1月9日,其中的B2的day为9,A2的day为4,则函数结果为9-4=5。
2)当B2的day小于A2的day时,以B2所在日期作为基准,将B2减去Date(B2所在年份、B2的前一个月份、A2的day)所得到的差值为结果。
例如A2为2003年3月4日,B2为2004年2月3日,则将B2减去2004年1月4日的天数差作为函数结果。假如B2的月份为1月,则其前一个月份为前一年的12月。
3)此参数在Excel 2007 SP2版本中包含bug,当满足上面第二个条件且B2日期为闰年的1月份日期时,函数结果会偏大164。这个bug在Excel2003 SP3版本中不存在,但在目前尚未发布的Excel 2010中仍有这个问题存在,只不过那个版本中的差值为113。这个莫名其妙的数值如何出现的,目前暂时没搞清楚。
4)此参数包含的另一个问题可能不能算bug,但在各个版本中都存在,由于第二条算法的原因,当A2的day为29、30、31且B2的月份为3月份时,由于B2的前一个月份即2月份中没有29号、30号、31号,Date(B2所在年份、B2的前一个月份、A2的day)会由Excel自动将这样的date转换为3月1日、3月2日、3月3日,由此产生误差会出现0和负数。对于这样一个计算两个日期差的函数来说,出现负数好像有点不太合理。
例如,A2日期为2003年5月31日,B2日期为2005年3月1日,date(2005,2,31)=2005年3月3日,因此B2与此日期相减得到结果为-2。
基于第4点的问题,个人认为有以下两种算法可能会更合理一些:
I)当day(B2)<day(A2)时,将B2与其当月1日相减+A2的月末与A2相减+1,用公式来表达就是:
=IF(DAY(B2)-DAY(A2)>=0,DAY(B2)-DAY(A2),B2-TEXT(B2,"yyyy-m-1")+DATE(YEAR(A2),MONTH(A2)+1,1)-A2)
II)当day(B2)<day(A2)时,将B2与Date(B2所在年份、B2的前一个月份、A2的day)相减,当差值小于零时取零作为结果。用公式来表达就是:
=IF(DAY(B2)-DAY(A2)>=0,DAY(B2)-DAY(A2),MAX(B2-DATE(YEAR(B2),MONTH(B2)-1,DAY(A2)),0))
当然,这两种方法只是本人的建议,仅供参考。

综合以上算法解释,这个参数在不够减的时候借位是以B2为基准的,这个参数的算法可以表示为以下的公式:
=IF(DAY(B2)-DAY(A2)>=0,DAY(B2)-DAY(A2),B2-DATE(YEAR(B2),MONTH(B2)-1,DAY(A2))+164*(TEXT(DATE(YEAR(B2),MONTH(B2)+1,29),"m-d")="2-29"))

其中包含下划线的部分是对上面第三点中提到的闰年bug的模拟。如果要排除闰年的错误,则可以使用下面的公式:
=IF(DAY(B2)-DAY(A2)>=0,DAY(B2)-DAY(A2),B2-DATE(YEAR(B2),MONTH(B2)-1,DAY(A2)))

关于这个参数算法的讨论,还在这个帖子中进行过:http://club.excelhome.net/viewthread.php?tid=357741

5,=Datedif(A2,B2,"YM")
此参数含义为返回时间段内的整月数,忽略日和年。
这里提到了“忽略”日,但实际与参数“M”一样,还是有关日期的相关计算。这个参数的算法实际上与参数“M”的算法一致,只是忽略其中年份差中所包含的月份数。

其算法可以表示为以下的公式,其中引用了Datedif函数的“M”参数方便公式编写:
=MOD(DATEDIF(A2,B2,"m"),12)

6,=Datedif(A2,B2,"YD")
此参数含义为返回时间段内的天数,忽略其中的年。
这个参数的算法比较复杂,情况比较多,简单地说包括以下几个重点:
1)当B2月份为3月份且B2的day大于等于A2的day时,两者相减是以A2的所在年份为基准的(如果够减,则以[A2的年份&B2的日期]与A2相减;如果不够减,则以[A2年份+1&B2的日期]与A2相减)
2)当B2月份为3月份且B2的day小于A2的day时,两者相减是以B2的所在年份为基准的(如果够减,则以B2与[B2的年份&A2的日期]相减;如果不够减,则以B2与[B2年份-1&A2的日期]相减)
3)当B2的月份不是3月份时,两者相减是以A2的所在年份为基准的,相减方式同第一条。
4)当B2的day小于A2的day,且B2日期是闰年的1月份日期,且B2与A2日期不直接够减时,存在着与“MD”参数类似的闰年bug,函数结果偏大164。这个bug在Excel2003的SP3中不存在,但在Excel 2010中依旧存在,且差值变为113。

综合以上算法解释,这个参数的算法可以表示为以下的公式(上面的文字不好理解,如果能看懂下面的公式则比较容易理解上述算法):
=IF(--(TEXT(B2,"!0!0-m-d"))>=--(TEXT(A2,"!0!0-m-d")),IF((DAY(B2)<DAY(A2))*(MONTH(B2)=3),B2-DATE(YEAR(B2),MONTH(A2),DAY(A2)),DATE(YEAR(A2),MONTH(B2),DAY(B2))-A2),IF((DAY(B2)<DAY(A2))*(MONTH(B2)=3),B2-DATE(YEAR(B2)-1,MONTH(A2),DAY(A2)),DATE(YEAR(A2)+1,MONTH(B2),DAY(B2))-A2+164*(TEXT(DATE(YEAR(B2),MONTH(B2)+1,29),"m-d")="2-29")*(DAY(B2)<DAY(A2))))
其中包含下划线的部分为闰年bug的模拟,如果希望排除闰年的错误,可以将这部分内容去除。
以上分析了6个参数详细算法含义,由于无法得到详细的内部运算代码,因此以上分析结论全部来源于Datedif函数公式的黑箱测试。
 

------分隔线----------------------------
标签(Tag):excel excel2007 excel2010 excel2013 excel2003 excel技巧 excel教程 excel实例教程
------分隔线----------------------------
推荐内容
猜你感兴趣