@Override
	public void add(int field, int amount) {
		// If amount == 0, do nothing even the given field is out of
        if (amount == 0) {
            return;   // Do nothing!
        }

        if (field < 0 || field >= ZONE_OFFSET) {
            throw new IllegalArgumentException();
        }
        
		switch (field) {
		case YEAR:
			if(internalGet(field) + amount > getMaximum(field) || internalGet(field) + amount < getMinimum(field))
				throw new IllegalArgumentException();
			set(field, fields[field] + amount);
			break;
		case MONTH:
			int month = internalGet(MONTH) + amount;
			int year = (month-1) / getMaximum(MONTH);
			if(amount > 0){
				//PLUS
				fields[YEAR] += year;
				if(month % getMaximum(MONTH) == 0)
					set(MONTH, DHU_AL_HIJJAH);
				else
					set(MONTH, month % getMaximum(MONTH));
			}else{
				//MINUS
				if(month > 0){
					set(MONTH, month);
				}else{
					year--;
					fields[YEAR] += year;
					set(MONTH, getMaximum(MONTH) + (month % getMaximum(MONTH)));
				}
			}
			if(internalGet(DATE) == 30 && UmmALQura.getMonthLength(internalGet(YEAR), internalGet(MONTH)) != 30)
				set(DATE, 29);
			break;
		case DAY_OF_MONTH:
			Calendar calendarDAY_OF_MONTH = toGregorianCalendar();
			calendarDAY_OF_MONTH.add(DAY_OF_MONTH, amount);
			int[] date = UmmALQura.gregorianToHijri(calendarDAY_OF_MONTH.get(YEAR), calendarDAY_OF_MONTH.get(MONTH)+1, calendarDAY_OF_MONTH.get(DATE));
			set(YEAR, date[0]);
			set(MONTH, date[1]);
			set(DAY_OF_MONTH, date[2]);
			set(DAY_OF_WEEK, date[3]);
			break;

		default:
			break;
		}
	}