File: src/main/java/org/joda/time/Period.java
Issue: none standard PeriodType without year throws exception
Hi.
I tried to get a Period only for months and weeks with following code:
Period p = new Period(new DateTime(startDate.getTime()), new DateTime(endDate.getTime()), PeriodType.forFields(new DurationFieldType[]{DurationFieldType.months(), DurationFieldType.weeks()})).normalizedStandard(PeriodType.forFields(new DurationFieldType[]{DurationFieldType.months(), DurationFieldType.weeks()}));
return p.getMonths();
This throws following exception:
 10-17 14:35:50.999: E/AndroidRuntime(1350): java.lang.UnsupportedOperationException: Field is not supported
 10-17 14:35:50.999: E/AndroidRuntime(1350): at org.joda.time.PeriodType.setIndexedField(PeriodType.java:690)
 10-17 14:35:50.999: E/AndroidRuntime(1350): at org.joda.time.Period.withYears(Period.java:896) 10-17
 14:35:50.999: E/AndroidRuntime(1350): at org.joda.time.Period.normalizedStandard(Period.java:1630)

Even removing the year component with .withYearsRemoved() throws the same exception:
this works:
Period p = new Period(new DateTime(startDate.getTime()), new DateTime(endDate.getTime()), PeriodType.standard()).normalizedStandard(PeriodType.standard());
return p.getMonths();
this fails:
Period p = new Period(new DateTime(startDate.getTime()), new DateTime(endDate.getTime()), PeriodType.standard().withYearsRemoved()).normalizedStandard(PeriodType.standard().withYearsRemoved());
return p.getMonths();

Buggy code:
public Period normalizedStandard(PeriodType type) {
    type = DateTimeUtils.getPeriodType(type);
    long millis = getMillis();  // no overflow can happen, even with Integer.MAX_VALUEs
    millis += (((long) getSeconds()) * ((long) DateTimeConstants.MILLIS_PER_SECOND));
    millis += (((long) getMinutes()) * ((long) DateTimeConstants.MILLIS_PER_MINUTE));
    millis += (((long) getHours()) * ((long) DateTimeConstants.MILLIS_PER_HOUR));
    millis += (((long) getDays()) * ((long) DateTimeConstants.MILLIS_PER_DAY));
    millis += (((long) getWeeks()) * ((long) DateTimeConstants.MILLIS_PER_WEEK));
    Period result = new Period(millis, type, ISOChronology.getInstanceUTC());
    int years = getYears();
    int months = getMonths();
    if (years != 0 || months != 0) {
        years = FieldUtils.safeAdd(years, months / 12);
        months = months % 12;
        if (years != 0) {
            result = result.withYears(years);
        }
        if (months != 0) {
            result = result.withMonths(months);
        }
    }
    return result;
}

Fixed code:
public Period normalizedStandard(PeriodType type) {
    type = DateTimeUtils.getPeriodType(type);
    long millis = getMillis();  // no overflow can happen, even with Integer.MAX_VALUEs
    millis += (((long) getSeconds()) * ((long) DateTimeConstants.MILLIS_PER_SECOND));
    millis += (((long) getMinutes()) * ((long) DateTimeConstants.MILLIS_PER_MINUTE));
    millis += (((long) getHours()) * ((long) DateTimeConstants.MILLIS_PER_HOUR));
    millis += (((long) getDays()) * ((long) DateTimeConstants.MILLIS_PER_DAY));
    millis += (((long) getWeeks()) * ((long) DateTimeConstants.MILLIS_PER_WEEK));
    Period result = new Period(millis, type, ISOChronology.getInstanceUTC());
    int years = getYears();
    int months = getMonths();
    if (years != 0 || months != 0) {
        long totalMonths = years * 12L + months;
        if (type.isSupported(DurationFieldType.YEARS_TYPE)) {
            int normalizedYears = FieldUtils.safeToInt(totalMonths / 12);
            result = result.withYears(normalizedYears);
            totalMonths = totalMonths - (normalizedYears * 12);
        }
        if (type.isSupported(DurationFieldType.MONTHS_TYPE)) {
            int normalizedMonths = FieldUtils.safeToInt(totalMonths);
            result = result.withMonths(normalizedMonths);
            totalMonths = totalMonths - normalizedMonths;
        }
        if (totalMonths != 0) {
            throw new UnsupportedOperationException("Unable to normalize as PeriodType is missing either years or months but period has a month/year amount: " + toString());
        }
    }
    return result;
}