我在网上搜了很久,发现他们的写法不太满足要求,根本不是我想要的。
我又搜了自然月和非自然月的区别:
从每月的第一天开始到每月的最后一天为止为一个自然月,而从一个月份中的任一天开始,到下个月份的相同日期的那一天为止,也算一个月,但就不是自然月。
那么我就有点疑问了,2019-02-28和2019-05-28相差多少个非自然月?
其他人的算法是3,我觉得应该是2,因为2月最后一天是28号,5月最后一天是31号,根本没有过完,只能是2。
我的写法是判断如果日期是该月最后一天的时候,默认把日期变成31号,即2月31号(一个不存在的日期),但是31日>28日,所以认为相差不足3个月,而判断为2个月。(于是我称之为奇葩月份31进制,哈哈哈哈)
当然我不知道我这么想到底对不对,我觉得这就应该是2个月~
代码如下:
package test;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Date;
public class CalendarTest {
/**
* 判断给定日期是否为月末的一天
*
* @param date
* @return true:是|false:不是
*/
public static boolean isLastDayOfMonth(Date date) {
Calendar calendar = Calendar.getInstance();
calendar.setTime(date);
calendar.set(Calendar.DATE, (calendar.get(Calendar.DATE) + 1));
if (calendar.get(Calendar.DAY_OF_MONTH) == 1) {
return true;
}
return false;
}
/**
* 计算两个日期之间相差的月数
*
* @param date1
* @param date2
* @return
*/
public static int getMonth(Date date1, Date date2) {
int iMonth = 0;
int flag = 0;
Calendar cal1 = Calendar.getInstance();
cal1.setTime(date1);
Calendar cal2 = Calendar.getInstance();
cal2.setTime(date2);
if (cal2.equals(cal1)) {
return 0;
}
if (cal1.after(cal2)) {
Calendar temp = cal1;
cal1 = cal2;
cal2 = temp;
}
int cal1Day = cal1.get(Calendar.DAY_OF_MONTH);
int cal2Day = cal2.get(Calendar.DAY_OF_MONTH);
//如果是每月最后一天,直接赋值31号
if(isLastDayOfMonth(date1)) {
cal1Day = 31;
}
if(isLastDayOfMonth(date2)) {
cal2Day = 31;
}
if (cal2Day < cal1Day) {
flag = 1;
}
if (cal2.get(Calendar.YEAR) > cal1.get(Calendar.YEAR)) {
iMonth = ((cal2.get(Calendar.YEAR) - cal1.get(Calendar.YEAR)) * 12 + cal2.get(Calendar.MONTH) - flag)
- cal1.get(Calendar.MONTH);
} else {
iMonth = cal2.get(Calendar.MONTH) - cal1.get(Calendar.MONTH) - flag;
}
return iMonth;
}
public static void main(String[] args) throws ParseException {
SimpleDateFormat sfd = new SimpleDateFormat("yyyy-MM-dd");
Date start = sfd.parse("2019-02-28");
Date end = sfd.parse("2019-05-28");
int i = getMonth(start, end);
System.out.println(i);
}
}