提交 74c0d1a3 编写于 作者: R rriggs

8025720: Separate temporal interface layer

Summary: Remove ZoneId and Chronology from TemporalField interface
Reviewed-by: sherman
Contributed-by: scolebourne@joda.org
上级 b4599018
...@@ -262,7 +262,7 @@ final class Parsed implements TemporalAccessor { ...@@ -262,7 +262,7 @@ final class Parsed implements TemporalAccessor {
while (changedCount < 50) { while (changedCount < 50) {
for (Map.Entry<TemporalField, Long> entry : fieldValues.entrySet()) { for (Map.Entry<TemporalField, Long> entry : fieldValues.entrySet()) {
TemporalField targetField = entry.getKey(); TemporalField targetField = entry.getKey();
TemporalAccessor resolvedObject = targetField.resolve(fieldValues, chrono, zone, resolverStyle); TemporalAccessor resolvedObject = targetField.resolve(fieldValues, this, resolverStyle);
if (resolvedObject != null) { if (resolvedObject != null) {
if (resolvedObject instanceof ChronoZonedDateTime) { if (resolvedObject instanceof ChronoZonedDateTime) {
ChronoZonedDateTime czdt = (ChronoZonedDateTime) resolvedObject; ChronoZonedDateTime czdt = (ChronoZonedDateTime) resolvedObject;
......
...@@ -69,6 +69,7 @@ import static java.time.temporal.ChronoUnit.MONTHS; ...@@ -69,6 +69,7 @@ import static java.time.temporal.ChronoUnit.MONTHS;
import static java.time.temporal.ChronoUnit.WEEKS; import static java.time.temporal.ChronoUnit.WEEKS;
import static java.time.temporal.ChronoUnit.YEARS; import static java.time.temporal.ChronoUnit.YEARS;
import java.time.DateTimeException;
import java.time.Duration; import java.time.Duration;
import java.time.LocalDate; import java.time.LocalDate;
import java.time.ZoneId; import java.time.ZoneId;
...@@ -343,7 +344,7 @@ public final class IsoFields { ...@@ -343,7 +344,7 @@ public final class IsoFields {
} }
@Override @Override
public ChronoLocalDate resolve( public ChronoLocalDate resolve(
Map<TemporalField, Long> fieldValues, Chronology chronology, ZoneId zone, ResolverStyle resolverStyle) { Map<TemporalField, Long> fieldValues, TemporalAccessor partialTemporal, ResolverStyle resolverStyle) {
Long yearLong = fieldValues.get(YEAR); Long yearLong = fieldValues.get(YEAR);
Long qoyLong = fieldValues.get(QUARTER_OF_YEAR); Long qoyLong = fieldValues.get(QUARTER_OF_YEAR);
if (yearLong == null || qoyLong == null) { if (yearLong == null || qoyLong == null) {
...@@ -351,6 +352,7 @@ public final class IsoFields { ...@@ -351,6 +352,7 @@ public final class IsoFields {
} }
int y = YEAR.checkValidIntValue(yearLong); // always validate int y = YEAR.checkValidIntValue(yearLong); // always validate
long doq = fieldValues.get(DAY_OF_QUARTER); long doq = fieldValues.get(DAY_OF_QUARTER);
ensureIso(partialTemporal);
LocalDate date; LocalDate date;
if (resolverStyle == ResolverStyle.LENIENT) { if (resolverStyle == ResolverStyle.LENIENT) {
date = LocalDate.of(y, 1, 1).plusMonths(Math.multiplyExact(Math.subtractExact(qoyLong, 1), 3)); date = LocalDate.of(y, 1, 1).plusMonths(Math.multiplyExact(Math.subtractExact(qoyLong, 1), 3));
...@@ -464,7 +466,7 @@ public final class IsoFields { ...@@ -464,7 +466,7 @@ public final class IsoFields {
} }
@Override @Override
public ChronoLocalDate resolve( public ChronoLocalDate resolve(
Map<TemporalField, Long> fieldValues, Chronology chronology, ZoneId zone, ResolverStyle resolverStyle) { Map<TemporalField, Long> fieldValues, TemporalAccessor partialTemporal, ResolverStyle resolverStyle) {
Long wbyLong = fieldValues.get(WEEK_BASED_YEAR); Long wbyLong = fieldValues.get(WEEK_BASED_YEAR);
Long dowLong = fieldValues.get(DAY_OF_WEEK); Long dowLong = fieldValues.get(DAY_OF_WEEK);
if (wbyLong == null || dowLong == null) { if (wbyLong == null || dowLong == null) {
...@@ -472,6 +474,7 @@ public final class IsoFields { ...@@ -472,6 +474,7 @@ public final class IsoFields {
} }
int wby = WEEK_BASED_YEAR.range().checkValidIntValue(wbyLong, WEEK_BASED_YEAR); // always validate int wby = WEEK_BASED_YEAR.range().checkValidIntValue(wbyLong, WEEK_BASED_YEAR); // always validate
long wowby = fieldValues.get(WEEK_OF_WEEK_BASED_YEAR); long wowby = fieldValues.get(WEEK_OF_WEEK_BASED_YEAR);
ensureIso(partialTemporal);
LocalDate date = LocalDate.of(wby, 1, 4); LocalDate date = LocalDate.of(wby, 1, 4);
if (resolverStyle == ResolverStyle.LENIENT) { if (resolverStyle == ResolverStyle.LENIENT) {
long dow = dowLong; // unvalidated long dow = dowLong; // unvalidated
...@@ -568,6 +571,12 @@ public final class IsoFields { ...@@ -568,6 +571,12 @@ public final class IsoFields {
return Chronology.from(temporal).equals(IsoChronology.INSTANCE); return Chronology.from(temporal).equals(IsoChronology.INSTANCE);
} }
private static void ensureIso(TemporalAccessor temporal) {
if (isIso(temporal) == false) {
throw new DateTimeException("Resolve requires IsoChronology");
}
}
private static ValueRange getWeekRange(LocalDate date) { private static ValueRange getWeekRange(LocalDate date) {
int wby = getWeekBasedYear(date); int wby = getWeekBasedYear(date);
date = date.withDayOfYear(1).withYear(wby); date = date.withDayOfYear(1).withYear(wby);
......
...@@ -291,13 +291,14 @@ public final class JulianFields { ...@@ -291,13 +291,14 @@ public final class JulianFields {
//----------------------------------------------------------------------- //-----------------------------------------------------------------------
@Override @Override
public ChronoLocalDate resolve( public ChronoLocalDate resolve(
Map<TemporalField, Long> fieldValues, Chronology chronology, ZoneId zone, ResolverStyle resolverStyle) { Map<TemporalField, Long> fieldValues, TemporalAccessor partialTemporal, ResolverStyle resolverStyle) {
long value = fieldValues.remove(this); long value = fieldValues.remove(this);
Chronology chrono = Chronology.from(partialTemporal);
if (resolverStyle == ResolverStyle.LENIENT) { if (resolverStyle == ResolverStyle.LENIENT) {
return chronology.dateEpochDay(Math.subtractExact(value, offset)); return chrono.dateEpochDay(Math.subtractExact(value, offset));
} }
range().checkValidValue(value, this); range().checkValidValue(value, this);
return chronology.dateEpochDay(value - offset); return chrono.dateEpochDay(value - offset);
} }
//----------------------------------------------------------------------- //-----------------------------------------------------------------------
......
...@@ -62,7 +62,6 @@ ...@@ -62,7 +62,6 @@
package java.time.temporal; package java.time.temporal;
import java.time.DateTimeException; import java.time.DateTimeException;
import java.time.ZoneId;
import java.time.chrono.Chronology; import java.time.chrono.Chronology;
import java.time.format.ResolverStyle; import java.time.format.ResolverStyle;
import java.util.Locale; import java.util.Locale;
...@@ -338,6 +337,13 @@ public interface TemporalField { ...@@ -338,6 +337,13 @@ public interface TemporalField {
* complete {@code LocalDate}. The resolve method will remove all three * complete {@code LocalDate}. The resolve method will remove all three
* fields from the map before returning the {@code LocalDate}. * fields from the map before returning the {@code LocalDate}.
* <p> * <p>
* A partially complete temporal is used to allow the chronology and zone
* to be queried. In general, only the chronology will be needed.
* Querying items other than the zone or chronology is undefined and
* must not be relied on.
* The behavior of other methods such as {@code get}, {@code getLong},
* {@code range} and {@code isSupported} is unpredictable and the results undefined.
* <p>
* If resolution should be possible, but the data is invalid, the resolver * If resolution should be possible, but the data is invalid, the resolver
* style should be used to determine an appropriate level of leniency, which * style should be used to determine an appropriate level of leniency, which
* may require throwing a {@code DateTimeException} or {@code ArithmeticException}. * may require throwing a {@code DateTimeException} or {@code ArithmeticException}.
...@@ -350,16 +356,14 @@ public interface TemporalField { ...@@ -350,16 +356,14 @@ public interface TemporalField {
* instances that can produce a date, such as {@code EPOCH_DAY}. * instances that can produce a date, such as {@code EPOCH_DAY}.
* <p> * <p>
* Not all {@code TemporalAccessor} implementations are accepted as return values. * Not all {@code TemporalAccessor} implementations are accepted as return values.
* Implementations must accept {@code ChronoLocalDate}, {@code ChronoLocalDateTime}, * Implementations that call this method must accept {@code ChronoLocalDate},
* {@code ChronoZonedDateTime} and {@code LocalTime}. * {@code ChronoLocalDateTime}, {@code ChronoZonedDateTime} and {@code LocalTime}.
* <p>
* The zone is not normally required for resolution, but is provided for completeness.
* <p> * <p>
* The default implementation must return null. * The default implementation must return null.
* *
* @param fieldValues the map of fields to values, which can be updated, not null * @param fieldValues the map of fields to values, which can be updated, not null
* @param chronology the effective chronology, not null * @param partialTemporal the partially complete temporal to query for zone and
* @param zone the effective zone, not null * chronology; querying for other things is undefined and not recommended, not null
* @param resolverStyle the requested type of resolve, not null * @param resolverStyle the requested type of resolve, not null
* @return the resolved temporal object; null if resolving only * @return the resolved temporal object; null if resolving only
* changed the map, or no resolve occurred * changed the map, or no resolve occurred
...@@ -368,8 +372,9 @@ public interface TemporalField { ...@@ -368,8 +372,9 @@ public interface TemporalField {
* by querying a field on the temporal without first checking if it is supported * by querying a field on the temporal without first checking if it is supported
*/ */
default TemporalAccessor resolve( default TemporalAccessor resolve(
Map<TemporalField, Long> fieldValues, Chronology chronology, Map<TemporalField, Long> fieldValues,
ZoneId zone, ResolverStyle resolverStyle) { TemporalAccessor partialTemporal,
ResolverStyle resolverStyle) {
return null; return null;
} }
......
...@@ -892,7 +892,7 @@ public final class WeekFields implements Serializable { ...@@ -892,7 +892,7 @@ public final class WeekFields implements Serializable {
@Override @Override
public ChronoLocalDate resolve( public ChronoLocalDate resolve(
Map<TemporalField, Long> fieldValues, Chronology chronology, ZoneId zone, ResolverStyle resolverStyle) { Map<TemporalField, Long> fieldValues, TemporalAccessor partialTemporal, ResolverStyle resolverStyle) {
final long value = fieldValues.get(this); final long value = fieldValues.get(this);
final int newValue = Math.toIntExact(value); // broad limit makes overflow checking lighter final int newValue = Math.toIntExact(value); // broad limit makes overflow checking lighter
// first convert localized day-of-week to ISO day-of-week // first convert localized day-of-week to ISO day-of-week
...@@ -915,19 +915,20 @@ public final class WeekFields implements Serializable { ...@@ -915,19 +915,20 @@ public final class WeekFields implements Serializable {
int dow = localizedDayOfWeek(isoDow); int dow = localizedDayOfWeek(isoDow);
// build date // build date
Chronology chrono = Chronology.from(partialTemporal);
if (fieldValues.containsKey(YEAR)) { if (fieldValues.containsKey(YEAR)) {
int year = YEAR.checkValidIntValue(fieldValues.get(YEAR)); // validate int year = YEAR.checkValidIntValue(fieldValues.get(YEAR)); // validate
if (rangeUnit == MONTHS && fieldValues.containsKey(MONTH_OF_YEAR)) { // week-of-month if (rangeUnit == MONTHS && fieldValues.containsKey(MONTH_OF_YEAR)) { // week-of-month
long month = fieldValues.get(MONTH_OF_YEAR); // not validated yet long month = fieldValues.get(MONTH_OF_YEAR); // not validated yet
return resolveWoM(fieldValues, chronology, year, month, newValue, dow, resolverStyle); return resolveWoM(fieldValues, chrono, year, month, newValue, dow, resolverStyle);
} }
if (rangeUnit == YEARS) { // week-of-year if (rangeUnit == YEARS) { // week-of-year
return resolveWoY(fieldValues, chronology, year, newValue, dow, resolverStyle); return resolveWoY(fieldValues, chrono, year, newValue, dow, resolverStyle);
} }
} else if ((rangeUnit == WEEK_BASED_YEARS || rangeUnit == FOREVER) && } else if ((rangeUnit == WEEK_BASED_YEARS || rangeUnit == FOREVER) &&
fieldValues.containsKey(weekDef.weekBasedYear) && fieldValues.containsKey(weekDef.weekBasedYear) &&
fieldValues.containsKey(weekDef.weekOfWeekBasedYear)) { // week-of-week-based-year and year-of-week-based-year fieldValues.containsKey(weekDef.weekOfWeekBasedYear)) { // week-of-week-based-year and year-of-week-based-year
return resolveWBY(fieldValues, chronology, dow, resolverStyle); return resolveWBY(fieldValues, chrono, dow, resolverStyle);
} }
return null; return null;
} }
......
...@@ -927,8 +927,7 @@ public class TCKDateTimeParseResolver { ...@@ -927,8 +927,7 @@ public class TCKDateTimeParseResolver {
} }
@Override @Override
public TemporalAccessor resolve( public TemporalAccessor resolve(
Map<TemporalField, Long> fieldValues, Chronology chronology, Map<TemporalField, Long> fieldValues, TemporalAccessor partialTemporal, ResolverStyle resolverStyle) {
ZoneId zone, ResolverStyle resolverStyle) {
return LocalTime.MIDNIGHT.plusNanos(fieldValues.remove(this)); return LocalTime.MIDNIGHT.plusNanos(fieldValues.remove(this));
} }
}; };
...@@ -979,8 +978,7 @@ public class TCKDateTimeParseResolver { ...@@ -979,8 +978,7 @@ public class TCKDateTimeParseResolver {
} }
@Override @Override
public TemporalAccessor resolve( public TemporalAccessor resolve(
Map<TemporalField, Long> fieldValues, Chronology chronology, Map<TemporalField, Long> fieldValues, TemporalAccessor partialTemporal, ResolverStyle resolverStyle) {
ZoneId zone, ResolverStyle resolverStyle) {
fieldValues.remove(this); fieldValues.remove(this);
return LocalDateTime.of(2010, 6, 30, 12, 30); return LocalDateTime.of(2010, 6, 30, 12, 30);
} }
...@@ -1032,8 +1030,7 @@ public class TCKDateTimeParseResolver { ...@@ -1032,8 +1030,7 @@ public class TCKDateTimeParseResolver {
} }
@Override @Override
public TemporalAccessor resolve( public TemporalAccessor resolve(
Map<TemporalField, Long> fieldValues, Chronology chronology, Map<TemporalField, Long> fieldValues, TemporalAccessor partialTemporal, ResolverStyle resolverStyle) {
ZoneId zone, ResolverStyle resolverStyle) {
return ThaiBuddhistChronology.INSTANCE.dateNow(); return ThaiBuddhistChronology.INSTANCE.dateNow();
} }
}; };
...@@ -1082,8 +1079,7 @@ public class TCKDateTimeParseResolver { ...@@ -1082,8 +1079,7 @@ public class TCKDateTimeParseResolver {
} }
@Override @Override
public TemporalAccessor resolve( public TemporalAccessor resolve(
Map<TemporalField, Long> fieldValues, Chronology chronology, Map<TemporalField, Long> fieldValues, TemporalAccessor partialTemporal, ResolverStyle resolverStyle) {
ZoneId zone, ResolverStyle resolverStyle) {
return ZonedDateTime.of(2010, 6, 30, 12, 30, 0, 0, ZoneId.of("Europe/Paris")); return ZonedDateTime.of(2010, 6, 30, 12, 30, 0, 0, ZoneId.of("Europe/Paris"));
} }
}; };
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册