有问题的代码:
/**
* 获取每月的最后那天的数值
*
* @param year
* @param month 1月传0,2月传1,依次类推
* @return
*/
public static int getActualMaximum(int year, int month) {
Calendar cal = Calendar.getInstance();
cal.set(Calendar.YEAR, year);
cal.set(Calendar.MONTH, month);
return cal.getActualMaximum(Calendar.DAY_OF_MONTH);
}
今天(2018/3/30)却发现一个小问题,当我要拿2018年2月的最后一天是,返回31。
原因解析:
原来是因为这样子的写法,改calendar为2018/2/30号,又没有这么一天所以Calender跳到了3月。
自然就返回了31。
解决方法1:
/**
* 获取每月的最后那天的数值
*
* @param year
* @param month 1月传0,2月传1,依次类推
* @return
*/
public static int getActualMaximum(int year, int month) {
Calendar cal = Calendar.getInstance();
cal.set(Calendar.YEAR, year);
cal.set(Calendar.MONTH, month);
// add code here
cal.set(Calendar.DATE, 1);
return cal.getActualMaximum(Calendar.DAY_OF_MONTH);
}
原因解析:
Calendar类在set的时候,并不会立即生效,只有在get的时候才会生效
解决方法2:
在实例化Calendar类之后,要先调用clear()方法清空缓存。
/**
* 获取每月的最后那天的数值
*
* @param year
* @param month 1月传0,2月传1,依次类推
* @return
*/
public static int getActualMaximum(int year, int month) {
Calendar cal = Calendar.getInstance();
cal.clear();
cal.set(Calendar.YEAR, year);
cal.set(Calendar.MONTH, month);
return cal.getActualMaximum(Calendar.DAY_OF_MONTH);
}
/**
* Field number for <code>get</code> and <code>set</code> indicating the
* month. This is a calendar-specific value. The first month of
* the year in the Gregorian and Julian calendars is
* <code>JANUARY</code> which is 0; the last depends on the number
* of months in a year.
*
* @see #JANUARY
* @see #FEBRUARY
* @see #MARCH
* @see #APRIL
* @see #MAY
* @see #JUNE
* @see #JULY
* @see #AUGUST
* @see #SEPTEMBER
* @see #OCTOBER
* @see #NOVEMBER
* @see #DECEMBER
* @see #UNDECIMBER
*/
public final static int MONTH = 2;
java.util.Calendar#DAY_OF_MONTH
/**
* Field number for <code>get</code> and <code>set</code> indicating the
* day of the month. This is a synonym for <code>DATE</code>.
* The first day of the month has value 1.
*
* @see #DATE
*/
public final static int DAY_OF_MONTH = 5;
java.util.Calendar#getActualMaximum 获取指定 calendar field的最大值。
/**
* Returns the maximum value that the specified calendar field
* could have, given the time value of this
* <code>Calendar</code>. For example, the actual maximum value of
* the <code>MONTH</code> field is 12 in some years, and 13 in
* other years in the Hebrew calendar system.
*
* <p>The default implementation of this method uses an iterative
* algorithm to determine the actual maximum value for the
* calendar field. Subclasses should, if possible, override this
* with a more efficient implementation.
*
* @param field the calendar field
* @return the maximum of the given calendar field for the time
* value of this <code>Calendar</code>
* @see #getMinimum(int)
* @see #getMaximum(int)
* @see #getGreatestMinimum(int)
* @see #getLeastMaximum(int)
* @see #getActualMinimum(int)
* @since 1.2
*/
public int getActualMaximum(int field) {
int fieldValue = getLeastMaximum(field);
int endValue = getMaximum(field);
// if we know that the maximum value is always the same, just return it.
if (fieldValue == endValue) {
return fieldValue;
}
// clone the calendar so we don't mess with the real one, and set it to
// accept anything for the field values.
Calendar work = (Calendar)this.clone();
work.setLenient(true);
// if we're counting weeks, set the day of the week to Sunday. We know the
// last week of a month or year will contain the first day of the week.
if (field == WEEK_OF_YEAR || field == WEEK_OF_MONTH) {
work.set(DAY_OF_WEEK, firstDayOfWeek);
}
// now try each value from getLeastMaximum() to getMaximum() one by one until
// we get a value that normalizes to another value. The last value that
// normalizes to itself is the actual maximum for the current date
int result = fieldValue;
do {
work.set(field, fieldValue);
if (work.get(field) != fieldValue) {
break;
} else {
result = fieldValue;
fieldValue++;
}
} while (fieldValue <= endValue);
return result;
}
网友评论