我正面临着非常奇怪的问题。下面是代码,它生成一个新的日期对象:
Date result = DateUtils.setYears(new Date(), year);
result = DateUtils.setMonths(result, month);
return DateUtils.setDays(result, day);如果我传递从1到11的月份的值-一切正常,1表示1月,2-2月. 11 -11月。但是对于12,它总是失败,除非java.lang.IllegalArgumentException: MONTH例外。
当我试图传递基于0的值时,第一个0表示前一年的12月。有什么想法吗?
提前谢谢你
发布于 2015-01-20 11:55:32
方法setMonths看起来像
public static Date setMonths(Date date, int amount) {
return set(date, Calendar.MONTH, amount);
}您可以注意到,在内部,它使用来自java的Calendar.MONTH。Calendar类中的月份从0开始到12(12值是指一年中的第三个月,虽然GregorianCalendar不使用这个值,但月历是这样的)。所以当你通过0,它意味着一月,1表示二月,.11表示12月。对于无效的月份值日历类抛出
java.lang.IllegalArgumentException发布于 2015-01-20 13:22:11
我们来追踪它。
setMonths方法在DateUtils中的定义如下:
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
}getTime方法在Calendar.java中如下所示:
public final Date getTime() {
return new Date(getTimeInMillis());
}getTimeInMillis方法在Calendar.java中的定义如下:
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;
}computeTime方法在Calendar.java中是一种抽象的方法,在这种情况下是在GregorianCalendar.java中具体实现的。我只会在方法中显示可以抛出异常的语句,因为整个方法非常长。
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
.............................
.............................
}如您所见,为特定字段提供的值将与字段的预定义最小值和最大值进行比较。对于月份字段,最小值为0(1月),最大值为11 (12月)。您可以从这里验证这些值。
至于你的另一个问题,你所提供的信息对我们来说是有限的,无法给出一个具体的答案。通过实现Calendar API,如果宽大处理模式设置为false,则月份的值0应对应于1月和11日至12月。要使0月份值与12月份相对应,唯一的方法是将宽大处理模式设置为true,并将“环绕(滚动)”的日期值“包装”到12月,例如月份=0,但日期= 369。
正如上面的注释中提到的,这里最好的猜测可能是您正在以某种方式修改month的值。
https://stackoverflow.com/questions/28044504
复制相似问题