< prev index next >

src/java.base/share/classes/java/time/format/DateTimeFormatterBuilder.java

Print this page


   1 /*
   2  * Copyright (c) 2012, 2018, Oracle and/or its affiliates. All rights reserved.
   3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
   4  *
   5  * This code is free software; you can redistribute it and/or modify it
   6  * under the terms of the GNU General Public License version 2 only, as
   7  * published by the Free Software Foundation.  Oracle designates this
   8  * particular file as subject to the "Classpath" exception as provided
   9  * by Oracle in the LICENSE file that accompanied this code.
  10  *
  11  * This code is distributed in the hope that it will be useful, but WITHOUT
  12  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  13  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
  14  * version 2 for more details (a copy is included in the LICENSE file that
  15  * accompanied this code).
  16  *
  17  * You should have received a copy of the GNU General Public License version
  18  * 2 along with this work; if not, write to the Free Software Foundation,
  19  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
  20  *
  21  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
  22  * or visit www.oracle.com if you need additional information or have any


  68 import static java.time.temporal.ChronoField.MONTH_OF_YEAR;
  69 import static java.time.temporal.ChronoField.NANO_OF_SECOND;
  70 import static java.time.temporal.ChronoField.OFFSET_SECONDS;
  71 import static java.time.temporal.ChronoField.SECOND_OF_MINUTE;
  72 import static java.time.temporal.ChronoField.YEAR;
  73 import static java.time.temporal.ChronoField.ERA;
  74 
  75 import java.lang.ref.SoftReference;
  76 import java.math.BigDecimal;
  77 import java.math.BigInteger;
  78 import java.math.RoundingMode;
  79 import java.text.ParsePosition;
  80 import java.time.DateTimeException;
  81 import java.time.Instant;
  82 import java.time.LocalDate;
  83 import java.time.LocalDateTime;
  84 import java.time.LocalTime;
  85 import java.time.ZoneId;
  86 import java.time.ZoneOffset;
  87 import java.time.chrono.ChronoLocalDate;
  88 import java.time.chrono.ChronoLocalDateTime;
  89 import java.time.chrono.Chronology;
  90 import java.time.chrono.Era;
  91 import java.time.chrono.IsoChronology;
  92 import java.time.format.DateTimeTextProvider.LocaleStore;
  93 import java.time.temporal.ChronoField;
  94 import java.time.temporal.IsoFields;
  95 import java.time.temporal.JulianFields;
  96 import java.time.temporal.TemporalAccessor;
  97 import java.time.temporal.TemporalField;
  98 import java.time.temporal.TemporalQueries;
  99 import java.time.temporal.TemporalQuery;
 100 import java.time.temporal.ValueRange;
 101 import java.time.temporal.WeekFields;
 102 import java.time.zone.ZoneRulesProvider;
 103 import java.util.AbstractMap.SimpleImmutableEntry;
 104 import java.util.ArrayList;
 105 import java.util.Arrays;
 106 import java.util.Collections;
 107 import java.util.Comparator;
 108 import java.util.HashMap;
 109 import java.util.HashSet;
 110 import java.util.Iterator;
 111 import java.util.LinkedHashMap;
 112 import java.util.List;
 113 import java.util.Locale;
 114 import java.util.Map;
 115 import java.util.Map.Entry;
 116 import java.util.Objects;
 117 import java.util.Set;
 118 import java.util.TimeZone;
 119 import java.util.concurrent.ConcurrentHashMap;
 120 import java.util.concurrent.ConcurrentMap;
 121 
 122 import sun.text.spi.JavaTimeDateTimePatternProvider;
 123 import sun.util.locale.provider.CalendarDataUtility;
 124 import sun.util.locale.provider.LocaleProviderAdapter;
 125 import sun.util.locale.provider.LocaleResources;
 126 import sun.util.locale.provider.TimeZoneNameUtility;
 127 
 128 /**
 129  * Builder to create date-time formatters.
 130  * <p>
 131  * This allows a {@code DateTimeFormatter} to be created.
 132  * All date-time formatters are created ultimately using this builder.
 133  * <p>
 134  * The basic elements of date-time can all be added:
 135  * <ul>
 136  * <li>Value - a numeric value</li>
 137  * <li>Fraction - a fractional value including the decimal place. Always use this when
 138  * outputting fractions to ensure that the fraction is parsed correctly</li>
 139  * <li>Text - the textual equivalent for the value</li>
 140  * <li>OffsetId/Offset - the {@linkplain ZoneOffset zone offset}</li>
 141  * <li>ZoneId - the {@linkplain ZoneId time-zone} id</li>
 142  * <li>ZoneText - the name of the time-zone</li>
 143  * <li>ChronologyId - the {@linkplain Chronology chronology} id</li>
 144  * <li>ChronologyText - the name of the chronology</li>
 145  * <li>Literal - a text literal</li>


3854         /**
3855          * Constructor.
3856          *
3857          * @param style  the style, not null
3858          */
3859         LocalizedOffsetIdPrinterParser(TextStyle style) {
3860             this.style = style;
3861         }
3862 
3863         private static StringBuilder appendHMS(StringBuilder buf, int t) {
3864             return buf.append((char)(t / 10 + '0'))
3865                       .append((char)(t % 10 + '0'));
3866         }
3867 
3868         @Override
3869         public boolean format(DateTimePrintContext context, StringBuilder buf) {
3870             Long offsetSecs = context.getValue(OFFSET_SECONDS);
3871             if (offsetSecs == null) {
3872                 return false;
3873             }
3874             String gmtText = "GMT";  // TODO: get localized version of 'GMT'




3875             buf.append(gmtText);
3876             int totalSecs = Math.toIntExact(offsetSecs);
3877             if (totalSecs != 0) {
3878                 int absHours = Math.abs((totalSecs / 3600) % 100);  // anything larger than 99 silently dropped
3879                 int absMinutes = Math.abs((totalSecs / 60) % 60);
3880                 int absSeconds = Math.abs(totalSecs % 60);
3881                 buf.append(totalSecs < 0 ? "-" : "+");
3882                 if (style == TextStyle.FULL) {
3883                     appendHMS(buf, absHours);
3884                     buf.append(':');
3885                     appendHMS(buf, absMinutes);
3886                     if (absSeconds != 0) {
3887                        buf.append(':');
3888                        appendHMS(buf, absSeconds);
3889                     }
3890                 } else {
3891                     if (absHours >= 10) {
3892                         buf.append((char)(absHours / 10 + '0'));
3893                     }
3894                     buf.append((char)(absHours % 10 + '0'));


3900                             appendHMS(buf, absSeconds);
3901                         }
3902                     }
3903                 }
3904             }
3905             return true;
3906         }
3907 
3908         int getDigit(CharSequence text, int position) {
3909             char c = text.charAt(position);
3910             if (c < '0' || c > '9') {
3911                 return -1;
3912             }
3913             return c - '0';
3914         }
3915 
3916         @Override
3917         public int parse(DateTimeParseContext context, CharSequence text, int position) {
3918             int pos = position;
3919             int end = text.length();
3920             String gmtText = "GMT";  // TODO: get localized version of 'GMT'




3921             if (!context.subSequenceEquals(text, pos, gmtText, 0, gmtText.length())) {
3922                     return ~position;
3923                 }
3924             pos += gmtText.length();
3925             // parse normal plus/minus offset
3926             int negative = 0;
3927             if (pos == end) {
3928                 return context.setParsedField(OFFSET_SECONDS, 0, position, pos);
3929             }
3930             char sign = text.charAt(pos);  // IOOBE if invalid position
3931             if (sign == '+') {
3932                 negative = 1;
3933             } else if (sign == '-') {
3934                 negative = -1;
3935             } else {
3936                 return context.setParsedField(OFFSET_SECONDS, 0, position, pos);
3937             }
3938             pos++;
3939             int h = 0;
3940             int m = 0;


   1 /*
   2  * Copyright (c) 2012, 2019, Oracle and/or its affiliates. All rights reserved.
   3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
   4  *
   5  * This code is free software; you can redistribute it and/or modify it
   6  * under the terms of the GNU General Public License version 2 only, as
   7  * published by the Free Software Foundation.  Oracle designates this
   8  * particular file as subject to the "Classpath" exception as provided
   9  * by Oracle in the LICENSE file that accompanied this code.
  10  *
  11  * This code is distributed in the hope that it will be useful, but WITHOUT
  12  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  13  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
  14  * version 2 for more details (a copy is included in the LICENSE file that
  15  * accompanied this code).
  16  *
  17  * You should have received a copy of the GNU General Public License version
  18  * 2 along with this work; if not, write to the Free Software Foundation,
  19  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
  20  *
  21  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
  22  * or visit www.oracle.com if you need additional information or have any


  68 import static java.time.temporal.ChronoField.MONTH_OF_YEAR;
  69 import static java.time.temporal.ChronoField.NANO_OF_SECOND;
  70 import static java.time.temporal.ChronoField.OFFSET_SECONDS;
  71 import static java.time.temporal.ChronoField.SECOND_OF_MINUTE;
  72 import static java.time.temporal.ChronoField.YEAR;
  73 import static java.time.temporal.ChronoField.ERA;
  74 
  75 import java.lang.ref.SoftReference;
  76 import java.math.BigDecimal;
  77 import java.math.BigInteger;
  78 import java.math.RoundingMode;
  79 import java.text.ParsePosition;
  80 import java.time.DateTimeException;
  81 import java.time.Instant;
  82 import java.time.LocalDate;
  83 import java.time.LocalDateTime;
  84 import java.time.LocalTime;
  85 import java.time.ZoneId;
  86 import java.time.ZoneOffset;
  87 import java.time.chrono.ChronoLocalDate;

  88 import java.time.chrono.Chronology;
  89 import java.time.chrono.Era;
  90 import java.time.chrono.IsoChronology;
  91 import java.time.format.DateTimeTextProvider.LocaleStore;
  92 import java.time.temporal.ChronoField;
  93 import java.time.temporal.IsoFields;
  94 import java.time.temporal.JulianFields;
  95 import java.time.temporal.TemporalAccessor;
  96 import java.time.temporal.TemporalField;
  97 import java.time.temporal.TemporalQueries;
  98 import java.time.temporal.TemporalQuery;
  99 import java.time.temporal.ValueRange;
 100 import java.time.temporal.WeekFields;
 101 import java.time.zone.ZoneRulesProvider;
 102 import java.util.AbstractMap.SimpleImmutableEntry;
 103 import java.util.ArrayList;
 104 import java.util.Arrays;
 105 import java.util.Collections;
 106 import java.util.Comparator;
 107 import java.util.HashMap;
 108 import java.util.HashSet;
 109 import java.util.Iterator;
 110 import java.util.LinkedHashMap;
 111 import java.util.List;
 112 import java.util.Locale;
 113 import java.util.Map;
 114 import java.util.Map.Entry;
 115 import java.util.Objects;
 116 import java.util.Set;
 117 import java.util.TimeZone;
 118 import java.util.concurrent.ConcurrentHashMap;
 119 import java.util.concurrent.ConcurrentMap;
 120 
 121 import sun.text.spi.JavaTimeDateTimePatternProvider;
 122 import sun.util.locale.provider.CalendarDataUtility;
 123 import sun.util.locale.provider.LocaleProviderAdapter;

 124 import sun.util.locale.provider.TimeZoneNameUtility;
 125 
 126 /**
 127  * Builder to create date-time formatters.
 128  * <p>
 129  * This allows a {@code DateTimeFormatter} to be created.
 130  * All date-time formatters are created ultimately using this builder.
 131  * <p>
 132  * The basic elements of date-time can all be added:
 133  * <ul>
 134  * <li>Value - a numeric value</li>
 135  * <li>Fraction - a fractional value including the decimal place. Always use this when
 136  * outputting fractions to ensure that the fraction is parsed correctly</li>
 137  * <li>Text - the textual equivalent for the value</li>
 138  * <li>OffsetId/Offset - the {@linkplain ZoneOffset zone offset}</li>
 139  * <li>ZoneId - the {@linkplain ZoneId time-zone} id</li>
 140  * <li>ZoneText - the name of the time-zone</li>
 141  * <li>ChronologyId - the {@linkplain Chronology chronology} id</li>
 142  * <li>ChronologyText - the name of the chronology</li>
 143  * <li>Literal - a text literal</li>


3852         /**
3853          * Constructor.
3854          *
3855          * @param style  the style, not null
3856          */
3857         LocalizedOffsetIdPrinterParser(TextStyle style) {
3858             this.style = style;
3859         }
3860 
3861         private static StringBuilder appendHMS(StringBuilder buf, int t) {
3862             return buf.append((char)(t / 10 + '0'))
3863                       .append((char)(t % 10 + '0'));
3864         }
3865 
3866         @Override
3867         public boolean format(DateTimePrintContext context, StringBuilder buf) {
3868             Long offsetSecs = context.getValue(OFFSET_SECONDS);
3869             if (offsetSecs == null) {
3870                 return false;
3871             }
3872             String key = "timezone.gmtZeroFormat";
3873             String gmtText = DateTimeTextProvider.getLocalizedResource(key, context.getLocale());
3874             if(gmtText == null) {
3875                 gmtText = "GMT";  // Default to "GMT"
3876             }
3877             buf.append(gmtText);
3878             int totalSecs = Math.toIntExact(offsetSecs);
3879             if (totalSecs != 0) {
3880                 int absHours = Math.abs((totalSecs / 3600) % 100);  // anything larger than 99 silently dropped
3881                 int absMinutes = Math.abs((totalSecs / 60) % 60);
3882                 int absSeconds = Math.abs(totalSecs % 60);
3883                 buf.append(totalSecs < 0 ? "-" : "+");
3884                 if (style == TextStyle.FULL) {
3885                     appendHMS(buf, absHours);
3886                     buf.append(':');
3887                     appendHMS(buf, absMinutes);
3888                     if (absSeconds != 0) {
3889                        buf.append(':');
3890                        appendHMS(buf, absSeconds);
3891                     }
3892                 } else {
3893                     if (absHours >= 10) {
3894                         buf.append((char)(absHours / 10 + '0'));
3895                     }
3896                     buf.append((char)(absHours % 10 + '0'));


3902                             appendHMS(buf, absSeconds);
3903                         }
3904                     }
3905                 }
3906             }
3907             return true;
3908         }
3909 
3910         int getDigit(CharSequence text, int position) {
3911             char c = text.charAt(position);
3912             if (c < '0' || c > '9') {
3913                 return -1;
3914             }
3915             return c - '0';
3916         }
3917 
3918         @Override
3919         public int parse(DateTimeParseContext context, CharSequence text, int position) {
3920             int pos = position;
3921             int end = text.length();
3922             String key = "timezone.gmtZeroFormat";
3923             String gmtText = DateTimeTextProvider.getLocalizedResource(key, context.getLocale());
3924             if(gmtText == null) {
3925                 gmtText = "GMT";  // Default to "GMT"
3926             }
3927             if (!context.subSequenceEquals(text, pos, gmtText, 0, gmtText.length())) {
3928                     return ~position;
3929                 }
3930             pos += gmtText.length();
3931             // parse normal plus/minus offset
3932             int negative = 0;
3933             if (pos == end) {
3934                 return context.setParsedField(OFFSET_SECONDS, 0, position, pos);
3935             }
3936             char sign = text.charAt(pos);  // IOOBE if invalid position
3937             if (sign == '+') {
3938                 negative = 1;
3939             } else if (sign == '-') {
3940                 negative = -1;
3941             } else {
3942                 return context.setParsedField(OFFSET_SECONDS, 0, position, pos);
3943             }
3944             pos++;
3945             int h = 0;
3946             int m = 0;


< prev index next >