ExcelHome技术论坛

 找回密码
 免费注册

QQ登录

只需一步,快速开始

快捷登录

搜索
EH技术汇-专业的职场技能充电站 妙哉!函数段子手趣味讲函数 Excel服务器-会Excel,做管理系统 Excel Home精品图文教程库
HR薪酬管理数字化实战 Excel 2021函数公式学习大典 Excel数据透视表实战秘技 打造核心竞争力的职场宝典
300集Office 2010微视频教程 数据工作者的案头书 免费直播课集锦 ExcelHome出品 - VBA代码宝免费下载
用ChatGPT与VBA一键搞定Excel WPS表格从入门到精通 Excel VBA经典代码实践指南
查看: 47879|回复: 37

[讨论]DATEDIF函数计算月数的疑问

[复制链接]

TA的精华主题

TA的得分主题

发表于 2006-5-9 09:40 | 显示全部楼层 |阅读模式
本帖已被收录到知识树中,索引项:DATEDIF

各位大侠:
我用datedif("2006/3/31","2006/4/30","M")计算得出0而不是1
而我用datedif("2006/3/31","2006/5/31","m")=2
datedif("2006/3/31","2006/6/30","m")=2而不是3,
请问是怎么回事,直接用该函数可否解决这个问题
谢过先啦

gouweicao78:因本帖在DateDif函数的“整月”计算方面有较高的探索价值,特此修改标题!20070528。

[此贴子已经被gouweicao78于2007-5-28 20:25:03编辑过]

TA的精华主题

TA的得分主题

发表于 2006-5-13 01:23 | 显示全部楼层
[广告] VBA代码宝 - VBA编程加强工具 · VBA代码随查随用  · 内置多项VBA编程加强工具       ★ 免费下载 ★      ★使用手册

Datedif函数帮助

DATEDIF
计算两个日期之间的天数、月数或年数。提供此函数是为了与 Lotus 1-2-3 兼容。

语法

DATEDIF(start_date,end_date,unit)

Start_date 为一个日期,它代表时间段内的第一个日期或起始日期。日期有多种输入方法:带引号的文本串(例如 "2001/1/30")、系列数(例如,如果使用 1900 日期系统则 36921 代表 2001 年 1 月 30 日)或其他公式或函数的结果(例如,DATEVALUE("2001/1/30"))。有关日期系列数的详细信息,请参阅 NOW。

End_date 为一个日期,它代表时间段内的最后一个日期或结束日期。

Unit 为所需信息的返回类型。



Unit
返回
"Y" 时间段中的整年数。
"M" 时间段中的整月数。
"D" 时间段中的天数。
"MD" start_date 与 end_date 日期中天数的差。忽略日期中的月和年。
"YM" start_date 与 end_date 日期中月数的差。忽略日期中的日和年。
"YD" start_date 与 end_date 日期中天数的差。忽略日期中的年。


说明

Microsoft Excel 按顺序的系列数保存日期,这样就可以对其进行计算。如果工作簿使用 1900 日期系统,则 Excel 会将 1900 年 1 月 1 日保存为系列数 1。而如果工作簿使用 1904 日期系统,则 Excel 会将 1904 年 1 月 1 日保存为系列数 0,(而将 1904 年 1 月 2 日保存为系列数 1)。例如,在 1900 日期系统中 Excel 将 1998 年 1 月 1 日保存为系列数 35796,因为该日期距离 1900 年 1 月 1 日为 35795 天。请查阅 Microsoft Excel 如何存储日期和时间。


Excel for Windows 和 Excel for Macintosh 使用不同的默认日期系统。有关详细信息,请参阅 NOW。
示例

DATEDIF("2001/1/1","2003/1/1","Y") 等于 2,即时间段中有两个整年。

DATEDIF("2001/6/1","2002/8/15","D") 等于 440,即在 2001 年 6 月 1 日和 2002 年 8 月 15 日之间有 440 天。

DATEDIF("2001/6/1","2002/8/15","YD") 等于 75,即在 6 月 1 日与 8 月 15 日之间有 75 天,忽略日期中的年。

DATEDIF("2001/6/1","2002/8/15","MD") 等于 14,即开始日期 1 和结束日期 15 之间的差,忽略日期中的年和月。

