提交 154ada10 编写于 作者: R rriggs

8025718: Enhance error messages for parsing

Summary: Add values and types to exception messages
Reviewed-by: lancea
Contributed-by: scolebourne@joda.org
上级 36fbe17a
......@@ -187,7 +187,12 @@ public enum DayOfWeek implements TemporalAccessor, TemporalAdjuster {
if (temporal instanceof DayOfWeek) {
return (DayOfWeek) temporal;
}
return of(temporal.get(DAY_OF_WEEK));
try {
return of(temporal.get(DAY_OF_WEEK));
} catch (DateTimeException ex) {
throw new DateTimeException("Unable to obtain DayOfWeek from TemporalAccessor: " +
temporal + " of type " + temporal.getClass().getName(), ex);
}
}
//-----------------------------------------------------------------------
......
......@@ -366,9 +366,14 @@ public final class Instant
return (Instant) temporal;
}
Objects.requireNonNull(temporal, "temporal");
long instantSecs = temporal.getLong(INSTANT_SECONDS);
int nanoOfSecond = temporal.get(NANO_OF_SECOND);
return Instant.ofEpochSecond(instantSecs, nanoOfSecond);
try {
long instantSecs = temporal.getLong(INSTANT_SECONDS);
int nanoOfSecond = temporal.get(NANO_OF_SECOND);
return Instant.ofEpochSecond(instantSecs, nanoOfSecond);
} catch (DateTimeException ex) {
throw new DateTimeException("Unable to obtain Instant from TemporalAccessor: " +
temporal + " of type " + temporal.getClass().getName());
}
}
//-----------------------------------------------------------------------
......
......@@ -356,7 +356,8 @@ public final class LocalDate
Objects.requireNonNull(temporal, "temporal");
LocalDate date = temporal.query(TemporalQuery.localDate());
if (date == null) {
throw new DateTimeException("Unable to obtain LocalDate from TemporalAccessor: " + temporal.getClass());
throw new DateTimeException("Unable to obtain LocalDate from TemporalAccessor: " +
temporal + " of type " + temporal.getClass().getName());
}
return date;
}
......
......@@ -449,7 +449,8 @@ public final class LocalDateTime
LocalTime time = LocalTime.from(temporal);
return new LocalDateTime(date, time);
} catch (DateTimeException ex) {
throw new DateTimeException("Unable to obtain LocalDateTime from TemporalAccessor: " + temporal.getClass(), ex);
throw new DateTimeException("Unable to obtain LocalDateTime from TemporalAccessor: " +
temporal + " of type " + temporal.getClass().getName(), ex);
}
}
......
......@@ -397,7 +397,8 @@ public final class LocalTime
Objects.requireNonNull(temporal, "temporal");
LocalTime time = temporal.query(TemporalQuery.localTime());
if (time == null) {
throw new DateTimeException("Unable to obtain LocalTime from TemporalAccessor: " + temporal.getClass());
throw new DateTimeException("Unable to obtain LocalTime from TemporalAccessor: " +
temporal + " of type " + temporal.getClass().getName());
}
return time;
}
......
......@@ -217,7 +217,8 @@ public enum Month implements TemporalAccessor, TemporalAdjuster {
}
return of(temporal.get(MONTH_OF_YEAR));
} catch (DateTimeException ex) {
throw new DateTimeException("Unable to obtain Month from TemporalAccessor: " + temporal.getClass(), ex);
throw new DateTimeException("Unable to obtain Month from TemporalAccessor: " +
temporal + " of type " + temporal.getClass().getName(), ex);
}
}
......
......@@ -266,7 +266,8 @@ public final class MonthDay
}
return of(temporal.get(MONTH_OF_YEAR), temporal.get(DAY_OF_MONTH));
} catch (DateTimeException ex) {
throw new DateTimeException("Unable to obtain MonthDay from TemporalAccessor: " + temporal.getClass(), ex);
throw new DateTimeException("Unable to obtain MonthDay from TemporalAccessor: " +
temporal + " of type " + temporal.getClass().getName(), ex);
}
}
......
......@@ -347,8 +347,8 @@ public final class OffsetDateTime
if (temporal instanceof OffsetDateTime) {
return (OffsetDateTime) temporal;
}
ZoneOffset offset = ZoneOffset.from(temporal);
try {
ZoneOffset offset = ZoneOffset.from(temporal);
try {
LocalDateTime ldt = LocalDateTime.from(temporal);
return OffsetDateTime.of(ldt, offset);
......@@ -357,7 +357,8 @@ public final class OffsetDateTime
return OffsetDateTime.ofInstant(instant, offset);
}
} catch (DateTimeException ex) {
throw new DateTimeException("Unable to obtain OffsetDateTime from TemporalAccessor: " + temporal.getClass(), ex);
throw new DateTimeException("Unable to obtain OffsetDateTime from TemporalAccessor: " +
temporal + " of type " + temporal.getClass().getName(), ex);
}
}
......
......@@ -284,7 +284,8 @@ public final class OffsetTime
ZoneOffset offset = ZoneOffset.from(temporal);
return new OffsetTime(time, offset);
} catch (DateTimeException ex) {
throw new DateTimeException("Unable to obtain OffsetTime from TemporalAccessor: " + temporal.getClass(), ex);
throw new DateTimeException("Unable to obtain OffsetTime from TemporalAccessor: " +
temporal + " of type " + temporal.getClass().getName(), ex);
}
}
......
......@@ -249,7 +249,8 @@ public final class Year
}
return of(temporal.get(YEAR));
} catch (DateTimeException ex) {
throw new DateTimeException("Unable to obtain Year from TemporalAccessor: " + temporal.getClass(), ex);
throw new DateTimeException("Unable to obtain Year from TemporalAccessor: " +
temporal + " of type " + temporal.getClass().getName(), ex);
}
}
......
......@@ -252,7 +252,8 @@ public final class YearMonth
}
return of(temporal.get(YEAR), temporal.get(MONTH_OF_YEAR));
} catch (DateTimeException ex) {
throw new DateTimeException("Unable to obtain YearMonth from TemporalAccessor: " + temporal.getClass(), ex);
throw new DateTimeException("Unable to obtain YearMonth from TemporalAccessor: " +
temporal + " of type " + temporal.getClass().getName(), ex);
}
}
......
......@@ -504,7 +504,8 @@ public abstract class ZoneId implements Serializable {
public static ZoneId from(TemporalAccessor temporal) {
ZoneId obj = temporal.query(TemporalQuery.zone());
if (obj == null) {
throw new DateTimeException("Unable to obtain ZoneId from TemporalAccessor: " + temporal.getClass());
throw new DateTimeException("Unable to obtain ZoneId from TemporalAccessor: " +
temporal + " of type " + temporal.getClass().getName());
}
return obj;
}
......
......@@ -336,7 +336,8 @@ public final class ZoneOffset
Objects.requireNonNull(temporal, "temporal");
ZoneOffset offset = temporal.query(TemporalQuery.offset());
if (offset == null) {
throw new DateTimeException("Unable to obtain ZoneOffset from TemporalAccessor: " + temporal.getClass());
throw new DateTimeException("Unable to obtain ZoneOffset from TemporalAccessor: " +
temporal + " of type " + temporal.getClass().getName());
}
return offset;
}
......
......@@ -553,7 +553,8 @@ public final class ZonedDateTime
return of(ldt, zone);
}
} catch (DateTimeException ex) {
throw new DateTimeException("Unable to create ZonedDateTime from TemporalAccessor: " + temporal.getClass(), ex);
throw new DateTimeException("Unable to obtain ZonedDateTime from TemporalAccessor: " +
temporal + " of type " + temporal.getClass().getName(), ex);
}
}
......
......@@ -588,11 +588,23 @@ final class Parsed implements TemporalAccessor {
//-----------------------------------------------------------------------
@Override
public String toString() {
String str = fieldValues.toString() + "," + chrono + "," + zone;
StringBuilder buf = new StringBuilder(64);
buf.append(fieldValues).append(',').append(chrono);
if (zone != null) {
buf.append(',').append(zone);
}
if (date != null || time != null) {
str += " resolved to " + date + "," + time;
buf.append(" resolved to ");
if (date != null) {
buf.append(date);
if (time != null) {
buf.append('T').append(time);
}
} else {
buf.append(time);
}
}
return str;
return buf.toString();
}
}
......@@ -61,12 +61,32 @@ package test.java.time.format;
import static java.time.temporal.ChronoField.DAY_OF_MONTH;
import static org.testng.Assert.assertSame;
import static org.testng.Assert.assertTrue;
import static org.testng.Assert.fail;
import java.time.format.DecimalStyle;
import java.time.DateTimeException;
import java.time.DayOfWeek;
import java.time.Instant;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.LocalTime;
import java.time.Month;
import java.time.MonthDay;
import java.time.OffsetDateTime;
import java.time.OffsetTime;
import java.time.Year;
import java.time.YearMonth;
import java.time.ZoneId;
import java.time.ZoneOffset;
import java.time.ZonedDateTime;
import java.time.chrono.ThaiBuddhistChronology;
import java.time.format.DateTimeFormatter;
import java.time.format.DateTimeFormatterBuilder;
import java.time.format.DecimalStyle;
import java.time.format.SignStyle;
import java.time.temporal.TemporalAccessor;
import java.util.Locale;
import java.util.function.Function;
import org.testng.annotations.Test;
......@@ -87,4 +107,93 @@ public class TestDateTimeFormatter {
assertSame(test, base);
}
@Test
public void test_parse_errorMessage() throws Exception {
assertGoodErrorDate(DayOfWeek::from, "DayOfWeek");
assertGoodErrorDate(Month::from, "Month");
assertGoodErrorDate(YearMonth::from, "YearMonth");
assertGoodErrorDate(MonthDay::from, "MonthDay");
assertGoodErrorDate(LocalDate::from, "LocalDate");
assertGoodErrorDate(LocalTime::from, "LocalTime");
assertGoodErrorDate(LocalDateTime::from, "LocalDateTime");
assertGoodErrorDate(OffsetTime::from, "OffsetTime");
assertGoodErrorDate(OffsetDateTime::from, "OffsetDateTime");
assertGoodErrorDate(ZonedDateTime::from, "ZonedDateTime");
assertGoodErrorDate(Instant::from, "Instant");
assertGoodErrorDate(ZoneOffset::from, "ZoneOffset");
assertGoodErrorDate(ZoneId::from, "ZoneId");
assertGoodErrorDate(ThaiBuddhistChronology.INSTANCE::date, "");
assertGoodErrorTime(DayOfWeek::from, "DayOfWeek");
assertGoodErrorTime(Month::from, "Month");
assertGoodErrorTime(Year::from, "Year");
assertGoodErrorTime(YearMonth::from, "YearMonth");
assertGoodErrorTime(MonthDay::from, "MonthDay");
assertGoodErrorTime(LocalDate::from, "LocalDate");
assertGoodErrorTime(LocalTime::from, "LocalTime");
assertGoodErrorTime(LocalDateTime::from, "LocalDateTime");
assertGoodErrorTime(OffsetTime::from, "OffsetTime");
assertGoodErrorTime(OffsetDateTime::from, "OffsetDateTime");
assertGoodErrorTime(ZonedDateTime::from, "ZonedDateTime");
assertGoodErrorTime(Instant::from, "Instant");
assertGoodErrorTime(ZoneOffset::from, "ZoneOffset");
assertGoodErrorTime(ZoneId::from, "ZoneId");
assertGoodErrorTime(ThaiBuddhistChronology.INSTANCE::date, "");
}
private void assertGoodErrorDate(Function<TemporalAccessor, Object> function, String expectedText) {
DateTimeFormatter f = DateTimeFormatter.ofPattern("yyyy-mm-dd");
TemporalAccessor temporal = f.parse("2010-06-30");
try {
function.apply(temporal);
fail("Should have failed");
} catch (DateTimeException ex) {
String msg = ex.getMessage();
assertTrue(msg.contains(expectedText), msg);
assertTrue(msg.contains("Year"), msg);
assertTrue(msg.contains("MinuteOfHour"), msg);
assertTrue(msg.contains("DayOfMonth"), msg);
}
}
private void assertGoodErrorTime(Function<TemporalAccessor, Object> function, String expectedText) {
DateTimeFormatter f = DateTimeFormatter.ofPattern("HH:MM:ss");
TemporalAccessor temporal = f.parse("11:30:56");
try {
function.apply(temporal);
fail("Should have failed");
} catch (DateTimeException ex) {
String msg = ex.getMessage();
assertTrue(msg.contains(expectedText), msg);
assertTrue(msg.contains("HourOfDay"), msg);
assertTrue(msg.contains("MonthOfYear"), msg);
assertTrue(msg.contains("SecondOfMinute"), msg);
}
}
@Test
public void test_parsed_toString_resolvedTime() {
DateTimeFormatter f = DateTimeFormatter.ofPattern("HH:mm:ss");
TemporalAccessor temporal = f.parse("11:30:56");
String msg = temporal.toString();
assertTrue(msg.contains("11:30:56"), msg);
}
@Test
public void test_parsed_toString_resolvedDate() {
DateTimeFormatter f = DateTimeFormatter.ofPattern("yyyy-MM-dd");
TemporalAccessor temporal = f.parse("2010-06-30");
String msg = temporal.toString();
assertTrue(msg.contains("2010-06-30"), msg);
}
@Test
public void test_parsed_toString_resolvedDateTime() {
DateTimeFormatter f = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
TemporalAccessor temporal = f.parse("2010-06-30 11:30:56");
String msg = temporal.toString();
assertTrue(msg.contains("2010-06-30"), msg);
assertTrue(msg.contains("11:30:56"), msg);
}
}
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册