jdk/src/share/classes/java/time/format/DateTimePrintContext.java
changeset 15658 55b829ca2334
parent 15289 3ac550392e43
child 16852 60207b2b4b42
equal deleted inserted replaced
15657:c588664d547e 15658:55b829ca2334
    65 import static java.time.temporal.ChronoField.INSTANT_SECONDS;
    65 import static java.time.temporal.ChronoField.INSTANT_SECONDS;
    66 
    66 
    67 import java.time.DateTimeException;
    67 import java.time.DateTimeException;
    68 import java.time.Instant;
    68 import java.time.Instant;
    69 import java.time.ZoneId;
    69 import java.time.ZoneId;
    70 import java.time.temporal.Chrono;
    70 import java.time.chrono.Chronology;
    71 import java.time.temporal.ChronoField;
    71 import java.time.temporal.ChronoField;
    72 import java.time.temporal.ChronoLocalDate;
    72 import java.time.chrono.ChronoLocalDate;
    73 import java.time.temporal.Queries;
    73 import java.time.temporal.Queries;
    74 import java.time.temporal.TemporalAccessor;
    74 import java.time.temporal.TemporalAccessor;
    75 import java.time.temporal.TemporalField;
    75 import java.time.temporal.TemporalField;
    76 import java.time.temporal.TemporalQuery;
    76 import java.time.temporal.TemporalQuery;
    77 import java.time.temporal.ValueRange;
    77 import java.time.temporal.ValueRange;
    79 import java.util.Objects;
    79 import java.util.Objects;
    80 
    80 
    81 /**
    81 /**
    82  * Context object used during date and time printing.
    82  * Context object used during date and time printing.
    83  * <p>
    83  * <p>
    84  * This class provides a single wrapper to items used in the print.
    84  * This class provides a single wrapper to items used in the format.
    85  *
    85  *
    86  * <h3>Specification for implementors</h3>
    86  * <h3>Specification for implementors</h3>
    87  * This class is a mutable context intended for use from a single thread.
    87  * This class is a mutable context intended for use from a single thread.
    88  * Usage of the class is thread-safe within standard printing as the framework creates
    88  * Usage of the class is thread-safe within standard printing as the framework creates
    89  * a new instance of the class for each print and printing is single-threaded.
    89  * a new instance of the class for each format and printing is single-threaded.
    90  *
    90  *
    91  * @since 1.8
    91  * @since 1.8
    92  */
    92  */
    93 final class DateTimePrintContext {
    93 final class DateTimePrintContext {
    94 
    94 
   107 
   107 
   108     /**
   108     /**
   109      * Creates a new instance of the context.
   109      * Creates a new instance of the context.
   110      *
   110      *
   111      * @param temporal  the temporal object being output, not null
   111      * @param temporal  the temporal object being output, not null
   112      * @param formatter  the formatter controlling the print, not null
   112      * @param formatter  the formatter controlling the format, not null
   113      */
   113      */
   114     DateTimePrintContext(TemporalAccessor temporal, DateTimeFormatter formatter) {
   114     DateTimePrintContext(TemporalAccessor temporal, DateTimeFormatter formatter) {
   115         super();
   115         super();
   116         this.temporal = adjust(temporal, formatter);
   116         this.temporal = adjust(temporal, formatter);
   117         this.formatter = formatter;
   117         this.formatter = formatter;
   118     }
   118     }
   119 
   119 
   120     private static TemporalAccessor adjust(final TemporalAccessor temporal, DateTimeFormatter formatter) {
   120     private static TemporalAccessor adjust(final TemporalAccessor temporal, DateTimeFormatter formatter) {
   121         // normal case first
   121         // normal case first
   122         Chrono<?> overrideChrono = formatter.getChrono();
   122         Chronology overrideChrono = formatter.getChronology();
   123         ZoneId overrideZone = formatter.getZone();
   123         ZoneId overrideZone = formatter.getZone();
   124         if (overrideChrono == null && overrideZone == null) {
   124         if (overrideChrono == null && overrideZone == null) {
   125             return temporal;
   125             return temporal;
   126         }
   126         }
   127 
   127 
   128         // ensure minimal change
   128         // ensure minimal change
   129         Chrono<?> temporalChrono = Chrono.from(temporal);  // default to ISO, handles Instant
   129         Chronology temporalChrono = Chronology.from(temporal);  // default to ISO, handles Instant
   130         ZoneId temporalZone = temporal.query(Queries.zone());  // zone then offset, handles OffsetDateTime
   130         ZoneId temporalZone = temporal.query(Queries.zone());  // zone then offset, handles OffsetDateTime
   131         if (temporal.isSupported(EPOCH_DAY) == false || Objects.equals(overrideChrono, temporalChrono)) {
   131         if (temporal.isSupported(EPOCH_DAY) == false || Objects.equals(overrideChrono, temporalChrono)) {
   132             overrideChrono = null;
   132             overrideChrono = null;
   133         }
   133         }
   134         if (temporal.isSupported(INSTANT_SECONDS) == false || Objects.equals(overrideZone, temporalZone)) {
   134         if (temporal.isSupported(INSTANT_SECONDS) == false || Objects.equals(overrideZone, temporalZone)) {
   142         if (overrideChrono != null && overrideZone != null) {
   142         if (overrideChrono != null && overrideZone != null) {
   143             return overrideChrono.zonedDateTime(Instant.from(temporal), overrideZone);
   143             return overrideChrono.zonedDateTime(Instant.from(temporal), overrideZone);
   144         } else if (overrideZone != null) {
   144         } else if (overrideZone != null) {
   145             return temporalChrono.zonedDateTime(Instant.from(temporal), overrideZone);
   145             return temporalChrono.zonedDateTime(Instant.from(temporal), overrideZone);
   146         } else {  // overrideChrono != null
   146         } else {  // overrideChrono != null
   147             // need class here to handle non-standard cases like OffsetDate
   147             // need class here to handle non-standard cases
   148             final ChronoLocalDate<?> date = overrideChrono.date(temporal);
   148             final ChronoLocalDate date = overrideChrono.date(temporal);
   149             return new TemporalAccessor() {
   149             return new TemporalAccessor() {
   150                 @Override
   150                 @Override
   151                 public boolean isSupported(TemporalField field) {
   151                 public boolean isSupported(TemporalField field) {
   152                     return temporal.isSupported(field);
   152                     return temporal.isSupported(field);
   153                 }
   153                 }
   158                             return date.range(field);
   158                             return date.range(field);
   159                         } else {
   159                         } else {
   160                             return temporal.range(field);
   160                             return temporal.range(field);
   161                         }
   161                         }
   162                     }
   162                     }
   163                     return field.doRange(this);
   163                     return field.rangeRefinedBy(this);
   164                 }
   164                 }
   165                 @Override
   165                 @Override
   166                 public long getLong(TemporalField field) {
   166                 public long getLong(TemporalField field) {
   167                     if (field instanceof ChronoField) {
   167                     if (field instanceof ChronoField) {
   168                         if (((ChronoField) field).isDateField()) {
   168                         if (((ChronoField) field).isDateField()) {
   169                             return date.getLong(field);
   169                             return date.getLong(field);
   170                         } else {
   170                         } else {
   171                             return temporal.getLong(field);
   171                             return temporal.getLong(field);
   172                         }
   172                         }
   173                     }
   173                     }
   174                     return field.doGet(this);
   174                     return field.getFrom(this);
   175                 }
   175                 }
       
   176                 @SuppressWarnings("unchecked")
   176                 @Override
   177                 @Override
   177                 public <R> R query(TemporalQuery<R> query) {
   178                 public <R> R query(TemporalQuery<R> query) {
   178                     if (query == Queries.zoneId() || query == Queries.chrono() || query == Queries.precision()) {
   179                     if (query == Queries.chronology()) {
       
   180                         return (R) date.getChronology();
       
   181                     }
       
   182                     if (query == Queries.zoneId() || query == Queries.precision()) {
   179                         return temporal.query(query);
   183                         return temporal.query(query);
   180                     }
   184                     }
   181                     return query.queryFrom(this);
   185                     return query.queryFrom(this);
   182                 }
   186                 }
   183             };
   187             };
   195     }
   199     }
   196 
   200 
   197     /**
   201     /**
   198      * Gets the locale.
   202      * Gets the locale.
   199      * <p>
   203      * <p>
   200      * This locale is used to control localization in the print output except
   204      * This locale is used to control localization in the format output except
   201      * where localization is controlled by the symbols.
   205      * where localization is controlled by the symbols.
   202      *
   206      *
   203      * @return the locale, not null
   207      * @return the locale, not null
   204      */
   208      */
   205     Locale getLocale() {
   209     Locale getLocale() {