纵观Excel日期函数对日期的运算规则得出以下理解(比如Edate、Datedif等都是遵循这个规则的): 先理解“月末”——指某月的最后一天 再理解“整月”即不是按30天也不是按29天等来算,这个是一个变动的概念。
——由m月d日至m+1月d日,若m+1月没有d日,则取m+1月的“月末”算一个“整月”。 反之,倒推回来,由m月d日至m-1月d日,若m-1月没有d日,则取m-1月的月末算一个“整月”
例子:2006-1-28~31日,往后推1个月得到的都是2-28,其中2006-1-28遵循了m+1=2月d=28日的规则,而2006-1-29~31则遵循了“取月末”的规则,即因为2006年的m+1=2月没有29、30、31日,则取其月末。 用=Edate(star_date,1)验证上述规则;用Datedif(star_date,"2006-2-28","m")同样能验证这个规则。即从2006-1-28~31日至2006-2-28的Datedif(……,"m")——都算1个“整月”。
[此贴子已经被作者于2006-5-13 1:43:09编辑过]

TA的精华主题

TA的得分主题

发表于 2006-5-13 13:12 | 显示全部楼层
gou兄对datedif的“整月”算法进行了分析,但好像只限于前后相差1个月的算法(即m月与m+1月或m-1月之间的算法判断)。guo兄得出结论:“整月”即不是按30天也不是按29天等来算,这个是一个变动的概念。这句话本身不错,但取m+1月的月末作为参考我觉得还是有些偏差的。 我根据我的试验分析,得出下面一个覆盖所有月份差(包括跨年度)的算法分析: 参考附件: t652JNU6.rar (3.38 KB, 下载次数: 718) 假设初始日期2003-01-30,中止日期2003-04-28。datedif的算法是这样的: 首先,两日之间的日期差值是88天。datedif怎么判断之间的“整月”个数呢?例子是1月到4月之间的日子,算法就计算1月、2月、3月的当月整天数是否包含在这88天之内。1月份共有31天(与起始日期无关),2月份有28天,3月份有31天,三者的和31+28+31=90。前面的88天小于90天,也就是88没有满3个“整月”,而只是满了2个“整月”,所以datedif计算所得为2。 再举一个例子:2003-02-20~2003-06-19,日期差值是119,判断整月的依据是2月份天数28+3月份天数31+4月份天数30+5月份天数31=120,119小于120,也是没有满4个“整月”,所以答案为4-1=3。 再来看一个例子:2002-05-26~2003-02-28,日期差值278,5月份+6月份+7月份+8月份+9月份+10月份+11月份+12月份+1月份的天数为276,278大于276,满了前面相加的9个“整月”,答案为9。 从上面的例子可以得出下面一个结论: 首先计算前后日期之间的差值,然后以初始月到(中止月-1)之间的整月天数为计算“整月”的依据,差值大于或等于整月天数的,函数结果就是(中止月-初始月);如果差值小于整月天数,函数结果就是(中止月-初始月-1)。 再回来看guo兄的那句话:“整月”即不是按30天也不是按29天等来算,这个是一个变动的概念。这句话说对了,“整月”概念的变动就是以日期跨越的各月的整天数为依据的(不包含中止日所在月)。 上面的文字不一定好理解,我为了解释我的说明,在上面附了一个附件,大家看看里面的公式就更清楚了。
[此贴子已经被作者于2006-5-13 13:14:05编辑过]

TA的精华主题

TA的得分主题

发表于 2006-5-13 14:40 | 显示全部楼层
以下是引用[I]lytton_lee[/I]在2006-5-9 9:40:32的发言:[BR]各位大侠: 我用datedif("2006/3/31","2006/4/30","M")计算得出0而不是1 而我用datedif("2006/3/31","2006/5/31","m")=2 datedif("2006/3/31","2006/6/30","m")=2而不是3, 请问是怎么回事,直接用该函数可否解决这个问题 谢过先啦
datedif("2006/3/31","2006/4/30","M") automatically as 2006/4/30 00:00

[求助]datedif

[求助]datedif

TA的精华主题

TA的得分主题

发表于 2006-5-13 19:19 | 显示全部楼层
[广告] Excel易用宝 - 提升Excel的操作效率 · Excel / WPS表格插件       ★免费下载 ★       ★ 使用帮助

to chrisfang:2楼仅仅是我个人理解而已。尚未定论。我看了3楼的意思是“以起、止日期中的中间月份的全部天数和起止日期的间隔天数来判断满月的个数”

但我的理解是由Edate的计算想到的:

比如1、Edate("2006-1-31",1)——表示返回1月31日过1个月后的日期,返回2-28,把2006-1-31改为2006-1-28~30都是返回2-28

2、Edate("2006-5-31",-3)——表示返回5月31日的3个月之前的日期,返回2-28,把2006-5-31改为2006-5-28~30都是返回2-28

首先,我觉得Edate的“Months”参数应该也是按“满月”的意思来的吧,如果不是这一条,我的观点就推翻了;

