apache.commons.lang3.DateUtils.setMonths with December



我面临着一个非常奇怪的问题。。这是代码,它生成一个新的Date对象:

Date result = DateUtils.setYears(new Date(), year);
result = DateUtils.setMonths(result, month);
return DateUtils.setDays(result, day);

如果我通过从1到11的月份的任何值-一切正常,1表示1月,2月。。。11月11日至11月。但对于12,它总是失败,java.lang.IllegalArgumentException: MONTH异常。。

当我试图传递基于0的值时,第一个0表示上一年的12月。。有什么想法吗?

提前感谢

方法setMonths看起来像

 public static Date setMonths(Date date, int amount) {
        return set(date, Calendar.MONTH, amount);
    }

您可以注意到,它在内部使用Calendar。来自java的MONTH。Calendar类中的月份从0开始到12(12值表示UNDECIMBER,即一年中的第三个月。虽然GregorianCalendar不使用此值,但阴历使用此值(。所以当你超过0时,它意味着一月,1意味着二月,。。。11表示12月。对于无效的月份值日历类,抛出

java.lang.IllegalArgumentException

让我们追踪它。

DateUtils中的setMonths方法定义如下:

public static Date setMonths(Date date, int amount) {
   return set(date, Calendar.MONTH, amount);
}

让我们来看看set方法。这些方法抛出相同的异常类,但原因不同。

private static Date set(Date date, int calendarField, int amount) {
    if (date == null) {
        throw new IllegalArgumentException("The date must not be null");
    }
    // getInstance() returns a new object, so this method is thread safe.
    Calendar c = Calendar.getInstance(); //returns an "empty" Calendar instance using default TimeZone and Local. Does not throw any exception
    c.setLenient(false); // Just set the leniency value of the Calendar.
    c.setTime(date); // set the time of the Calendar to the reference time by converting the date input into milliseconds
    c.set(calendarField, amount); // this one looks interesting, but not quite
    return c.getTime(); //returns the Date Object, possible source of the thrown Exception
}

Calendar.java中的getTime方法看起来像:

 public final Date getTime() {
     return new Date(getTimeInMillis());
 }

Calendar.java中的方法getTimeInMillis定义如下:

public long getTimeInMillis() {
   if (!isTimeSet) {
       updateTime();
   }
   return time;
}

这个方法中唯一有趣的语句是updateTime,它的定义如下:

 private void updateTime() {
     computeTime();
     // The areFieldsSet and areAllFieldsSet values are no longer
     // controlled here (as of 1.5).
     isTimeSet = true;
}

Calendar.java中的computeTime方法是一个抽象方法,在这种情况下,它在GregorianCalendar.jva中具体实现。我只显示方法中可以抛出该异常的语句,因为整个方法很长。

    protected void computeTime() {
        // In non-lenient mode, perform brief checking of calendar
        // fields which have been set externally. Through this
        // checking, the field values are stored in originalFields[]
        // to see if any of them are normalized later.
        if (!isLenient()) {
            if (originalFields == null) {
                originalFields = new int[FIELD_COUNT];
            }
            for (int field = 0; field < FIELD_COUNT; field++) {
                int value = internalGet(field);
                if (isExternallySet(field)) {
                    // Quick validation for any out of range values
                    **This is the part of the code that has thrown that Exception**
                    if (value < getMinimum(field) || value > getMaximum(field)) {
                       throw new IllegalArgumentException(getFieldName(field));
                    }
            }
            originalFields[field] = value;
        }
    //After this part, code that computes the time in milliseconds follows
   .............................
   .............................
    }

如您所见,为特定字段提供的值将与字段预定义的最小值和最大值进行比较。对于MONTH字段,最小值为0(一月(,最大值为11(十二月(。您可以从这里验证这些值。

至于你的另一个问题,你提供的信息有限,我们无法提供具体答案。通过日历API的实现,如果宽大处理模式设置为false,则该月的值0应对应1月和11至12月。0个月的值与12月相对应的唯一方法是将宽大处理模式设置为true,并且您有一个"环绕(滚动("到12月的日期值,例如month=0但day=369。

正如上面的一条评论中所提到的,这里最好的猜测是,您可能正在某个地方以某种方式修改month的值。

相关内容

  • 没有找到相关文章

最新更新