给人事用的c/s架构的程序,工龄开始算法为 截止日期(year*12+month)- 入厂时间(year*12+month)。后人事反馈错误一起研究了下,人事也无具体的算法,基本统计为:
一年到下一年的前一天算足年 ex:2007-1-5 到 2008-1-4 算满一年,即12个月
平闰年无所谓吧 ex:2008为闰年 2008-2-29 到2009-2-28 算一年,到2009-2-27 只能算11个月
1-30 到 2-28(平年) 或者到2-29(闰年) 反正就是要到月尾 才算一个月这样的算法想实现应该怎么做呢。是以月为当位的。
一年到下一年的前一天算足年 ex:2007-1-5 到 2008-1-4 算满一年,即12个月
平闰年无所谓吧 ex:2008为闰年 2008-2-29 到2009-2-28 算一年,到2009-2-27 只能算11个月
1-30 到 2-28(平年) 或者到2-29(闰年) 反正就是要到月尾 才算一个月这样的算法想实现应该怎么做呢。是以月为当位的。
1-1 到1-31算1month,
1-2 到2-1 算1month,
1-29到2-28算1month,
如果2月只有28,那
1-29,1-30,1-31到2月28都算1month,
如果2月有29,那
1-29到2-28不足月,到2-29才足月。
1-30,1-31到2-29算1month。我日
1.ex:2007-1-5 到 2008-1-4 算满一年,即12个月 这个好判断
2.1-29到2-28算1month, 如果2月只有28,那 1-29,1-30,1-31到2月28都算1month,
如果正好赶上某个月的结束哪天,你可以用java中的一个日期方法,可以得出这个月的最后一天。这就算一个月。
3。闰年的2月,你看看能否用2实现。如不行,就再if吧。
int b1 = 0;
Calendar crcsj =Calendar.getInstance();
Calendar cdqrq =Calendar.getInstance();
crcsj.setTime(rcsj);
cdqrq.setTime(dqrq);
int month = (cdqrq.get(Calendar.YEAR) * 12 + cdqrq.get(Calendar.MONTH)) - (crcsj.get(Calendar.YEAR) * 12 + crcsj.get(Calendar.MONTH));
crcsj.add(Calendar.MONTH, month);
if(crcsj.after(cdqrq)){
b1 = month-1;
}else b1 = month;
return b1;
}这是开始的算法,一般情况下,结束日期+1天再算基本正常
有些特殊情况,如 1-31 到 4-30 正常3个月,1-30 到4-29 只有2个月了。
还有平润年的问题。
1)先算出大概的 yearEnd*12+monthEnd -YearBegin*12-monthBegin
2)如果开始为1,结束为最后一天,+1,返回
3) 看你的举例说明,好像是看距离月末的天数,如果开始那天距离月终的天数>结束那天距离月终的天数,就-1返回。(已经看到你的举例,归纳的逻辑)对这个逻辑存疑中。
平闰年无所谓吧 ex:2008为闰年 2008-2-29 到2009-2-28 算一年,到2009-2-27 只能算11个月
1-30 到 2-28(平年) 或者到2-29(闰年) 反正就是要到月尾 才算一个月 ====>看你的这个类子又不对了。2008-1-4 比 2007-1-5 早一天算1年,为什么 2008-2-29 到 2009-2-27不算1年呢?
//初始计算
int result= dayEnd.get(Calendar.MONTH) +dayEnd.get(Calendar.YEAR)*12
-dayBegin.get(Calendar.MONTH) - dayBegin.get(Calendar.YEAR)*12;
//赋值开始和结束那天的月末
Calendar dayBeginMonthEndDay=Calendar.getInstance();
dayBeginMonthEndDay.set(dayBegin.get(Calendar.YEAR),
dayBegin.get(Calendar.MONTH),1);
dayBeginMonthEndDay.add(Calendar.MONTH,1);
dayBeginMonthEndDay.add(Calendar.DATE,-1);
Calendar dayEndMonthEndDay=Calendar.getInstance();
dayEndMonthEndDay.set(dayEnd.get(Calendar.YEAR),
dayEnd.get(Calendar.MONTH),1);
dayEndMonthEndDay.add(Calendar.MONTH,1);
dayEndMonthEndDay.add(Calendar.DATE,-1);
System.out.println(dayEndMonthEndDay.get(Calendar.DATE)-dayEnd.get(Calendar.DATE));
System.out.println(dayBeginMonthEndDay.get(Calendar.DATE)-dayBegin.get(Calendar.DATE));
//如果开始在第一天,结束在月末,加一个月
if((dayEndMonthEndDay.get(Calendar.DATE)==dayEnd.get(Calendar.DATE)) && (dayBegin.get(Calendar.DATE)==1 )){
result += 1;
return result;
}
// 如果结束那天距离月末的天数大于开始那天距离月末的天数-1
// 那么需要扣除一个月
if(dayEndMonthEndDay.get(Calendar.DATE)-dayEnd.get(Calendar.DATE)-1
>dayBeginMonthEndDay.get(Calendar.DATE)-dayBegin.get(Calendar.DATE))
{
result -= 1;
}
return result;
}
下面的部分还要加工。
1,原则上以一个月的当天到下个月的前一天算足一月,比如:1-20 ---- 2-19 算一月
2,以当月1号为起始日期,则到月末为足月,比如:1-1 ---- 1-31 ,4-1 --- 4-30
3,特殊计算方面,为2月28及2月29号,分平闰年。以07年及08年为例子(07平年08闰年)则:
比如:
2007-1-30、31及2007-2-1 --- 2007-2-28 均为满一个月
--- 2008-2-28 只算满12个月,---2008-2-29才算满13个月 ?
2008-1-30、31及2008-2-1 --- 2008-2-29 均为满一个月
--- 2009-2-28 也都为满13个月这样的话WONDERDE的代码就是很符合的了
不知道还有没有什么会产生遗漏或者错误的特例
1.初始值
2.开始在1日,结束在月底,那么就+1;
3.你的2,3可以归并成,如果结束日期不是当月最后一天(你说的特例不算特例,只是月底的日期比较特别而已),并且 结束日期+1<开始日期,那么就-1。
===>简单的理解,就是要干满开始的一个月。
所以开始月份在2月比较好(@~@)public static void main(String args[]) {
Calendar dayBegin = Calendar.getInstance();
Calendar dayEnd = Calendar.getInstance();
dayBegin.set(2007, 0, 5);
dayEnd.set(2008, 0, 4);
System.out.println(MonthDays(dayBegin, dayEnd)); //12
dayBegin.set(2008, 1, 29);
dayEnd.set(2009, 1, 28);
System.out.println(MonthDays(dayBegin, dayEnd)); //12
dayBegin.set(2008, 1, 29);
dayEnd.set(2009, 1, 27);
System.out.println(MonthDays(dayBegin, dayEnd));//11
dayBegin.set(2008, 0, 31);
dayEnd.set(2008, 1, 29);
System.out.println(MonthDays(dayBegin, dayEnd)); //1
dayBegin.set(2008, 0, 31);
dayEnd.set(2008, 1, 28);
System.out.println(MonthDays(dayBegin, dayEnd)); //0
dayBegin.set(2009, 0, 31);
dayEnd.set(2009, 1, 28);
System.out.println(MonthDays(dayBegin, dayEnd)); //1
dayBegin.set(2009, 0, 1);
dayEnd.set(2009, 0, 31);
System.out.println(MonthDays(dayBegin, dayEnd)); //1
dayBegin.set(2009, 0, 2);
dayEnd.set(2009, 1, 1);
System.out.println(MonthDays(dayBegin, dayEnd)); //1
dayBegin.set(2008, 0, 31);
dayEnd.set(2008, 3, 30);
System.out.println(MonthDays(dayBegin, dayEnd)); //3
dayBegin.set(2008, 0, 31);
dayEnd.set(2008, 3, 29);
System.out.println(MonthDays(dayBegin, dayEnd)); //2
}public static int MonthDays(Calendar dayBegin, Calendar dayEnd) {
//初始计算
int result= dayEnd.get(Calendar.MONTH) +dayEnd.get(Calendar.YEAR)*12
-dayBegin.get(Calendar.MONTH) - dayBegin.get(Calendar.YEAR)*12;
//赋值结束日期的月末
Calendar lastDayInEndMonth=Calendar.getInstance();
lastDayInEndMonth.set(dayEnd.get(Calendar.YEAR),
dayEnd.get(Calendar.MONTH),1);
lastDayInEndMonth.add(Calendar.MONTH,1);
lastDayInEndMonth.add(Calendar.DATE,-1);
// 开始在1日,结束在月末,加一个月
if((lastDayInEndMonth.get(Calendar.DATE)==dayEnd.get(Calendar.DATE))&&(dayBegin.get(Calendar.DATE)==1)){
result += 1;
}
// 如果结束的日期+1<开始日期 并且结束的日期不为月底就扣除一个月
if((dayEnd.get(Calendar.DATE)+1 < dayBegin.get(Calendar.DATE))&& !(lastDayInEndMonth.get(Calendar.DATE)==dayEnd.get(Calendar.DATE))){
result -=1;
}
return result;
}