再来看按“天数”理解的(我模拟的)——比如从2006-5-31向前推3个月,则先判断4、3、2月的天数即30+31+28=89天,用2006-5-31直接减去89得到的是2006-3-3(与Edate得到的结果不同)。当然,或许我并未吃透3楼的意思。

很高兴Chrisfang兄的讨论及wclaw兄补充了精确到时分秒的意见。

TA的精华主题

TA的得分主题

发表于 2006-5-13 20:24 | 显示全部楼层

guo兄由Edate来联系的想法没有问题,应该说两者大体上的算法是一致的。但datedif是由天数推算整月数,而edate是由整月数推算天数,正向和逆向的行为不能简单的进行比较,有时需要反过来看。可以看看我下面的解释是否合理:

Edate("2006-1-31",1),从1月往后推1个月,按照我datedif的说法,应该是计算1月份的天数31天,然后进行比较,1-28到2-28的日期差为31,29日、30日、31日到2-28都小于31,凡小于等于31天的都算作1个整月。所以28~31日算出来的结果都是2-28。如果换成1月27日,日期差为32,大于31了,所以加1个月只能到2月27日了。这就是反过来的看法。

Edate("2006-5-31",-3),从5月往前推3个月,应该是计算4月份、3月份、2月份的总天数,共89天。凡大于等于89天的都可算作3个整月(因为是倒推,所以取大于等于;上面1月例子是正推,所以取小于等于,相当于一个行减法,一个行加法)。所以5月28日~5月30日到2月28日的日期差都大于等于89天,三个月减出来的结果都一样。如果换成5月27日,日期差为88,小于89天,减3个月了就会过头了,出来2月27日了。(我没有加载edate函数,根据我的推算,应该是这个结果吧?)

上面这个就是将datedif和edate统一起来的解释算法,当然这也只是我的个人看法。而且可能其他人不是很好理解我的话,呵呵,我老婆都常常听不明白我的话[em06]。

有兴趣的朋友可以参照3楼附件的样式,套用我上面的解释同样做一个edate函数的公式解释算法出来。

[此贴子已经被作者于2006-5-13 20:27:38编辑过]

TA的精华主题

TA的得分主题

发表于 2006-5-13 21:29 | 显示全部楼层
[广告] Excel易用宝 - 提升Excel的操作效率 · Excel / WPS表格插件       ★免费下载 ★       ★ 使用帮助

呵呵,经6楼这么一解释,倒让我也觉得很有道理。再研究研究。

TA的精华主题

TA的得分主题

发表于 2006-5-14 12:05 | 显示全部楼层
More Information: By definition, a "full month" means that the day number in Date2 is >= the day ' number in Date1, or Date1 and Date2 occur on the last days of their respective ' months. A "full year" means that 12 "full months" have passed. ' In Excel, this function is an alternative to the little-known DATEDIF. DATEDIF ' usually works well, but can create strange results when a date is at month end. ' Thus, this formula: ' =DATEDIF(A1,B1,"y") & " years, " & DATEDIF(A1,B1,"ym") & " months, " & ' DATEDIF(A1,B1,"md") & " days" ' will return "0 years, 1 months, -2 days" for 31-Jan-2006 and 1-Mar-2006. ' This function will return "0 years, 1 month, 1 day" ' Chip Pearson gives a VBA equivalent in his Age() function at ' http://www.cpearson.com/excel/datedif.htm ' Unfortunately, it gives the same result in the test case above EdR2rAhJ.zip (11.89 KB, 下载次数: 125)

TA的精华主题

TA的得分主题

发表于 2006-5-14 17:26 | 显示全部楼层

谢谢楼上朋友提供的信息,不过它的作者也只是发现datedif函数的奇怪结果(strange results ),但并没有对这种现象做出解释吧?

TA的精华主题

TA的得分主题

发表于 2006-5-16 00:47 | 显示全部楼层
既然楼主想用月末来判断整月,何不用月初来判断呢?这样可能就好处理了:)
您需要登录后才可以回帖 登录 | 免费注册

本版积分规则

手机版|关于我们|联系我们|ExcelHome

GMT+8, 2024-3-29 03:29 , Processed in 0.034211 second(s), 9 queries , Gzip On, Redis On.

Powered by Discuz! X3.4

© 1999-2023 Wooffice Inc.

沪公网安备 31011702000001号 沪ICP备11019229号-2

本论坛言论纯属发表者个人意见,任何违反国家相关法律的言论,本站将协助国家相关部门追究发言者责任!     本站特聘法律顾问:李志群律师

快速回复 返回顶部 返回列表