Skip to content

Instantly share code, notes, and snippets.

@jodastephen
Created February 27, 2013 16:34
Show Gist options
  • Save jodastephen/5049319 to your computer and use it in GitHub Desktop.
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)
# 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