ThreeTen / threeten

This project was the home of code used to develop a modern date and time library for JDK8. Development has moved to OpenJDK and a separate backport project, threetenbp.
http://threeten.github.io/
191 stars 37 forks source link

Lenient date creation/resolving #282

Closed jodastephen closed 11 years ago

jodastephen commented 11 years ago

I had the challenge of creating a date leniently from a day-of-month in the range 1-31 today. These two options work today:

day = Math.min(day, YearMonth.of(year, month).lengthOfMonth());
day = Math.min(day, Month.of(month).length(Year.isLeap(year)));

The latter is clunky, the former is OK, but is still indirect (I really want a date, not to adjust the day) and it involves an object creation.

It would be worth adding one (or both) of these options:

date = YearMonth.of(year, month).atDayOrEndOfMonth(day);
date = YearMonth.of(year, month).atDayPreviousValid(day);
date = LocalDate.ofPreviousValid(year, month, day);

or a more general date resolver (interface or enum):

DateResolver.PREVIOUS_VALID.date(year, month, day);
DateResolver.STRICT.date(year, month, day);
DateResolver.PART_LENIENT.date(year, month, day);
DateResolver.LENIENT.date(year, month, day);
// and maybe
DateResolver.PREVIOUS_VALID.date(chronology, year, month, day);
// and even
DateResolver.LENIENT.addYearsMonths(localDate, 2, 3);

This last option could be linked to lenient parsing #115.

RogerRiggs commented 11 years ago

How about a real builder class that produces the equivalent of Parsed (which BTW, should not be public). Then the rest of the mechanisms we have for resolving dates can be used in the same manner as they are in DateTimeFormatter parsing. It can implement TemporalAccessor and be usable with any Chronology.

Builder with method like ZonedDateTime but mutable.

jodastephen commented 11 years ago

You mean a public class? Thats where we started from and have been trying to get away from...

I think we have enough ways for applications to build up date-times. Any builder is only useful when you need to make sense of a "random map" of date-time info, and parsing is the main use case for that. It would be better to keep any mechanism private and have a factory passing in a map if we want to expose it.

Ultimately, the DateResolver problem keeps being present (in coding, or leniency). We took it out to get us to where we are, but the ability it provides is still needed. A standalone utility class provides the functionality without affecting the rest of the code, which is why I bring it up.

RogerRiggs commented 11 years ago

DateTimeBuilder was not a real builder class and had all kinds of magic built-in, its API was not designed for use by developers. Only dates have this feature so a date-only mechanism is ok but it needs to support other chronologies, not just ISO. The leniency is only really needed to adapt the day, though perhaps in a Hebrew calendar handling the 13th month automatically would be useful to cope with entry errors.

Adding factory methods like date = LocalDate.ofPreviousValid(year, month, day); might be the simplest; they could be just in LocalDate and Chronology.dateOrPreviousValid. with proleptic and yearOfEra overrides.

jodastephen commented 11 years ago

A builder class focussed on just year-month-day doesn't add any value, while one merging any data is more complex.

Leniency doesn't just apply to day within month-year. Other fields have similar issues, such as year-month-day within era in Japanese, or day-of-year within year.

Thats why ofPreviousValid is quite a point specific solution, but DateResolver would scale better (more methods for each of the cases). Of course it depends on whether a suitable algorithm can be created for leniency that is chrono neutral. Otherwise, each chrono subclass will need to handle the various cases

(previous valid, next valid, part lenient and full lenient are the four basic approaches)

RogerRiggs commented 11 years ago

I don't the practical use cases for any but previous valid and the Chronology already needs to have a hand in the resolution. Adding a Leniency enum for the leniency choices for (previous and next ) and add a method to Chronology would be sufficient. Chronology.date(year, month, day, Leniency) Adding the other cases could be accommodated later. The leniency enum can then be part of the DateTimeFormatter context. There is still an issue with the relationship between Chronology .resolveDate and any leniency setting.

jodastephen commented 11 years ago

This approach might work OK, although the ChronoField resolve method may also need the Leniency object.

jodastephen commented 11 years ago

First part of a patch to add ResolverStyle, settable on DateTimeFormatter, controlling how the date/time is resolved.

# HG changeset patch
# User scolebourne
# Date 1364851962 -3600
# Node ID 7eb1e6fa26d0378caded7309b655b4dd17a3fd4f
# Parent  4517b8abe0eb72fb31b47f55a3d0159f4815d321
Basic support for ResolverStyle

Three possible ways to control resolving date/time

diff -r 4517b8abe0eb -r 7eb1e6fa26d0 src/share/classes/java/time/format/DateTimeFormatter.java
--- a/src/share/classes/java/time/format/DateTimeFormatter.java Mon Apr 01 02:29:21 2013 +0100
+++ b/src/share/classes/java/time/format/DateTimeFormatter.java Mon Apr 01 22:32:42 2013 +0100
@@ -80,6 +80,7 @@
 import java.time.ZoneId;
 import java.time.ZoneOffset;
 import java.time.chrono.Chronology;
+import java.time.chrono.IsoChronology;
 import java.time.format.DateTimeFormatterBuilder.CompositePrinterParser;
 import java.time.temporal.ChronoField;
 import java.time.temporal.IsoFields;
@@ -438,6 +439,10 @@
      */
     private final DateTimeFormatSymbols symbols;
     /**
+     * The resolver style to use, not null.
+     */
+    private final ResolverStyle resolverStyle;
+    /**
      * The chronology to use for formatting, null for no override.
      */
     private final Chronology chrono;
