1 /* 2 * Copyright (c) 1999, 2017, 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 23 * questions. 24 */ 25 26 package sun.util.locale.provider; 27 28 import java.text.DateFormat; 29 import java.text.SimpleDateFormat; 30 import java.text.spi.DateFormatProvider; 31 import java.util.Calendar; 32 import java.util.Locale; 33 import java.util.MissingResourceException; 34 import java.util.Set; 35 import java.util.TimeZone; 36 37 /** 38 * Concrete implementation of the {@link java.text.spi.DateFormatProvider 39 * DateFormatProvider} class for the JRE LocaleProviderAdapter. 40 * 41 * @author Naoto Sato 42 * @author Masayoshi Okutsu 43 */ 44 public class DateFormatProviderImpl extends DateFormatProvider implements AvailableLanguageTags { 45 private final LocaleProviderAdapter.Type type; 46 private final Set<String> langtags; 47 48 public DateFormatProviderImpl(LocaleProviderAdapter.Type type, Set<String> langtags) { 49 this.type = type; 50 this.langtags = langtags; 51 } 52 53 /** 54 * Returns an array of all locales for which this locale service provider 55 * can provide localized objects or names. 56 * 57 * @return An array of all locales for which this locale service provider 58 * can provide localized objects or names. 59 */ 60 @Override 61 public Locale[] getAvailableLocales() { 62 return LocaleProviderAdapter.toLocaleArray(langtags); 63 } 64 65 @Override 66 public boolean isSupportedLocale(Locale locale) { 67 return LocaleProviderAdapter.forType(type).isSupportedProviderLocale(locale, langtags); 68 } 69 70 /** 71 * Returns a new <code>DateFormat</code> instance which formats time 72 * with the given formatting style for the specified locale. 73 * @param style the given formatting style. Either one of 74 * {@link java.text.DateFormat#SHORT DateFormat.SHORT}, 75 * {@link java.text.DateFormat#MEDIUM DateFormat.MEDIUM}, 76 * {@link java.text.DateFormat#LONG DateFormat.LONG}, or 77 * {@link java.text.DateFormat#FULL DateFormat.FULL}. 78 * @param locale the desired locale. 79 * @exception IllegalArgumentException if <code>style</code> is invalid, 80 * or if <code>locale</code> isn't 81 * one of the locales returned from 82 * {@link java.util.spi.LocaleServiceProvider#getAvailableLocales() 83 * getAvailableLocales()}. 84 * @exception NullPointerException if <code>locale</code> is null 85 * @return a time formatter. 86 * @see java.text.DateFormat#getTimeInstance(int, java.util.Locale) 87 */ 88 @Override 89 public DateFormat getTimeInstance(int style, Locale locale) { 90 return getInstance(-1, style, locale); 91 } 92 93 /** 94 * Returns a new <code>DateFormat</code> instance which formats date 95 * with the given formatting style for the specified locale. 96 * @param style the given formatting style. Either one of 97 * {@link java.text.DateFormat#SHORT DateFormat.SHORT}, 98 * {@link java.text.DateFormat#MEDIUM DateFormat.MEDIUM}, 99 * {@link java.text.DateFormat#LONG DateFormat.LONG}, or 100 * {@link java.text.DateFormat#FULL DateFormat.FULL}. 101 * @param locale the desired locale. 102 * @exception IllegalArgumentException if <code>style</code> is invalid, 103 * or if <code>locale</code> isn't 104 * one of the locales returned from 105 * {@link java.util.spi.LocaleServiceProvider#getAvailableLocales() 106 * getAvailableLocales()}. 107 * @exception NullPointerException if <code>locale</code> is null 108 * @return a date formatter. 109 * @see java.text.DateFormat#getDateInstance(int, java.util.Locale) 110 */ 111 @Override 112 public DateFormat getDateInstance(int style, Locale locale) { 113 return getInstance(style, -1, locale); 114 } 115 116 /** 117 * Returns a new <code>DateFormat</code> instance which formats date and time 118 * with the given formatting style for the specified locale. 119 * @param dateStyle the given date formatting style. Either one of 120 * {@link java.text.DateFormat#SHORT DateFormat.SHORT}, 121 * {@link java.text.DateFormat#MEDIUM DateFormat.MEDIUM}, 122 * {@link java.text.DateFormat#LONG DateFormat.LONG}, or 123 * {@link java.text.DateFormat#FULL DateFormat.FULL}. 124 * @param timeStyle the given time formatting style. Either one of 125 * {@link java.text.DateFormat#SHORT DateFormat.SHORT}, 126 * {@link java.text.DateFormat#MEDIUM DateFormat.MEDIUM}, 127 * {@link java.text.DateFormat#LONG DateFormat.LONG}, or 128 * {@link java.text.DateFormat#FULL DateFormat.FULL}. 129 * @param locale the desired locale. 130 * @exception IllegalArgumentException if <code>dateStyle</code> or 131 * <code>timeStyle</code> is invalid, 132 * or if <code>locale</code> isn't 133 * one of the locales returned from 134 * {@link java.util.spi.LocaleServiceProvider#getAvailableLocales() 135 * getAvailableLocales()}. 136 * @exception NullPointerException if <code>locale</code> is null 137 * @return a date/time formatter. 138 * @see java.text.DateFormat#getDateTimeInstance(int, int, java.util.Locale) 139 */ 140 @Override 141 public DateFormat getDateTimeInstance(int dateStyle, int timeStyle, 142 Locale locale) { 143 return getInstance(dateStyle, timeStyle, locale); 144 } 145 146 private DateFormat getInstance(int dateStyle, int timeStyle, Locale locale) { 147 if (locale == null) { 148 throw new NullPointerException(); 149 } 150 151 // Check for region override 152 Locale rg = CalendarDataUtility.findRegionOverride(locale).orElse(locale); 153 154 SimpleDateFormat sdf = new SimpleDateFormat("", rg); 155 Calendar cal = sdf.getCalendar(); 156 try { 157 String pattern = LocaleProviderAdapter.forType(type) 158 .getLocaleResources(rg).getDateTimePattern(timeStyle, dateStyle, 159 cal); 160 sdf.applyPattern(pattern); 161 } catch (MissingResourceException mre) { 162 // Specify the fallback pattern 163 sdf.applyPattern("M/d/yy h:mm a"); 164 } 165 166 // Check for timezone override 167 String tz = locale.getUnicodeLocaleType("tz"); 168 if (tz != null) { 169 sdf.setTimeZone( 170 TimeZoneNameUtility.convertLDMLShortID(tz) 171 .map(TimeZone::getTimeZone) 172 .orElseGet(sdf::getTimeZone)); 173 } 174 175 return sdf; 176 } 177 178 @Override 179 public Set<String> getAvailableLanguageTags() { 180 return langtags; 181 } 182 }