我有两个日期:(YYYY-dd-mm)
1)1960-11-11
2)1986-04-02
我有以下函数,旨在计算自任意日期以来经过的月份,以上两个是我的测试条件。此函数计算月份而不考虑当前月份。也就是说,只有在完整的一个月后才添加一个月。
功能是:
public static final int months(Date date1) {// tricky
Calendar calFirst = Calendar.getInstance();
calFirst.setTime(date1);
System.out.println(""+calFirst.getTime());
Calendar calNow = Calendar.getInstance();
calNow.setTime(getCurrentDate());
System.out.println(calNow.getTime());
int m2 = calNow.get(Calendar.YEAR) * 12 + calNow.get((Calendar.MONTH));
System.out.println(calNow.get(Calendar.YEAR) * 12 );
System.out.println(calNow.get(Calendar.MONTH));
//23832
int m1 = calFirst.get(Calendar.YEAR) * 12 + (calFirst.get(Calendar.MONTH));
System.out.println(calFirst.get(Calendar.YEAR) * 12 );
System.out.println(calFirst.get(Calendar.MONTH));
//24168
return Math.abs(m2 - (m1));
}
1986-04-02 的结果:
Wed Apr 02 00:00:00 IST 1986
Wed Jan 08 00:00:00 IST 2014
24168
0
23832
3
333
哪个是正确的
1960年11月11日的结果:
Fri Nov 11 00:00:00 IST 1960
Wed Jan 08 00:00:00 IST 2014
24168
0
23520
10
638
哪个是错误的。
有什么提示我哪里出错了吗?
我认为333和638都是很好的答案...
让我解释一下:
包括 1986 年 4 月至 12 月 = 9 个月 + 27 年 + 2014 年 0 个月 = 333。
同样的想法也适用于另一个:
包含 1960 年 11 月至 12 月 = 2 个月 + 53 整年 + 2014 年 0 个月 = 638。
从这个角度来看,这两个数字都是正确的:包括第一个月,不包括上个月
为什么不使用 Joda
Period
来代替,正如这里所讨论的:
Period p = new Period(from, to, PeriodType.months().withDaysRemoved());
int months = p.getMonths() + 1;
ChronoUnit.MONTHS.between ( LocalDate.parse ( "1960-11-11" ) , LocalDate.parse ( "1986-04-02" ) )
在现代 Java 中,使用 java.time 类来完成所有日期时间工作。
对于仅日期值,请使用
java.time.LocalDate
类。
LocalDate first = LocalDate.parse ( "1960-11-11" ) ;
LocalDate second = LocalDate.parse ( "1986-04-02" ) ;
将过去的月份计算为
Period
。
Period period = Period.between ( first , second ) ;
long months = period.toTotalMonths() ;
if ( months > 12 ) { … handle expiration … }
或者使用
ChronoUnit.MONTHS
枚举对象计算过去的月份。
long months = ChronoUnit.MONTHS.between ( first , second ) ;
if ( months > 12 ) { … handle expiration … }