@@ -458,6 +463,9 @@
      * The formatter will use the {@link Locale#getDefault(Locale.Category) default FORMAT locale}.
      * This can be changed using {@link DateTimeFormatter#withLocale(Locale)} on the returned formatter
      * Alternatively use the {@link #ofPattern(String, Locale)} variant of this method.
+     * <p>
+     * The returned formatter has no override chronology or zone.
+     * It uses {@link ResolverStyle#SMART SMART} resolver style.
      *
      * @param pattern  the pattern to use, not null
      * @return the formatter based on the pattern, not null
@@ -478,6 +486,9 @@
      * <p>
      * The formatter will use the specified locale.
      * This can be changed using {@link DateTimeFormatter#withLocale(Locale)} on the returned formatter
+     * <p>
+     * The returned formatter has no override chronology or zone.
+     * It uses {@link ResolverStyle#SMART SMART} resolver style.
      *
      * @param pattern  the pattern to use, not null
      * @param locale  the locale to use, not null
@@ -507,14 +518,15 @@
      * <p>
      * The returned formatter has a chronology of ISO set to ensure dates in
      * other calendar systems are correctly converted.
-     * The chronology is visible via {@link DateTimeFormatter#getChronology()}.
+     * It has no override zone and uses the {@link ResolverStyle#SMART SMART} resolver style.
      *
      * @param dateStyle  the formatter style to obtain, not null
      * @return the date formatter, not null
      */
     public static DateTimeFormatter ofLocalizedDate(FormatStyle dateStyle) {
         Objects.requireNonNull(dateStyle, "dateStyle");
-        return new DateTimeFormatterBuilder().appendLocalized(dateStyle, null).toFormatterIso();
+        return new DateTimeFormatterBuilder().appendLocalized(dateStyle, null)
+                .toFormatter(ResolverStyle.SMART, IsoChronology.INSTANCE);
     }

     /**
@@ -534,14 +546,15 @@
      * <p>
      * The returned formatter has a chronology of ISO set to ensure dates in
      * other calendar systems are correctly converted.
-     * The chronology is visible via {@link DateTimeFormatter#getChronology()}.
+     * It has no override zone and uses the {@link ResolverStyle#SMART SMART} resolver style.
      *
      * @param timeStyle  the formatter style to obtain, not null
      * @return the time formatter, not null
      */
     public static DateTimeFormatter ofLocalizedTime(FormatStyle timeStyle) {
         Objects.requireNonNull(timeStyle, "timeStyle");
-        return new DateTimeFormatterBuilder().appendLocalized(null, timeStyle).toFormatterIso();
+        return new DateTimeFormatterBuilder().appendLocalized(null, timeStyle)
+                .toFormatter(ResolverStyle.SMART, IsoChronology.INSTANCE);
     }

     /**
@@ -561,14 +574,15 @@
      * <p>
      * The returned formatter has a chronology of ISO set to ensure dates in
      * other calendar systems are correctly converted.
-     * The chronology is visible via {@link DateTimeFormatter#getChronology()}.
+     * It has no override zone and uses the {@link ResolverStyle#SMART SMART} resolver style.
      *
      * @param dateTimeStyle  the formatter style to obtain, not null
      * @return the date-time formatter, not null
      */
     public static DateTimeFormatter ofLocalizedDateTime(FormatStyle dateTimeStyle) {
         Objects.requireNonNull(dateTimeStyle, "dateTimeStyle");
-        return new DateTimeFormatterBuilder().appendLocalized(dateTimeStyle, dateTimeStyle).toFormatterIso();
+        return new DateTimeFormatterBuilder().appendLocalized(dateTimeStyle, dateTimeStyle)
+                .toFormatter(ResolverStyle.SMART, IsoChronology.INSTANCE);
     }

     /**
@@ -588,7 +602,7 @@
      * <p>
      * The returned formatter has a chronology of ISO set to ensure dates in
      * other calendar systems are correctly converted.
-     * The chronology is visible via {@link DateTimeFormatter#getChronology()}.
+     * It has no override zone and uses the {@link ResolverStyle#SMART SMART} resolver style.
      *
      * @param dateStyle  the date formatter style to obtain, not null
      * @param timeStyle  the time formatter style to obtain, not null
@@ -597,7 +611,8 @@
     public static DateTimeFormatter ofLocalizedDateTime(FormatStyle dateStyle, FormatStyle timeStyle) {
         Objects.requireNonNull(dateStyle, "dateStyle");
         Objects.requireNonNull(timeStyle, "timeStyle");
-        return new DateTimeFormatterBuilder().appendLocalized(dateStyle, timeStyle).toFormatterIso();
+        return new DateTimeFormatterBuilder().appendLocalized(dateStyle, timeStyle)
+                .toFormatter(ResolverStyle.SMART, IsoChronology.INSTANCE);
     }

     //-----------------------------------------------------------------------
@@ -622,7 +637,7 @@
      * <p>
      * The returned formatter has a chronology of ISO set to ensure dates in
      * other calendar systems are correctly converted.
-     * The chronology is visible via {@link DateTimeFormatter#getChronology()}.
+     * It has no override zone and uses the {@link ResolverStyle#STRICT STRICT} resolver style.
      */
     public static final DateTimeFormatter ISO_LOCAL_DATE;
     static {
@@ -632,7 +647,7 @@
                 .appendValue(MONTH_OF_YEAR, 2)
                 .appendLiteral('-')
                 .appendValue(DAY_OF_MONTH, 2)
-                .toFormatterIso();
+                .toFormatter(ResolverStyle.STRICT, IsoChronology.INSTANCE);
     }

     //-----------------------------------------------------------------------
@@ -652,7 +667,7 @@
      * <p>
      * The returned formatter has a chronology of ISO set to ensure dates in
      * other calendar systems are correctly converted.
-     * The chronology is visible via {@link DateTimeFormatter#getChronology()}.
+     * It has no override zone and uses the {@link ResolverStyle#STRICT STRICT} resolver style.
      */
     public static final DateTimeFormatter ISO_OFFSET_DATE;
     static {
@@ -660,7 +675,7 @@
                 .parseCaseInsensitive()
                 .append(ISO_LOCAL_DATE)
                 .appendOffsetId()
-                .toFormatterIso();
+                .toFormatter(ResolverStyle.STRICT, IsoChronology.INSTANCE);
     }

     //-----------------------------------------------------------------------
@@ -684,7 +699,7 @@
      * <p>
      * The returned formatter has a chronology of ISO set to ensure dates in
      * other calendar systems are correctly converted.
-     * The chronology is visible via {@link DateTimeFormatter#getChronology()}.
+     * It has no override zone and uses the {@link ResolverStyle#STRICT STRICT} resolver style.
      */
     public static final DateTimeFormatter ISO_DATE;
     static {
@@ -693,7 +708,7 @@
                 .append(ISO_LOCAL_DATE)
                 .optionalStart()
                 .appendOffsetId()
-                .toFormatterIso();
+                .toFormatter(ResolverStyle.STRICT, IsoChronology.INSTANCE);
     }

     //-----------------------------------------------------------------------
@@ -719,6 +734,9 @@
      * <li>One to nine digits for the {@link ChronoField#NANO_OF_SECOND nano-of-second}.
      *  As many digits will be output as required.
      * </ul>
+     * <p>
+     * The returned formatter has no override chronology or zone.
+     * It uses the {@link ResolverStyle#STRICT STRICT} resolver style.
      */
     public static final DateTimeFormatter ISO_LOCAL_TIME;
     static {
@@ -731,7 +749,7 @@
                 .appendValue(SECOND_OF_MINUTE, 2)
                 .optionalStart()
                 .appendFraction(NANO_OF_SECOND, 0, 9, true)
-                .toFormatter();
+                .toFormatter(ResolverStyle.STRICT, null);
     }

     //-----------------------------------------------------------------------
@@ -748,6 +766,9 @@
      *  they will be handled even though this is not part of the ISO-8601 standard.
      *  Parsing is case insensitive.
      * </ul>
+     * <p>
+     * The returned formatter has no override chronology or zone.
+     * It uses the {@link ResolverStyle#STRICT STRICT} resolver style.
      */
     public static final DateTimeFormatter ISO_OFFSET_TIME;
     static {
@@ -755,7 +776,7 @@
                 .parseCaseInsensitive()
                 .append(ISO_LOCAL_TIME)
                 .appendOffsetId()
-                .toFormatter();
+                .toFormatter(ResolverStyle.STRICT, null);
     }

     //-----------------------------------------------------------------------
@@ -776,6 +797,9 @@
      * <p>
      * As this formatter has an optional element, it may be necessary to parse using
      * {@link DateTimeFormatter#parseBest}.
+     * <p>
+     * The returned formatter has no override chronology or zone.
+     * It uses the {@link ResolverStyle#STRICT STRICT} resolver style.
      */
     public static final DateTimeFormatter ISO_TIME;
     static {
@@ -784,7 +808,7 @@
                 .append(ISO_LOCAL_TIME)
                 .optionalStart()
                 .appendOffsetId()
-                .toFormatter();
+                .toFormatter(ResolverStyle.STRICT, null);
     }

     //-----------------------------------------------------------------------
@@ -803,7 +827,7 @@
      * <p>
      * The returned formatter has a chronology of ISO set to ensure dates in
      * other calendar systems are correctly converted.
-     * The chronology is visible via {@link DateTimeFormatter#getChronology()}.
+     * It has no override zone and uses the {@link ResolverStyle#STRICT STRICT} resolver style.
      */
     public static final DateTimeFormatter ISO_LOCAL_DATE_TIME;
     static {
@@ -812,7 +836,7 @@
                 .append(ISO_LOCAL_DATE)
                 .appendLiteral('T')
                 .append(ISO_LOCAL_TIME)
-                .toFormatterIso();
+                .toFormatter(ResolverStyle.STRICT, IsoChronology.INSTANCE);
     }

     //-----------------------------------------------------------------------
@@ -832,7 +856,7 @@
      * <p>
      * The returned formatter has a chronology of ISO set to ensure dates in
      * other calendar systems are correctly converted.
-     * The chronology is visible via {@link DateTimeFormatter#getChronology()}.
+     * It has no override zone and uses the {@link ResolverStyle#STRICT STRICT} resolver style.
      */
     public static final DateTimeFormatter ISO_OFFSET_DATE_TIME;
     static {
@@ -840,7 +864,7 @@
                 .parseCaseInsensitive()
                 .append(ISO_LOCAL_DATE_TIME)
                 .appendOffsetId()
-                .toFormatterIso();
+                .toFormatter(ResolverStyle.STRICT, IsoChronology.INSTANCE);
     }

     //-----------------------------------------------------------------------
@@ -864,7 +888,7 @@
      * <p>
      * The returned formatter has a chronology of ISO set to ensure dates in
      * other calendar systems are correctly converted.
-     * The chronology is visible via {@link DateTimeFormatter#getChronology()}.
+     * It has no override zone and uses the {@link ResolverStyle#STRICT STRICT} resolver style.
      */
     public static final DateTimeFormatter ISO_ZONED_DATE_TIME;
     static {
@@ -875,7 +899,7 @@
                 .parseCaseSensitive()
                 .appendZoneRegionId()
                 .appendLiteral(']')
-                .toFormatterIso();
+                .toFormatter(ResolverStyle.STRICT, IsoChronology.INSTANCE);
     }

     //-----------------------------------------------------------------------
@@ -905,7 +929,7 @@
      * <p>
      * The returned formatter has a chronology of ISO set to ensure dates in
      * other calendar systems are correctly converted.
-     * The chronology is visible via {@link DateTimeFormatter#getChronology()}.
+     * It has no override zone and uses the {@link ResolverStyle#STRICT STRICT} resolver style.
      */
     public static final DateTimeFormatter ISO_DATE_TIME;
     static {
@@ -918,7 +942,7 @@
                 .parseCaseSensitive()
                 .appendZoneRegionId()
                 .appendLiteral(']')
-                .toFormatterIso();
+                .toFormatter(ResolverStyle.STRICT, IsoChronology.INSTANCE);
     }

     //-----------------------------------------------------------------------
@@ -947,7 +971,7 @@
      * <p>
      * The returned formatter has a chronology of ISO set to ensure dates in
      * other calendar systems are correctly converted.
-     * The chronology is visible via {@link DateTimeFormatter#getChronology()}.
+     * It has no override zone and uses the {@link ResolverStyle#STRICT STRICT} resolver style.
      */
     public static final DateTimeFormatter ISO_ORDINAL_DATE;
     static {
@@ -958,7 +982,7 @@
                 .appendValue(DAY_OF_YEAR, 3)
                 .optionalStart()
                 .appendOffsetId()
-                .toFormatterIso();
+                .toFormatter(ResolverStyle.STRICT, IsoChronology.INSTANCE);
     }

     //-----------------------------------------------------------------------
@@ -991,7 +1015,7 @@
      * <p>
      * The returned formatter has a chronology of ISO set to ensure dates in
      * other calendar systems are correctly converted.
-     * The chronology is visible via {@link DateTimeFormatter#getChronology()}.
+     * It has no override zone and uses the {@link ResolverStyle#STRICT STRICT} resolver style.
      */
     public static final DateTimeFormatter ISO_WEEK_DATE;
     static {
@@ -1004,7 +1028,7 @@
                 .appendValue(DAY_OF_WEEK, 1)
                 .optionalStart()
                 .appendOffsetId()
-                .toFormatterIso();
+                .toFormatter(ResolverStyle.STRICT, IsoChronology.INSTANCE);
     }

     //-----------------------------------------------------------------------
@@ -1029,13 +1053,16 @@
      *  {@link ChronoField#INSTANT_SECONDS} and {@link ChronoField#NANO_OF_SECOND}
      *  using the {@code UTC} offset. Parsing is case insensitive.
      * </ul>
+     * <p>
+     * The returned formatter has no override chronology or zone.
+     * It uses the {@link ResolverStyle#STRICT STRICT} resolver style.
      */
     public static final DateTimeFormatter ISO_INSTANT;
     static {
         ISO_INSTANT = new DateTimeFormatterBuilder()
                 .parseCaseInsensitive()
                 .appendInstant()
-                .toFormatter();
+                .toFormatter(ResolverStyle.STRICT, null);
     }

     //-----------------------------------------------------------------------
@@ -1064,7 +1091,7 @@
      * <p>
      * The returned formatter has a chronology of ISO set to ensure dates in
      * other calendar systems are correctly converted.
-     * The chronology is visible via {@link DateTimeFormatter#getChronology()}.
+     * It has no override zone and uses the {@link ResolverStyle#STRICT STRICT} resolver style.
      */
     public static final DateTimeFormatter BASIC_ISO_DATE;
     static {
@@ -1075,7 +1102,7 @@
                 .appendValue(DAY_OF_MONTH, 2)
                 .optionalStart()
                 .appendOffset("+HHMMss", "Z")
-                .toFormatterIso();
+                .toFormatter(ResolverStyle.STRICT, IsoChronology.INSTANCE);
     }

     //-----------------------------------------------------------------------
@@ -1120,7 +1147,7 @@
      * <p>
      * The returned formatter has a chronology of ISO set to ensure dates in
      * other calendar systems are correctly converted.
-     * The chronology is visible via {@link DateTimeFormatter#getChronology()}.
+     * It has no override zone and uses the {@link ResolverStyle#SMART SMART} resolver style.
      */
     public static final DateTimeFormatter RFC_1123_DATE_TIME;
     static {
@@ -1169,7 +1196,7 @@
                 .optionalEnd()
                 .appendLiteral(' ')
                 .appendOffset("+HHMM", "GMT")  // should handle UT/Z/EST/EDT/CST/CDT/MST/MDT/PST/MDT
-                .toFormatterIso();
+                .toFormatter(ResolverStyle.SMART, IsoChronology.INSTANCE);
     }

     /**
@@ -1179,15 +1206,18 @@
      * @param resolveFields  the fields to use during resolving, null for all fields
      * @param locale  the locale to use, not null
      * @param symbols  the symbols to use, not null
+     * @param resolverStyle  the resolver style to use, not null
      * @param chrono  the chronology to use, null for no override
      * @param zone  the zone to use, null for no override
      */
     DateTimeFormatter(CompositePrinterParser printerParser, List<TemporalField> resolveFields,
-            Locale locale, DateTimeFormatSymbols symbols, Chronology chrono, ZoneId zone) {
+            Locale locale, DateTimeFormatSymbols symbols, ResolverStyle resolverStyle,
+            Chronology chrono, ZoneId zone) {
         this.printerParser = Objects.requireNonNull(printerParser, "printerParser");
         this.resolveFields = resolveFields;
         this.locale = Objects.requireNonNull(locale, "locale");
         this.symbols = Objects.requireNonNull(symbols, "symbols");
+        this.resolverStyle = Objects.requireNonNull(resolverStyle, "resolverStyle");
         this.chrono = chrono;
         this.zone = zone;
     }
@@ -1220,7 +1250,7 @@
         if (this.locale.equals(locale)) {
             return this;
         }
-        return new DateTimeFormatter(printerParser, resolveFields, locale, symbols, chrono, zone);
+        return new DateTimeFormatter(printerParser, resolveFields, locale, symbols, resolverStyle, chrono, zone);
     }

     //-----------------------------------------------------------------------
@@ -1245,7 +1275,7 @@
         if (this.symbols.equals(symbols)) {
             return this;
         }
-        return new DateTimeFormatter(printerParser, resolveFields, locale, symbols, chrono, zone);
+        return new DateTimeFormatter(printerParser, resolveFields, locale, symbols, resolverStyle, chrono, zone);
     }

     //-----------------------------------------------------------------------
@@ -1256,7 +1286,7 @@
      * By default, a formatter has no override chronology, returning null.
      * See {@link #withChronology(Chronology)} for more details on overriding.
      *
-     * @return the chronology of this formatter, null if no override
+     * @return the override chronology of this formatter, null if no override
      */
     public Chronology getChronology() {
         return chrono;
@@ -1292,14 +1322,14 @@
      * <p>
      * This instance is immutable and unaffected by this method call.
      *
-     * @param chrono  the new chronology, not null
+     * @param chrono  the new chronology, null if no override
      * @return a formatter based on this formatter with the requested override chronology, not null
      */
     public DateTimeFormatter withChronology(Chronology chrono) {
         if (Objects.equals(this.chrono, chrono)) {
             return this;
         }
-        return new DateTimeFormatter(printerParser, resolveFields, locale, symbols, chrono, zone);
+        return new DateTimeFormatter(printerParser, resolveFields, locale, symbols, resolverStyle, chrono, zone);
     }

     //-----------------------------------------------------------------------
@@ -1310,7 +1340,7 @@
      * By default, a formatter has no override zone, returning null.
      * See {@link #withZone(ZoneId)} for more details on overriding.
      *
-     * @return the chronology of this formatter, null if no override
+     * @return the override zone of this formatter, null if no override
      */
     public ZoneId getZone() {
         return zone;
@@ -1349,14 +1379,56 @@
      * <p>
      * This instance is immutable and unaffected by this method call.
      *
-     * @param zone  the new override zone, not null
+     * @param zone  the new override zone, null if no override
      * @return a formatter based on this formatter with the requested override zone, not null
      */
     public DateTimeFormatter withZone(ZoneId zone) {
         if (Objects.equals(this.zone, zone)) {
             return this;
         }
-        return new DateTimeFormatter(printerParser, resolveFields, locale, symbols, chrono, zone);
+        return new DateTimeFormatter(printerParser, resolveFields, locale, symbols, resolverStyle, chrono, zone);
+    }
+
+    //-----------------------------------------------------------------------
+    /**
+     * Gets the resolver style to use during  parsing.
+     * <p>
+     * This returns the resolver style, used during the second phase of parsing
+     * when fields are resolved into dates and times.
+     * By default, a formatter has the {@link ResolverStyle#SMART SMART} resolver style.
+     * See {@link #withResolverStyle(ResolverStyle)} for more details.
+     *
+     * @return the resolver style of this formatter, not null
+     */
+    public ResolverStyle getResolverStyle() {
+        return resolverStyle;
+    }
+
+    /**
+     * Returns a copy of this formatter with a new resolver style.
+     * <p>
+     * This returns a formatter with similar state to this formatter but
+     * with the resolver style set. By default, a formatter has the
+     * {@link ResolverStyle#SMART SMART} resolver style.
+     * <p>
+     * Changing the resolver style only has an effect during parsing.
+     * Parsing a text string occurs in two phases.
+     * Phase 1 is a basic text parse according to the fields added to the builder.
+     * Phase 2 resolves the parsed field-value pairs into date and/or time objects.
+     * The resolver style is used to control how phase 2, resolving, happens.
+     * See {@code ResolverStyle} for more information on the options available.
+     * <p>
+     * This instance is immutable and unaffected by this method call.
+     *
+     * @param resolverStyle  the new resolver style, not null
+     * @return a formatter based on this formatter with the requested resolver style, not null
+     */
+    public DateTimeFormatter withResolverStyle(ResolverStyle resolverStyle) {
+        Objects.requireNonNull(resolverStyle, "resolverStyle");
+        if (Objects.equals(this.resolverStyle, resolverStyle)) {
+            return this;
+        }
+        return new DateTimeFormatter(printerParser, resolveFields, locale, symbols, resolverStyle, chrono, zone);
     }

     //-----------------------------------------------------------------------
@@ -1606,7 +1678,7 @@
                         pos.getIndex(), text, pos.getIndex());
             }
         }
-        return unresolved.resolve(resolveFields);
+        return unresolved.resolve(resolveFields, resolverStyle);
     }

     /**
@@ -1800,7 +1872,7 @@
                 return null;
             }
             try {
-                TemporalAccessor resolved = unresolved.resolve(formatter.resolveFields);
+                TemporalAccessor resolved = unresolved.resolve(formatter.resolveFields, formatter.resolverStyle);
                 if (parseType == null) {
                     return resolved;
                 }
diff -r 4517b8abe0eb -r 7eb1e6fa26d0 src/share/classes/java/time/format/DateTimeFormatterBuilder.java
--- a/src/share/classes/java/time/format/DateTimeFormatterBuilder.java  Mon Apr 01 02:29:21 2013 +0100
+++ b/src/share/classes/java/time/format/DateTimeFormatterBuilder.java  Mon Apr 01 22:32:42 2013 +0100
@@ -1895,8 +1895,9 @@
      * Completes this builder by creating the {@code DateTimeFormatter}
      * using the default locale.
      * <p>
-     * This will create a formatter with the {@link Locale#getDefault(Locale.Category) default FORMAT locale}.
+     * This will create a formatter with the {@linkplain Locale#getDefault(Locale.Category) default FORMAT locale}.
      * Numbers will be printed and parsed using the standard non-localized set of symbols.
+     * The resolver style will be {@link ResolverStyle#SMART SMART}.
      * <p>
      * Calling this method will end any open optional sections by repeatedly
      * calling {@link #optionalEnd()} before creating the formatter.
@@ -1907,7 +1908,7 @@
      * @return the created formatter, not null
      */
     public DateTimeFormatter toFormatter() {
-        return toFormatter(Locale.getDefault(Locale.Category.FORMAT), null);
+        return toFormatter(Locale.getDefault(Locale.Category.FORMAT));
     }

     /**
@@ -1916,6 +1917,7 @@
      * <p>
      * This will create a formatter with the specified locale.
      * Numbers will be printed and parsed using the standard non-localized set of symbols.
+     * The resolver style will be {@link ResolverStyle#SMART SMART}.
      * <p>
      * Calling this method will end any open optional sections by repeatedly
      * calling {@link #optionalEnd()} before creating the formatter.
@@ -1927,27 +1929,18 @@
      * @return the created formatter, not null
      */
     public DateTimeFormatter toFormatter(Locale locale) {
-        return toFormatter(locale, null);
+        return toFormatter(locale, ResolverStyle.SMART, null);
     }

     /**
-     * Completes this builder by creating the {@code DateTimeFormatter}
-     * using the default locale and setting the chronlogy to ISO.
-     * <p>
-     * This will create a formatter with the {@link Locale#getDefault(Locale.Category) default FORMAT locale}.
-     * Numbers will be printed and parsed using the standard non-localized set of symbols.
-     * The chronology will be set to ISO.
-     * <p>
-     * Calling this method will end any open optional sections by repeatedly
-     * calling {@link #optionalEnd()} before creating the formatter.
-     * <p>
-     * This builder can still be used after creating the formatter if desired,
-     * although the state may have been changed by calls to {@code optionalEnd}.
+     * Completes this builder by creating the formatter.
+     * This uses the default locale.
      *
+     * @param resolverStyle  the resolver style to use, not null
      * @return the created formatter, not null
      */
-    DateTimeFormatter toFormatterIso() {
-        return toFormatter(Locale.getDefault(Locale.Category.FORMAT), IsoChronology.INSTANCE);
+    DateTimeFormatter toFormatter(ResolverStyle resolverStyle, Chronology chrono) {
+        return toFormatter(Locale.getDefault(Locale.Category.FORMAT), resolverStyle, chrono);
     }

     /**
@@ -1957,13 +1950,14 @@
      * @param chrono  the chronology to use, may be null
      * @return the created formatter, not null
      */
-    private DateTimeFormatter toFormatter(Locale locale, Chronology chrono) {
+    private DateTimeFormatter toFormatter(Locale locale, ResolverStyle resolverStyle, Chronology chrono) {
         Objects.requireNonNull(locale, "locale");
         while (active.parent != null) {
             optionalEnd();
         }
         CompositePrinterParser pp = new CompositePrinterParser(printerParsers, false);
-        return new DateTimeFormatter(pp, resolveFields, locale, DateTimeFormatSymbols.STANDARD, chrono, null);
+        return new DateTimeFormatter(pp, resolveFields,
+                locale, DateTimeFormatSymbols.STANDARD, resolverStyle, chrono, null);
     }

     //-----------------------------------------------------------------------
diff -r 4517b8abe0eb -r 7eb1e6fa26d0 src/share/classes/java/time/format/Parsed.java
--- a/src/share/classes/java/time/format/Parsed.java    Mon Apr 01 02:29:21 2013 +0100
+++ b/src/share/classes/java/time/format/Parsed.java    Mon Apr 01 22:32:42 2013 +0100
@@ -132,6 +132,10 @@
      */
     Chronology effectiveChrono;
     /**
+     * The resolver style to use.
+     */
+    private ResolverStyle resolverStyle;
+    /**
      * The resolved date.
      */
     private ChronoLocalDate<?> date;
@@ -214,14 +218,21 @@
      * Resolves the fields in this context.
      *
      * @param resolveFields  the fields to use for resolving, null for all fields
+     * @param resolverStyle  the resolver style, not null
      * @return this, for method chaining
      * @throws DateTimeException if resolving one field results in a value for
      *  another field that is in conflict
      */
-    TemporalAccessor resolve(List<TemporalField> resolveFields) {
+    TemporalAccessor resolve(List<TemporalField> resolveFields, ResolverStyle resolverStyle) {
         if (resolveFields != null) {
             fieldValues.keySet().retainAll(resolveFields);
         }
+        if (resolverStyle == ResolverStyle.STRICT) {
+            for (Entry<TemporalField, Long> entry : fieldValues.entrySet()) {
+                entry.getKey().range().checkValidValue(entry.getValue(), entry.getKey());
+            }
+        }
+        this.resolverStyle = resolverStyle;
         chrono = effectiveChrono;
         resolveFields();
         resolveTimeLenient();
diff -r 4517b8abe0eb -r 7eb1e6fa26d0 src/share/classes/java/time/format/ResolverStyle.java
--- /dev/null   Thu Jan 01 00:00:00 1970 +0000
+++ b/src/share/classes/java/time/format/ResolverStyle.java Mon Apr 01 22:32:42 2013 +0100
@@ -0,0 +1,116 @@
+/*
+ * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/*
+ * This file is available under and governed by the GNU General Public
+ * License version 2 only, as published by the Free Software Foundation.
+ * However, the following notice accompanied the original version of this
+ * file:
+ *
+ * Copyright (c) 2008-2013, Stephen Colebourne & Michael Nascimento Santos
+ *
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ *  * Redistributions of source code must retain the above copyright notice,
+ *    this list of conditions and the following disclaimer.
+ *
+ *  * Redistributions in binary form must reproduce the above copyright notice,
+ *    this list of conditions and the following disclaimer in the documentation
+ *    and/or other materials provided with the distribution.
+ *
+ *  * Neither the name of JSR-310 nor the names of its contributors
+ *    may be used to endorse or promote products derived from this software
+ *    without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+package java.time.format;
+
+/**
+ * Enumeration of different ways to resolve dates and times.
+ * <p>
+ * Parsing a text string occurs in two phases.
+ * Phase 1 is a basic text parse according to the fields added to the builder.
+ * Phase 2 resolves the parsed field-value pairs into date and/or time objects.
+ * This style is used to control how phase 2, resolving, happens.
+ *
+ * <h3>Specification for implementors</h3>
+ * This is an immutable and thread-safe enum.
+ *
+ * @since 1.8
+ */
+public enum ResolverStyle {
+
+    /**
+     * Style to resolve dates and times strictly.
+     * <p>
+     * Using strict resolution will ensure that all parsed values are within
+     * the outer range of valid values for the field. Individual fields may
+     * be further processed for strictness.
+     * <p>
+     * For example, resolving year-month and day-of-month in the ISO calendar
+     * system using strict mode will ensure that the day-of-month is valid
+     * for the year-month, rejecting invalid values.
+     */
+    STRICT,
+    /**
+     * Style to resolve dates and times in a smart, or intelligent, manner.
+     * <p>
+     * Using smart resolution will perform the a sensible default for each
+     * field, which may be the same as strict, the same as lenient, or a third
+     * behavior. Individual fields will interpret this differently.
+     * <p>
+     * For example, resolving year-month and day-of-month in the ISO calendar
+     * system using smart mode will ensure that the day-of-month is valid
+     * for the year-month, rejecting invalid values, with the exception that
+     * February 29th in a year other than a leap year will be converted to
+     * February 28th.
+     */
+    SMART,
+    /**
+     * Style to resolve dates and times leniently.
+     * <p>
+     * Using lenient resolution will resolve the values in an appropriate
+     * lenient manner. Individual fields will interpret this differently.
+     * <p>
+     * For example, lenient mode allows the month in the ISO calendar system
+     * to be outside the range 1 to 12.
+     */
+    LENIENT;
+
+}
diff -r 4517b8abe0eb -r 7eb1e6fa26d0 test/java/time/tck/java/time/format/TCKDateTimeFormatters.java
--- a/test/java/time/tck/java/time/format/TCKDateTimeFormatters.java    Mon Apr 01 02:29:21 2013 +0100
+++ b/test/java/time/tck/java/time/format/TCKDateTimeFormatters.java    Mon Apr 01 22:32:42 2013 +0100
@@ -88,6 +88,7 @@
 import java.time.format.DateTimeFormatter;
 import java.time.format.DateTimeParseException;
 import java.time.format.FormatStyle;
+import java.time.format.ResolverStyle;
 import java.time.format.TextStyle;
 import java.time.temporal.IsoFields;
 import java.time.temporal.TemporalAccessor;
@@ -168,23 +169,31 @@
     //-----------------------------------------------------------------------
     //-----------------------------------------------------------------------
     @Test
-    public void test_ofLocalizedDate_chronology() {
+    public void test_ofLocalizedDate_basics() {
         assertEquals(DateTimeFormatter.ofLocalizedDate(FormatStyle.FULL).getChronology(), IsoChronology.INSTANCE);
+        assertEquals(DateTimeFormatter.ofLocalizedDate(FormatStyle.FULL).getZone(), null);
+        assertEquals(DateTimeFormatter.ofLocalizedDate(FormatStyle.FULL).getResolverStyle(), ResolverStyle.SMART);
     }

     @Test
-    public void test_ofLocalizedTime_chronology() {
+    public void test_ofLocalizedTime_basics() {
         assertEquals(DateTimeFormatter.ofLocalizedTime(FormatStyle.FULL).getChronology(), IsoChronology.INSTANCE);
+        assertEquals(DateTimeFormatter.ofLocalizedTime(FormatStyle.FULL).getZone(), null);
+        assertEquals(DateTimeFormatter.ofLocalizedTime(FormatStyle.FULL).getResolverStyle(), ResolverStyle.SMART);
     }

     @Test
-    public void test_ofLocalizedDateTime1_chronology() {
+    public void test_ofLocalizedDateTime1_basics() {
         assertEquals(DateTimeFormatter.ofLocalizedDateTime(FormatStyle.FULL).getChronology(), IsoChronology.INSTANCE);
+        assertEquals(DateTimeFormatter.ofLocalizedDateTime(FormatStyle.FULL).getZone(), null);
+        assertEquals(DateTimeFormatter.ofLocalizedDateTime(FormatStyle.FULL).getResolverStyle(), ResolverStyle.SMART);
     }

     @Test
-    public void test_ofLocalizedDateTime2_chronology() {
+    public void test_ofLocalizedDateTime2_basics() {
         assertEquals(DateTimeFormatter.ofLocalizedDateTime(FormatStyle.FULL, FormatStyle.MEDIUM).getChronology(), IsoChronology.INSTANCE);
+        assertEquals(DateTimeFormatter.ofLocalizedDateTime(FormatStyle.FULL, FormatStyle.MEDIUM).getZone(), null);
+        assertEquals(DateTimeFormatter.ofLocalizedDateTime(FormatStyle.FULL, FormatStyle.MEDIUM).getResolverStyle(), ResolverStyle.SMART);
     }

     //-----------------------------------------------------------------------
@@ -275,8 +284,10 @@
     }

     @Test
-    public void test_isoLocalDate_chronology() {
+    public void test_isoLocalDate_basics() {
         assertEquals(DateTimeFormatter.ISO_LOCAL_DATE.getChronology(), IsoChronology.INSTANCE);
+        assertEquals(DateTimeFormatter.ISO_LOCAL_DATE.getZone(), null);
+        assertEquals(DateTimeFormatter.ISO_LOCAL_DATE.getResolverStyle(), ResolverStyle.STRICT);
     }

     //-----------------------------------------------------------------------
@@ -331,8 +342,10 @@
     }

     @Test
-    public void test_isoOffsetDate_chronology() {
+    public void test_isoOffsetDate_basics() {
         assertEquals(DateTimeFormatter.ISO_OFFSET_DATE.getChronology(), IsoChronology.INSTANCE);
+        assertEquals(DateTimeFormatter.ISO_OFFSET_DATE.getZone(), null);
+        assertEquals(DateTimeFormatter.ISO_OFFSET_DATE.getResolverStyle(), ResolverStyle.STRICT);
     }

     //-----------------------------------------------------------------------
@@ -389,8 +402,10 @@
     }

     @Test
-    public void test_isoDate_chronology() {
+    public void test_isoDate_basics() {
         assertEquals(DateTimeFormatter.ISO_DATE.getChronology(), IsoChronology.INSTANCE);
+        assertEquals(DateTimeFormatter.ISO_DATE.getZone(), null);
+        assertEquals(DateTimeFormatter.ISO_DATE.getResolverStyle(), ResolverStyle.STRICT);
     }

     //-----------------------------------------------------------------------
@@ -457,8 +472,10 @@
     }

     @Test
-    public void test_isoLocalTime_chronology() {
+    public void test_isoLocalTime_basics() {
         assertEquals(DateTimeFormatter.ISO_LOCAL_TIME.getChronology(), null);
+        assertEquals(DateTimeFormatter.ISO_LOCAL_TIME.getZone(), null);
+        assertEquals(DateTimeFormatter.ISO_LOCAL_TIME.getResolverStyle(), ResolverStyle.STRICT);
     }

     //-----------------------------------------------------------------------
@@ -525,8 +542,10 @@
     }

     @Test
-    public void test_isoOffsetTime_chronology() {
+    public void test_isoOffsetTime_basics() {
         assertEquals(DateTimeFormatter.ISO_OFFSET_TIME.getChronology(), null);
+        assertEquals(DateTimeFormatter.ISO_OFFSET_TIME.getZone(), null);
+        assertEquals(DateTimeFormatter.ISO_OFFSET_TIME.getResolverStyle(), ResolverStyle.STRICT);
     }

     //-----------------------------------------------------------------------
@@ -595,8 +614,10 @@
     }

     @Test
-    public void test_isoTime_chronology() {
+    public void test_isoTime_basics() {
         assertEquals(DateTimeFormatter.ISO_TIME.getChronology(), null);
+        assertEquals(DateTimeFormatter.ISO_TIME.getZone(), null);
+        assertEquals(DateTimeFormatter.ISO_TIME.getResolverStyle(), ResolverStyle.STRICT);
     }

     //-----------------------------------------------------------------------
@@ -672,8 +693,10 @@
     }

     @Test
-    public void test_isoLocalDateTime_chronology() {
+    public void test_isoLocalDateTime_basics() {
         assertEquals(DateTimeFormatter.ISO_LOCAL_DATE_TIME.getChronology(), IsoChronology.INSTANCE);
+        assertEquals(DateTimeFormatter.ISO_LOCAL_DATE_TIME.getZone(), null);
+        assertEquals(DateTimeFormatter.ISO_LOCAL_DATE_TIME.getResolverStyle(), ResolverStyle.STRICT);
     }

     //-----------------------------------------------------------------------
@@ -750,8 +773,10 @@
     }

     @Test
-    public void test_isoOffsetDateTime_chronology() {
+    public void test_isoOffsetDateTime_basics() {
         assertEquals(DateTimeFormatter.ISO_OFFSET_DATE_TIME.getChronology(), IsoChronology.INSTANCE);
+        assertEquals(DateTimeFormatter.ISO_OFFSET_DATE_TIME.getZone(), null);
+        assertEquals(DateTimeFormatter.ISO_OFFSET_DATE_TIME.getResolverStyle(), ResolverStyle.STRICT);
     }

     //-----------------------------------------------------------------------
@@ -841,8 +866,10 @@
     }

     @Test
-    public void test_isoZonedDateTime_chronology() {
+    public void test_isoZonedDateTime_basics() {
         assertEquals(DateTimeFormatter.ISO_ZONED_DATE_TIME.getChronology(), IsoChronology.INSTANCE);
+        assertEquals(DateTimeFormatter.ISO_ZONED_DATE_TIME.getZone(), null);
+        assertEquals(DateTimeFormatter.ISO_ZONED_DATE_TIME.getResolverStyle(), ResolverStyle.STRICT);
     }

     //-----------------------------------------------------------------------
@@ -924,8 +951,10 @@
     }

     @Test
-    public void test_isoDateTime_chronology() {
+    public void test_isoDateTime_basics() {
         assertEquals(DateTimeFormatter.ISO_DATE_TIME.getChronology(), IsoChronology.INSTANCE);
+        assertEquals(DateTimeFormatter.ISO_DATE_TIME.getZone(), null);
+        assertEquals(DateTimeFormatter.ISO_DATE_TIME.getResolverStyle(), ResolverStyle.STRICT);
     }

     //-----------------------------------------------------------------------
@@ -997,8 +1026,10 @@
     }

     @Test
-    public void test_isoOrdinalDate_chronology() {
+    public void test_isoOrdinalDate_basics() {
         assertEquals(DateTimeFormatter.ISO_ORDINAL_DATE.getChronology(), IsoChronology.INSTANCE);
+        assertEquals(DateTimeFormatter.ISO_ORDINAL_DATE.getZone(), null);
+        assertEquals(DateTimeFormatter.ISO_ORDINAL_DATE.getResolverStyle(), ResolverStyle.STRICT);
     }

     //-----------------------------------------------------------------------
@@ -1060,8 +1091,10 @@
     }

     @Test
-    public void test_basicIsoDate_chronology() {
+    public void test_basicIsoDate_basics() {
         assertEquals(DateTimeFormatter.BASIC_ISO_DATE.getChronology(), IsoChronology.INSTANCE);
+        assertEquals(DateTimeFormatter.BASIC_ISO_DATE.getZone(), null);
+        assertEquals(DateTimeFormatter.BASIC_ISO_DATE.getResolverStyle(), ResolverStyle.STRICT);
     }

     //-----------------------------------------------------------------------
@@ -1138,8 +1171,20 @@
     }

     @Test
-    public void test_isoWeekDate_chronology() {
+    public void test_isoWeekDate_basics() {
         assertEquals(DateTimeFormatter.ISO_WEEK_DATE.getChronology(), IsoChronology.INSTANCE);
+        assertEquals(DateTimeFormatter.ISO_WEEK_DATE.getZone(), null);
+        assertEquals(DateTimeFormatter.ISO_WEEK_DATE.getResolverStyle(), ResolverStyle.STRICT);
+    }
+
+    //-----------------------------------------------------------------------
+    //-----------------------------------------------------------------------
+    //-----------------------------------------------------------------------
+    @Test
+    public void test_isoInstant_basics() {
+        assertEquals(DateTimeFormatter.ISO_INSTANT.getChronology(), null);
+        assertEquals(DateTimeFormatter.ISO_INSTANT.getZone(), null);
+        assertEquals(DateTimeFormatter.ISO_INSTANT.getResolverStyle(), ResolverStyle.STRICT);
     }

     //-----------------------------------------------------------------------
@@ -1174,8 +1219,10 @@
     }

     @Test
-    public void test_rfc1123_chronology() {
+    public void test_rfc1123_basics() {
         assertEquals(DateTimeFormatter.RFC_1123_DATE_TIME.getChronology(), IsoChronology.INSTANCE);
+        assertEquals(DateTimeFormatter.RFC_1123_DATE_TIME.getZone(), null);
+        assertEquals(DateTimeFormatter.RFC_1123_DATE_TIME.getResolverStyle(), ResolverStyle.SMART);
     }

     //-----------------------------------------------------------------------
jodastephen commented 11 years ago

The idea is to add a ResolverStyle argument to TemporalField.resolve() and Chronology.resolveDate(), so that the implementations can decide what to do.

jodastephen commented 11 years ago

See http://hg.openjdk.java.net/threeten/threeten/jdk/rev/fa5461db0139 http://hg.openjdk.java.net/threeten/threeten/jdk/rev/d8d90fa2a73a http://hg.openjdk.java.net/threeten/threeten/jdk/rev/35a4c497f286 http://hg.openjdk.java.net/threeten/threeten/jdk/rev/75c0b557aaec

Code still needed in Chronlogy and WeekFields. Plus tests and documentation.

jodastephen commented 11 years ago

I don't think there is any more to do here.