Created
February 27, 2013 16:34
-
-
Save jodastephen/5049319 to your computer and use it in GitHub Desktop.
APPLIED: Move date resolving to Chronology
More to do here, including stricter Japanese era/year, and handling the "requested" chronology (in the formatter)
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# HG changeset patch | |
# User scolebourne | |
# Date 1361982846 0 | |
# Node ID ac8dfa77cb919d1554b78ee6fd0ae12f53ea391d | |
# Parent 27b30fa91ee0f519ad4dda6efad4b221aebf9fff | |
Move date resolution to Chronology | |
See #268 | |
diff --git a/src/share/classes/java/time/chrono/Chronology.java b/src/share/classes/java/time/chrono/Chronology.java | |
--- a/src/share/classes/java/time/chrono/Chronology.java | |
+++ b/src/share/classes/java/time/chrono/Chronology.java | |
@@ -61,6 +61,18 @@ | |
*/ | |
package java.time.chrono; | |
+import static java.time.temporal.Adjusters.nextOrSame; | |
+import static java.time.temporal.ChronoField.ALIGNED_DAY_OF_WEEK_IN_MONTH; | |
+import static java.time.temporal.ChronoField.ALIGNED_DAY_OF_WEEK_IN_YEAR; | |
+import static java.time.temporal.ChronoField.ALIGNED_WEEK_OF_MONTH; | |
+import static java.time.temporal.ChronoField.ALIGNED_WEEK_OF_YEAR; | |
+import static java.time.temporal.ChronoField.DAY_OF_MONTH; | |
+import static java.time.temporal.ChronoField.DAY_OF_WEEK; | |
+import static java.time.temporal.ChronoField.DAY_OF_YEAR; | |
+import static java.time.temporal.ChronoField.EPOCH_DAY; | |
+import static java.time.temporal.ChronoField.MONTH_OF_YEAR; | |
+import static java.time.temporal.ChronoField.PROLEPTIC_MONTH; | |
+import static java.time.temporal.ChronoField.YEAR; | |
import static java.time.temporal.ChronoField.YEAR_OF_ERA; | |
import java.io.DataInput; | |
@@ -70,20 +82,23 @@ | |
import java.io.ObjectStreamException; | |
import java.time.Clock; | |
import java.time.DateTimeException; | |
+import java.time.DayOfWeek; | |
import java.time.Instant; | |
import java.time.LocalDate; | |
import java.time.LocalTime; | |
-import java.time.temporal.UnsupportedTemporalTypeException; | |
import java.time.ZoneId; | |
import java.time.format.DateTimeFormatterBuilder; | |
import java.time.format.TextStyle; | |
import java.time.temporal.ChronoField; | |
+import java.time.temporal.ChronoUnit; | |
import java.time.temporal.Queries; | |
import java.time.temporal.Temporal; | |
import java.time.temporal.TemporalAccessor; | |
import java.time.temporal.TemporalField; | |
import java.time.temporal.TemporalQuery; | |
+import java.time.temporal.UnsupportedTemporalTypeException; | |
import java.time.temporal.ValueRange; | |
+import java.util.EnumMap; | |
import java.util.HashSet; | |
import java.util.List; | |
import java.util.Locale; | |
@@ -857,6 +872,105 @@ | |
return prolepticYear(eraObj, yoe); | |
} | |
+ /** | |
+ * Resolves parsed {@code ChronoField} values into a date during parsing. | |
+ * <p> | |
+ * The default implementation is suitable for most calendar systems. | |
+ * | |
+ * @param fieldValues the map of fields to values, which can be updated, not null | |
+ * @return the resolved date, null if insufficient information to create a date | |
+ * @throws DateTimeException if the date cannot be resolved, typically | |
+ * because of a conflict in the input data | |
+ */ | |
+ public ChronoLocalDate<?> resolveDate(EnumMap<ChronoField, Long> fieldValues) { | |
+ // year-of-era and era resolved to year before this method starts | |
+ | |
+ if (fieldValues.containsKey(EPOCH_DAY)) { | |
+ // TODO: really need a dateFromEpochDay() method | |
+ return date(LocalDate.ofEpochDay(fieldValues.remove(EPOCH_DAY))); | |
+ } | |
+ | |
+ if (fieldValues.containsKey(PROLEPTIC_MONTH)) { | |
+ long em = fieldValues.remove(PROLEPTIC_MONTH); | |
+ ChronoLocalDate<?> chronoDate = date(0, 1, 1); | |
+ chronoDate = chronoDate.plus(em, ChronoUnit.MONTHS); | |
+ addFieldValue(fieldValues, MONTH_OF_YEAR, chronoDate.get(MONTH_OF_YEAR)); | |
+ addFieldValue(fieldValues, YEAR, chronoDate.get(YEAR)); | |
+ } | |
+ | |
+ // build date | |
+ if (fieldValues.containsKey(YEAR)) { | |
+ if (fieldValues.containsKey(MONTH_OF_YEAR)) { | |
+ if (fieldValues.containsKey(DAY_OF_MONTH)) { | |
+ int y = range(YEAR).checkValidIntValue(fieldValues.remove(YEAR), YEAR); | |
+ int moy = range(MONTH_OF_YEAR).checkValidIntValue(fieldValues.remove(MONTH_OF_YEAR), MONTH_OF_YEAR); | |
+ int dom = range(DAY_OF_MONTH).checkValidIntValue(fieldValues.remove(DAY_OF_MONTH), DAY_OF_MONTH); | |
+ return date(y, moy, dom); | |
+ } | |
+ if (fieldValues.containsKey(ALIGNED_WEEK_OF_MONTH)) { | |
+ if (fieldValues.containsKey(ALIGNED_DAY_OF_WEEK_IN_MONTH)) { | |
+ int y = range(YEAR).checkValidIntValue(fieldValues.remove(YEAR), YEAR); | |
+ int moy = range(MONTH_OF_YEAR).checkValidIntValue(fieldValues.remove(MONTH_OF_YEAR), MONTH_OF_YEAR); | |
+ int aw = range(ALIGNED_WEEK_OF_MONTH).checkValidIntValue(fieldValues.remove(ALIGNED_WEEK_OF_MONTH), ALIGNED_WEEK_OF_MONTH); | |
+ int ad = range(ALIGNED_DAY_OF_WEEK_IN_MONTH).checkValidIntValue(fieldValues.remove(ALIGNED_DAY_OF_WEEK_IN_MONTH), ALIGNED_DAY_OF_WEEK_IN_MONTH); | |
+ ChronoLocalDate<?> chronoDate = date(y, moy, 1); | |
+ return chronoDate.plus((aw - 1) * 7 + (ad - 1), ChronoUnit.DAYS); | |
+ } | |
+ if (fieldValues.containsKey(DAY_OF_WEEK)) { | |
+ int y = range(YEAR).checkValidIntValue(fieldValues.remove(YEAR), YEAR); | |
+ int moy = range(MONTH_OF_YEAR).checkValidIntValue(fieldValues.remove(MONTH_OF_YEAR), MONTH_OF_YEAR); | |
+ int aw = range(ALIGNED_WEEK_OF_MONTH).checkValidIntValue(fieldValues.remove(ALIGNED_WEEK_OF_MONTH), ALIGNED_WEEK_OF_MONTH); | |
+ int dow = range(DAY_OF_WEEK).checkValidIntValue(fieldValues.remove(DAY_OF_WEEK), DAY_OF_WEEK); | |
+ ChronoLocalDate<?> chronoDate = date(y, moy, 1); | |
+ return chronoDate.plus((aw - 1) * 7, ChronoUnit.DAYS).with(nextOrSame(DayOfWeek.of(dow))); | |
+ } | |
+ } | |
+ } | |
+ if (fieldValues.containsKey(DAY_OF_YEAR)) { | |
+ int y = range(YEAR).checkValidIntValue(fieldValues.remove(YEAR), YEAR); | |
+ int doy = range(DAY_OF_YEAR).checkValidIntValue(fieldValues.remove(DAY_OF_YEAR), DAY_OF_YEAR); | |
+ return dateYearDay(y, doy); | |
+ } | |
+ if (fieldValues.containsKey(ALIGNED_WEEK_OF_YEAR)) { | |
+ if (fieldValues.containsKey(ALIGNED_DAY_OF_WEEK_IN_YEAR)) { | |
+ int y = range(YEAR).checkValidIntValue(fieldValues.remove(YEAR), YEAR); | |
+ int aw = range(ALIGNED_WEEK_OF_YEAR).checkValidIntValue(fieldValues.remove(ALIGNED_WEEK_OF_YEAR), ALIGNED_WEEK_OF_YEAR); | |
+ int ad = range(ALIGNED_DAY_OF_WEEK_IN_YEAR).checkValidIntValue(fieldValues.remove(ALIGNED_DAY_OF_WEEK_IN_YEAR), ALIGNED_DAY_OF_WEEK_IN_YEAR); | |
+ ChronoLocalDate<?> chronoDate = dateYearDay(y, 1); | |
+ return chronoDate.plus((aw - 1) * 7 + (ad - 1), ChronoUnit.DAYS); | |
+ } | |
+ if (fieldValues.containsKey(DAY_OF_WEEK)) { | |
+ int y = range(YEAR).checkValidIntValue(fieldValues.remove(YEAR), YEAR); | |
+ int aw = range(ALIGNED_WEEK_OF_YEAR).checkValidIntValue(fieldValues.remove(ALIGNED_WEEK_OF_YEAR), ALIGNED_WEEK_OF_YEAR); | |
+ int dow = range(DAY_OF_WEEK).checkValidIntValue(fieldValues.remove(DAY_OF_WEEK), DAY_OF_WEEK); | |
+ ChronoLocalDate<?> chronoDate = dateYearDay(y, 1); | |
+ return chronoDate.plus((aw - 1) * 7, ChronoUnit.DAYS).with(nextOrSame(DayOfWeek.of(dow))); | |
+ } | |
+ } | |
+ } | |
+ return null; | |
+ } | |
+ | |
+ /** | |
+ * Adds a field-value pair to the map, checking for conflicts. | |
+ * <p> | |
+ * If the field is not already present, then the field-value pair is added to the map. | |
+ * If the field is already present and it has the same value as that specified, no action occurs. | |
+ * If the field is already present and it has a different value to that specified, then | |
+ * an exception is thrown. | |
+ * | |
+ * @param field the field to add, not null | |
+ * @param value the value to add, not null | |
+ * @throws DateTimeException if the field is already present with a different value | |
+ */ | |
+ void addFieldValue(EnumMap<ChronoField, Long> fieldValues, ChronoField field, long value) { | |
+ Long old = fieldValues.get(field); // check first for better error message | |
+ if (old != null && old.longValue() != value) { | |
+ throw new DateTimeException("Conflict found: " + field + " " + old + " differs from " + field + " " + value + ": " + this); | |
+ } | |
+ fieldValues.put(field, value); | |
+ } | |
+ | |
//----------------------------------------------------------------------- | |
/** | |
* Compares this chronology to another chronology. | |
diff --git a/src/share/classes/java/time/chrono/IsoChronology.java b/src/share/classes/java/time/chrono/IsoChronology.java | |
--- a/src/share/classes/java/time/chrono/IsoChronology.java | |
+++ b/src/share/classes/java/time/chrono/IsoChronology.java | |
@@ -61,12 +61,29 @@ | |
*/ | |
package java.time.chrono; | |
+import static java.time.temporal.Adjusters.nextOrSame; | |
+import static java.time.temporal.ChronoField.ALIGNED_DAY_OF_WEEK_IN_MONTH; | |
+import static java.time.temporal.ChronoField.ALIGNED_DAY_OF_WEEK_IN_YEAR; | |
+import static java.time.temporal.ChronoField.ALIGNED_WEEK_OF_MONTH; | |
+import static java.time.temporal.ChronoField.ALIGNED_WEEK_OF_YEAR; | |
+import static java.time.temporal.ChronoField.DAY_OF_MONTH; | |
+import static java.time.temporal.ChronoField.DAY_OF_WEEK; | |
+import static java.time.temporal.ChronoField.DAY_OF_YEAR; | |
+import static java.time.temporal.ChronoField.EPOCH_DAY; | |
+import static java.time.temporal.ChronoField.ERA; | |
+import static java.time.temporal.ChronoField.MONTH_OF_YEAR; | |
+import static java.time.temporal.ChronoField.PROLEPTIC_MONTH; | |
+import static java.time.temporal.ChronoField.YEAR; | |
+import static java.time.temporal.ChronoField.YEAR_OF_ERA; | |
+ | |
import java.io.Serializable; | |
import java.time.Clock; | |
import java.time.DateTimeException; | |
+import java.time.DayOfWeek; | |
import java.time.Instant; | |
import java.time.LocalDate; | |
import java.time.LocalDateTime; | |
+import java.time.temporal.ChronoUnit; | |
import java.time.temporal.UnsupportedTemporalTypeException; | |
import java.time.ZoneId; | |
import java.time.ZonedDateTime; | |
@@ -74,6 +91,7 @@ | |
import java.time.temporal.TemporalAccessor; | |
import java.time.temporal.ValueRange; | |
import java.util.Arrays; | |
+import java.util.EnumMap; | |
import java.util.List; | |
import java.util.Locale; | |
import java.util.Objects; | |
@@ -393,6 +411,70 @@ | |
} | |
} | |
+ @Override // override for performance | |
+ public LocalDate resolveDate(EnumMap<ChronoField, Long> fieldValues) { | |
+ // year-of-era and era resolved to year before this method starts | |
+ | |
+ if (fieldValues.containsKey(EPOCH_DAY)) { | |
+ return LocalDate.ofEpochDay(fieldValues.remove(EPOCH_DAY)); | |
+ } | |
+ | |
+ // normalize fields | |
+ if (fieldValues.containsKey(PROLEPTIC_MONTH)) { | |
+ long em = fieldValues.remove(PROLEPTIC_MONTH); | |
+ addFieldValue(fieldValues, MONTH_OF_YEAR, Math.floorMod(em, 12) + 1); | |
+ addFieldValue(fieldValues, YEAR, Math.floorDiv(em, 12)); | |
+ } | |
+ | |
+ // build date | |
+ if (fieldValues.containsKey(YEAR)) { | |
+ if (fieldValues.containsKey(MONTH_OF_YEAR)) { | |
+ if (fieldValues.containsKey(DAY_OF_MONTH)) { | |
+ int y = YEAR.checkValidIntValue(fieldValues.remove(YEAR)); | |
+ int moy = MONTH_OF_YEAR.checkValidIntValue(fieldValues.remove(MONTH_OF_YEAR)); | |
+ int dom = DAY_OF_MONTH.checkValidIntValue(fieldValues.remove(DAY_OF_MONTH)); | |
+ return LocalDate.of(y, moy, dom); | |
+ } | |
+ if (fieldValues.containsKey(ALIGNED_WEEK_OF_MONTH)) { | |
+ if (fieldValues.containsKey(ALIGNED_DAY_OF_WEEK_IN_MONTH)) { | |
+ int y = YEAR.checkValidIntValue(fieldValues.remove(YEAR)); | |
+ int moy = MONTH_OF_YEAR.checkValidIntValue(fieldValues.remove(MONTH_OF_YEAR)); | |
+ int aw = ALIGNED_WEEK_OF_MONTH.checkValidIntValue(fieldValues.remove(ALIGNED_WEEK_OF_MONTH)); | |
+ int ad = ALIGNED_DAY_OF_WEEK_IN_MONTH.checkValidIntValue(fieldValues.remove(ALIGNED_DAY_OF_WEEK_IN_MONTH)); | |
+ return LocalDate.of(y, moy, 1).plusDays((aw - 1) * 7 + (ad - 1)); | |
+ } | |
+ if (fieldValues.containsKey(DAY_OF_WEEK)) { | |
+ int y = YEAR.checkValidIntValue(fieldValues.remove(YEAR)); | |
+ int moy = MONTH_OF_YEAR.checkValidIntValue(fieldValues.remove(MONTH_OF_YEAR)); | |
+ int aw = ALIGNED_WEEK_OF_MONTH.checkValidIntValue(fieldValues.remove(ALIGNED_WEEK_OF_MONTH)); | |
+ int dow = DAY_OF_WEEK.checkValidIntValue(fieldValues.remove(DAY_OF_WEEK)); | |
+ return LocalDate.of(y, moy, 1).plusDays((aw - 1) * 7).with(nextOrSame(DayOfWeek.of(dow))); | |
+ } | |
+ } | |
+ } | |
+ if (fieldValues.containsKey(DAY_OF_YEAR)) { | |
+ int doy = DAY_OF_YEAR.checkValidIntValue(fieldValues.remove(DAY_OF_YEAR)); | |
+ int y = YEAR.checkValidIntValue(fieldValues.remove(YEAR)); | |
+ return LocalDate.ofYearDay(y, doy); | |
+ } | |
+ if (fieldValues.containsKey(ALIGNED_WEEK_OF_YEAR)) { | |
+ if (fieldValues.containsKey(ALIGNED_DAY_OF_WEEK_IN_YEAR)) { | |
+ int y = YEAR.checkValidIntValue(fieldValues.remove(YEAR)); | |
+ int aw = ALIGNED_WEEK_OF_YEAR.checkValidIntValue(fieldValues.remove(ALIGNED_WEEK_OF_YEAR)); | |
+ int ad = ALIGNED_DAY_OF_WEEK_IN_YEAR.checkValidIntValue(fieldValues.remove(ALIGNED_DAY_OF_WEEK_IN_YEAR)); | |
+ return LocalDate.of(y, 1, 1).plusDays((aw - 1) * 7 + (ad - 1)); | |
+ } | |
+ if (fieldValues.containsKey(DAY_OF_WEEK)) { | |
+ int y = YEAR.checkValidIntValue(fieldValues.remove(YEAR)); | |
+ int aw = ALIGNED_WEEK_OF_YEAR.checkValidIntValue(fieldValues.remove(ALIGNED_WEEK_OF_YEAR)); | |
+ int dow = DAY_OF_WEEK.checkValidIntValue(fieldValues.remove(DAY_OF_WEEK)); | |
+ return LocalDate.of(y, 1, 1).plusDays((aw - 1) * 7).with(nextOrSame(DayOfWeek.of(dow))); | |
+ } | |
+ } | |
+ } | |
+ return null; | |
+ } | |
+ | |
//----------------------------------------------------------------------- | |
@Override | |
public ValueRange range(ChronoField field) { | |
diff --git a/src/share/classes/java/time/format/DateTimeBuilder.java b/src/share/classes/java/time/format/DateTimeBuilder.java | |
--- a/src/share/classes/java/time/format/DateTimeBuilder.java | |
+++ b/src/share/classes/java/time/format/DateTimeBuilder.java | |
@@ -61,18 +61,9 @@ | |
*/ | |
package java.time.format; | |
-import static java.time.temporal.Adjusters.nextOrSame; | |
-import static java.time.temporal.ChronoField.ALIGNED_DAY_OF_WEEK_IN_MONTH; | |
-import static java.time.temporal.ChronoField.ALIGNED_DAY_OF_WEEK_IN_YEAR; | |
-import static java.time.temporal.ChronoField.ALIGNED_WEEK_OF_MONTH; | |
-import static java.time.temporal.ChronoField.ALIGNED_WEEK_OF_YEAR; | |
import static java.time.temporal.ChronoField.AMPM_OF_DAY; | |
import static java.time.temporal.ChronoField.CLOCK_HOUR_OF_AMPM; | |
import static java.time.temporal.ChronoField.CLOCK_HOUR_OF_DAY; | |
-import static java.time.temporal.ChronoField.DAY_OF_MONTH; | |
-import static java.time.temporal.ChronoField.DAY_OF_WEEK; | |
-import static java.time.temporal.ChronoField.DAY_OF_YEAR; | |
-import static java.time.temporal.ChronoField.EPOCH_DAY; | |
import static java.time.temporal.ChronoField.HOUR_OF_AMPM; | |
import static java.time.temporal.ChronoField.HOUR_OF_DAY; | |
import static java.time.temporal.ChronoField.MICRO_OF_DAY; | |
@@ -81,26 +72,18 @@ | |
import static java.time.temporal.ChronoField.MILLI_OF_SECOND; | |
import static java.time.temporal.ChronoField.MINUTE_OF_DAY; | |
import static java.time.temporal.ChronoField.MINUTE_OF_HOUR; | |
-import static java.time.temporal.ChronoField.MONTH_OF_YEAR; | |
import static java.time.temporal.ChronoField.NANO_OF_DAY; | |
import static java.time.temporal.ChronoField.NANO_OF_SECOND; | |
-import static java.time.temporal.ChronoField.PROLEPTIC_MONTH; | |
import static java.time.temporal.ChronoField.SECOND_OF_DAY; | |
import static java.time.temporal.ChronoField.SECOND_OF_MINUTE; | |
-import static java.time.temporal.ChronoField.YEAR; | |
import java.time.DateTimeException; | |
-import java.time.DayOfWeek; | |
import java.time.LocalDate; | |
import java.time.LocalTime; | |
import java.time.ZoneId; | |
import java.time.chrono.ChronoLocalDate; | |
import java.time.chrono.Chronology; | |
-import java.time.chrono.Era; | |
-import java.time.chrono.IsoChronology; | |
-import java.time.chrono.JapaneseChronology; | |
import java.time.temporal.ChronoField; | |
-import java.time.temporal.ChronoUnit; | |
import java.time.temporal.Queries; | |
import java.time.temporal.TemporalAccessor; | |
import java.time.temporal.TemporalField; | |
@@ -108,7 +91,6 @@ | |
import java.util.EnumMap; | |
import java.util.HashMap; | |
import java.util.LinkedHashMap; | |
-import java.util.List; | |
import java.util.Map; | |
import java.util.Objects; | |
@@ -153,7 +135,7 @@ | |
/** | |
* The date. | |
*/ | |
- private LocalDate date; | |
+ private ChronoLocalDate<?> date; | |
/** | |
* The time. | |
*/ | |
@@ -220,7 +202,7 @@ | |
this.zone = zone; | |
} | |
- void addObject(LocalDate date) { | |
+ void addObject(ChronoLocalDate<?> date) { | |
this.date = date; | |
} | |
@@ -247,139 +229,13 @@ | |
} | |
private void mergeDate() { | |
- if (standardFields.containsKey(EPOCH_DAY)) { | |
- checkDate(LocalDate.ofEpochDay(standardFields.remove(EPOCH_DAY))); | |
- return; | |
- } | |
- | |
- if (chrono == IsoChronology.INSTANCE) { | |
- // normalize fields | |
- if (standardFields.containsKey(PROLEPTIC_MONTH)) { | |
- long em = standardFields.remove(PROLEPTIC_MONTH); | |
- addFieldValue(MONTH_OF_YEAR, Math.floorMod(em, 12) + 1); | |
- addFieldValue(YEAR, Math.floorDiv(em, 12)); | |
- } | |
- } else { | |
- // TODO: revisit PROLEPTIC_MONTH calculation in non-ISO chronology | |
- // Handle PROLEPTIC_MONTH here for non-ISO Chronology | |
- if (standardFields.containsKey(PROLEPTIC_MONTH)) { | |
- long em = standardFields.remove(PROLEPTIC_MONTH); | |
- ChronoLocalDate<?> chronoDate = chrono.date(1, 1, 1); | |
- chronoDate = chronoDate.plus(em, ChronoUnit.MONTHS); | |
- LocalDate date = LocalDate.ofEpochDay(chronoDate.toEpochDay()); | |
- checkDate(date); | |
- return; | |
- } | |
- } | |
- | |
- // build date | |
- if (standardFields.containsKey(YEAR)) { | |
- if (standardFields.containsKey(MONTH_OF_YEAR)) { | |
- if (standardFields.containsKey(DAY_OF_MONTH)) { | |
- int y = Math.toIntExact(standardFields.remove(YEAR)); | |
- int moy = Math.toIntExact(standardFields.remove(MONTH_OF_YEAR)); | |
- int dom = Math.toIntExact(standardFields.remove(DAY_OF_MONTH)); | |
- LocalDate date; | |
- if (chrono == IsoChronology.INSTANCE) { | |
- date = LocalDate.of(y, moy, dom); | |
- } else { | |
- ChronoLocalDate<?> chronoDate; | |
- chronoDate = chrono.date(y, moy, dom); | |
- date = LocalDate.ofEpochDay(chronoDate.toEpochDay()); | |
- } | |
- checkDate(date); | |
- return; | |
- } | |
- if (standardFields.containsKey(ALIGNED_WEEK_OF_MONTH)) { | |
- if (standardFields.containsKey(ALIGNED_DAY_OF_WEEK_IN_MONTH)) { | |
- int y = Math.toIntExact(standardFields.remove(YEAR)); | |
- int moy = Math.toIntExact(standardFields.remove(MONTH_OF_YEAR)); | |
- int aw = Math.toIntExact(standardFields.remove(ALIGNED_WEEK_OF_MONTH)); | |
- int ad = Math.toIntExact(standardFields.remove(ALIGNED_DAY_OF_WEEK_IN_MONTH)); | |
- LocalDate date; | |
- if (chrono == IsoChronology.INSTANCE) { | |
- date = LocalDate.of(y, moy, 1).plusDays((aw - 1) * 7 + (ad - 1)); | |
- } else { | |
- ChronoLocalDate<?> chronoDate; | |
- chronoDate = chrono.date(y, moy, 1); | |
- chronoDate = chronoDate.plus((aw - 1) * 7 + (ad - 1), ChronoUnit.DAYS); | |
- date = LocalDate.ofEpochDay(chronoDate.toEpochDay()); | |
- } | |
- checkDate(date); | |
- return; | |
- } | |
- if (standardFields.containsKey(DAY_OF_WEEK)) { | |
- int y = Math.toIntExact(standardFields.remove(YEAR)); | |
- int moy = Math.toIntExact(standardFields.remove(MONTH_OF_YEAR)); | |
- int aw = Math.toIntExact(standardFields.remove(ALIGNED_WEEK_OF_MONTH)); | |
- int dow = Math.toIntExact(standardFields.remove(DAY_OF_WEEK)); | |
- LocalDate date; | |
- if (chrono == IsoChronology.INSTANCE) { | |
- date = LocalDate.of(y, moy, 1).plusDays((aw - 1) * 7).with(nextOrSame(DayOfWeek.of(dow))); | |
- } else { | |
- ChronoLocalDate<?> chronoDate; | |
- chronoDate = chrono.date(y, moy, 1); | |
- chronoDate = chronoDate.plus((aw - 1) * 7, ChronoUnit.DAYS).with(nextOrSame(DayOfWeek.of(dow))); | |
- date = LocalDate.ofEpochDay(chronoDate.toEpochDay()); | |
- } | |
- checkDate(date); | |
- return; | |
- } | |
- } | |
- } | |
- if (standardFields.containsKey(DAY_OF_YEAR)) { | |
- int y = Math.toIntExact(standardFields.remove(YEAR)); | |
- int doy = Math.toIntExact(standardFields.remove(DAY_OF_YEAR)); | |
- LocalDate date; | |
- if (chrono == IsoChronology.INSTANCE) { | |
- date = LocalDate.ofYearDay(y, doy); | |
- } else { | |
- ChronoLocalDate<?> chronoDate; | |
- chronoDate = chrono.dateYearDay(y, doy); | |
- date = LocalDate.ofEpochDay(chronoDate.toEpochDay()); | |
- } | |
- checkDate(date); | |
- return; | |
- } | |
- if (standardFields.containsKey(ALIGNED_WEEK_OF_YEAR)) { | |
- if (standardFields.containsKey(ALIGNED_DAY_OF_WEEK_IN_YEAR)) { | |
- int y = Math.toIntExact(standardFields.remove(YEAR)); | |
- int aw = Math.toIntExact(standardFields.remove(ALIGNED_WEEK_OF_YEAR)); | |
- int ad = Math.toIntExact(standardFields.remove(ALIGNED_DAY_OF_WEEK_IN_YEAR)); | |
- LocalDate date; | |
- if (chrono == IsoChronology.INSTANCE) { | |
- date = LocalDate.of(y, 1, 1).plusDays((aw - 1) * 7 + (ad - 1)); | |
- } else { | |
- ChronoLocalDate<?> chronoDate; | |
- chronoDate = chrono.dateYearDay(y, 1); | |
- chronoDate = chronoDate.plus((aw - 1) * 7 + (ad - 1), ChronoUnit.DAYS); | |
- date = LocalDate.ofEpochDay(chronoDate.toEpochDay()); | |
- } | |
- checkDate(date); | |
- return; | |
- } | |
- if (standardFields.containsKey(DAY_OF_WEEK)) { | |
- int y = Math.toIntExact(standardFields.remove(YEAR)); | |
- int aw = Math.toIntExact(standardFields.remove(ALIGNED_WEEK_OF_YEAR)); | |
- int dow = Math.toIntExact(standardFields.remove(DAY_OF_WEEK)); | |
- LocalDate date; | |
- if (chrono == IsoChronology.INSTANCE) { | |
- date = LocalDate.of(y, 1, 1).plusDays((aw - 1) * 7).with(nextOrSame(DayOfWeek.of(dow))); | |
- } else { | |
- ChronoLocalDate<?> chronoDate; | |
- chronoDate = chrono.dateYearDay(y, 1); | |
- chronoDate = chronoDate.plus((aw - 1) * 7, ChronoUnit.DAYS).with(nextOrSame(DayOfWeek.of(dow))); | |
- date = LocalDate.ofEpochDay(chronoDate.toEpochDay()); | |
- } | |
- checkDate(date); | |
- return; | |
- } | |
- } | |
+ ChronoLocalDate<?> date = chrono.resolveDate(standardFields); | |
+ if (date != null) { | |
+ addObject(checkDate(date)); | |
} | |
} | |
- private void checkDate(LocalDate date) { | |
- addObject(date); | |
+ private ChronoLocalDate<?> checkDate(ChronoLocalDate<?> date) { | |
for (ChronoField field : standardFields.keySet()) { | |
long val1; | |
try { | |
@@ -392,6 +248,7 @@ | |
throw new DateTimeException("Conflict found: Field " + field + " " + val1 + " differs from " + field + " " + val2 + " derived from " + date); | |
} | |
} | |
+ return date; | |
} | |
private void mergeTime() { | |
@@ -517,7 +374,7 @@ | |
} else if (query == Queries.chronology()) { | |
return (R) chrono; | |
} else if (query == Queries.localDate()) { | |
- return (R) date; | |
+ return (R) (date != null ? LocalDate.from(date) : null); | |
} else if (query == Queries.localTime()) { | |
return (R) time; | |
} else if (query == Queries.zone() || query == Queries.offset()) { |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment