Closed jodastephen closed 11 years ago
Code review for Period
//-----------------------------------------------------------------------
/**
* Obtains an instance of {@code Period} from a temporal amount.
* <p>
* This obtains a period based on the specified amount.
* A {@code TemporalAmount} represents an amount of time, which may be
* date-based or time-based.
* This factory attempts to convert the amount to a {@code Period}.
* <p>
* The conversion loops around the set of units from the amount and uses
* the {@link ChronoUnit#YEARS YEARS}, {@link ChronoUnit#MONTHS MONTHS}
* and {@link ChronoUnit#DAYS DAYS} units to create a period.
* If any other units are found then an exception is thrown.
*
* @param amount the temporal amount to convert, not null
* @return the period, not null
* @throws DateTimeException if unable to convert to a {@code Period}
* @throws ArithmeticException if the amount of years, months or days exceeds an int
*/
public static Period from(TemporalAmount amount) {
Objects.requireNonNull(amount, "amount");
int years = 0;
int months = 0;
int days = 0;
for (TemporalUnit unit : amount.getUnits()) {
long unitAmount = amount.get(unit);
if (unit == ChronoUnit.YEARS) {
years = Math.toIntExact(unitAmount);
} else if (unit == ChronoUnit.MONTHS) {
months = Math.toIntExact(unitAmount);
} else if (unit == ChronoUnit.DAYS) {
days = Math.toIntExact(unitAmount);
} else {
throw new DateTimeException("Unit must be Years, Months or Days, but was " + unit);
}
}
return create(years, months, days);
}
tests
//-----------------------------------------------------------------------
// from(TemporalAmount)
//-----------------------------------------------------------------------
@Test
public void factory_from_Years() {
TemporalAmount years23 = new TemporalAmount() {
@Override
public long get(TemporalUnit unit) {
return 23;
}
@Override
public List<TemporalUnit> getUnits() {
return Collections.<TemporalUnit>singletonList(ChronoUnit.YEARS);
}
@Override
public Temporal addTo(Temporal temporal) {
throw new UnsupportedOperationException();
}
@Override
public Temporal subtractFrom(Temporal temporal) {
throw new UnsupportedOperationException();
}
};
assertPeriod(Period.from(years23), 23, 0, 0);
}
@Test(expectedExceptions = ArithmeticException.class)
public void factory_from_Years_tooBig() {
TemporalAmount yearsBig = new TemporalAmount() {
@Override
public long get(TemporalUnit unit) {
return ((long) (Integer.MAX_VALUE)) + 1;
}
@Override
public List<TemporalUnit> getUnits() {
return Collections.<TemporalUnit>singletonList(ChronoUnit.YEARS);
}
@Override
public Temporal addTo(Temporal temporal) {
throw new UnsupportedOperationException();
}
@Override
public Temporal subtractFrom(Temporal temporal) {
throw new UnsupportedOperationException();
}
};
Period.from(yearsBig);
}
@Test(expectedExceptions = DateTimeException.class)
public void factory_from_TemporalAmount_Duration() {
Period.from(Duration.ZERO);
}
@Test(expectedExceptions = NullPointerException.class)
public void factory_from_TemporalAmount_null() {
Period.from(null);
}
Look ok.
Fixed in Period and Duration by http://hg.openjdk.java.net/threeten/threeten/jdk/rev/651fb9ce9eb3
Reordered methods in http://hg.openjdk.java.net/threeten/threeten/jdk/rev/c46ed88b168e
Add Period/Duration from(TemporalAmount) methods that match those on date and time classes.