< prev index next >

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

Print this page
rev 57376 : 8235238: Parsing a time string ignores any custom TimeZoneNameProvider
Reviewed-by: joehw, rriggs


  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


4106                     zname = name;
4107                 }
4108             }
4109             buf.append(zname);
4110             return true;
4111         }
4112 
4113         // cache per instance for now
4114         private final Map<Locale, Entry<Integer, SoftReference<PrefixTree>>>
4115             cachedTree = new HashMap<>();
4116         private final Map<Locale, Entry<Integer, SoftReference<PrefixTree>>>
4117             cachedTreeCI = new HashMap<>();
4118 
4119         @Override
4120         protected PrefixTree getTree(DateTimeParseContext context) {
4121             if (textStyle == TextStyle.NARROW) {
4122                 return super.getTree(context);
4123             }
4124             Locale locale = context.getLocale();
4125             boolean isCaseSensitive = context.isCaseSensitive();
4126             Set<String> regionIds = ZoneRulesProvider.getAvailableZoneIds();

4127             int regionIdsSize = regionIds.size();
4128 
4129             Map<Locale, Entry<Integer, SoftReference<PrefixTree>>> cached =
4130                 isCaseSensitive ? cachedTree : cachedTreeCI;
4131 
4132             Entry<Integer, SoftReference<PrefixTree>> entry = null;
4133             PrefixTree tree = null;
4134             String[][] zoneStrings = null;
4135             if ((entry = cached.get(locale)) == null ||
4136                 (entry.getKey() != regionIdsSize ||
4137                 (tree = entry.getValue().get()) == null)) {
4138                 tree = PrefixTree.newTree(context);
4139                 zoneStrings = TimeZoneNameUtility.getZoneStrings(locale);
4140                 for (String[] names : zoneStrings) {
4141                     String zid = names[0];
4142                     if (!regionIds.contains(zid)) {

4143                         continue;
4144                     }
4145                     tree.add(zid, zid);    // don't convert zid -> metazone
4146                     zid = ZoneName.toZid(zid, locale);
4147                     int i = textStyle == TextStyle.FULL ? 1 : 2;
4148                     for (; i < names.length; i += 2) {
4149                         tree.add(names[i], zid);
4150                     }
4151                 }















4152                 // if we have a set of preferred zones, need a copy and
4153                 // add the preferred zones again to overwrite
4154                 if (preferredZones != null) {
4155                     for (String[] names : zoneStrings) {
4156                         String zid = names[0];
4157                         if (!preferredZones.contains(zid) || !regionIds.contains(zid)) {
4158                             continue;
4159                         }
4160                         int i = textStyle == TextStyle.FULL ? 1 : 2;
4161                         for (; i < names.length; i += 2) {
4162                             tree.add(names[i], zid);
4163                        }
4164                     }
4165                 }
4166                 cached.put(locale, new SimpleImmutableEntry<>(regionIdsSize, new SoftReference<>(tree)));
4167             }
4168             return tree;
4169         }
4170     }
4171 
4172     //-----------------------------------------------------------------------
4173     /**
4174      * Prints or parses a zone ID.
4175      */
4176     static class ZoneIdPrinterParser implements DateTimePrinterParser {
4177         private final TemporalQuery<ZoneId> query;




  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.Optional;
 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.TimeZoneNameUtility;
 126 
 127 /**
 128  * Builder to create date-time formatters.
 129  * <p>
 130  * This allows a {@code DateTimeFormatter} to be created.
 131  * All date-time formatters are created ultimately using this builder.
 132  * <p>
 133  * The basic elements of date-time can all be added:
 134  * <ul>
 135  * <li>Value - a numeric value</li>
 136  * <li>Fraction - a fractional value including the decimal place. Always use this when


4107                     zname = name;
4108                 }
4109             }
4110             buf.append(zname);
4111             return true;
4112         }
4113 
4114         // cache per instance for now
4115         private final Map<Locale, Entry<Integer, SoftReference<PrefixTree>>>
4116             cachedTree = new HashMap<>();
4117         private final Map<Locale, Entry<Integer, SoftReference<PrefixTree>>>
4118             cachedTreeCI = new HashMap<>();
4119 
4120         @Override
4121         protected PrefixTree getTree(DateTimeParseContext context) {
4122             if (textStyle == TextStyle.NARROW) {
4123                 return super.getTree(context);
4124             }
4125             Locale locale = context.getLocale();
4126             boolean isCaseSensitive = context.isCaseSensitive();
4127             Set<String> regionIds = new HashSet<>(ZoneRulesProvider.getAvailableZoneIds());
4128             Set<String> nonRegionIds = new HashSet<>(64);
4129             int regionIdsSize = regionIds.size();
4130 
4131             Map<Locale, Entry<Integer, SoftReference<PrefixTree>>> cached =
4132                 isCaseSensitive ? cachedTree : cachedTreeCI;
4133 
4134             Entry<Integer, SoftReference<PrefixTree>> entry = null;
4135             PrefixTree tree = null;
4136             String[][] zoneStrings = null;
4137             if ((entry = cached.get(locale)) == null ||
4138                 (entry.getKey() != regionIdsSize ||
4139                 (tree = entry.getValue().get()) == null)) {
4140                 tree = PrefixTree.newTree(context);
4141                 zoneStrings = TimeZoneNameUtility.getZoneStrings(locale);
4142                 for (String[] names : zoneStrings) {
4143                     String zid = names[0];
4144                     if (!regionIds.remove(zid)) {
4145                         nonRegionIds.add(zid);
4146                         continue;
4147                     }
4148                     tree.add(zid, zid);    // don't convert zid -> metazone
4149                     zid = ZoneName.toZid(zid, locale);
4150                     int i = textStyle == TextStyle.FULL ? 1 : 2;
4151                     for (; i < names.length; i += 2) {
4152                         tree.add(names[i], zid);
4153                     }
4154                 }
4155 
4156                 // add names for provider's custom ids
4157                 final PrefixTree t = tree;
4158                 regionIds.stream()
4159                     .filter(zid -> !zid.startsWith("Etc") && !zid.startsWith("GMT"))
4160                     .forEach(cid -> {
4161                         String[] cidNames = TimeZoneNameUtility.retrieveDisplayNames(cid, locale);
4162                         int i = textStyle == TextStyle.FULL ? 1 : 2;
4163                         for (; i < cidNames.length; i += 2) {
4164                             if (cidNames[i] != null && !cidNames[i].isEmpty()) {
4165                                 t.add(cidNames[i], cid);
4166                             }
4167                         }
4168                     });
4169 
4170                 // if we have a set of preferred zones, need a copy and
4171                 // add the preferred zones again to overwrite
4172                 if (preferredZones != null) {
4173                     for (String[] names : zoneStrings) {
4174                         String zid = names[0];
4175                         if (!preferredZones.contains(zid) || nonRegionIds.contains(zid)) {
4176                             continue;
4177                         }
4178                         int i = textStyle == TextStyle.FULL ? 1 : 2;
4179                         for (; i < names.length; i += 2) {
4180                             tree.add(names[i], zid);
4181                        }
4182                     }
4183                 }
4184                 cached.put(locale, new SimpleImmutableEntry<>(regionIdsSize, new SoftReference<>(tree)));
4185             }
4186             return tree;
4187         }
4188     }
4189 
4190     //-----------------------------------------------------------------------
4191     /**
4192      * Prints or parses a zone ID.
4193      */
4194     static class ZoneIdPrinterParser implements DateTimePrinterParser {
4195         private final TemporalQuery<ZoneId> query;


< prev index next >