2
* Copyright 2001-2005 Stephen Colebourne
4
* Licensed under the Apache License, Version 2.0 (the "License");
5
* you may not use this file except in compliance with the License.
6
* You may obtain a copy of the License at
8
* http://www.apache.org/licenses/LICENSE-2.0
10
* Unless required by applicable law or agreed to in writing, software
11
* distributed under the License is distributed on an "AS IS" BASIS,
12
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13
* See the License for the specific language governing permissions and
14
* limitations under the License.
16
package org.joda.time.chrono;
18
import java.lang.ref.WeakReference;
19
import java.text.DateFormatSymbols;
20
import java.util.WeakHashMap;
21
import java.util.Locale;
22
import java.util.TreeMap;
24
import org.joda.time.DateTimeFieldType;
25
import org.joda.time.IllegalFieldValueException;
28
* Utility class used by a few of the GJDateTimeFields.
30
* @author Brian S O'Neill
33
class GJLocaleSymbols {
34
private static final int FAST_CACHE_SIZE = 64;
36
private static final GJLocaleSymbols[] cFastCache = new GJLocaleSymbols[FAST_CACHE_SIZE];
38
private static WeakHashMap cCache = new WeakHashMap();
40
public static GJLocaleSymbols forLocale(Locale locale) {
42
locale = Locale.getDefault();
44
int index = System.identityHashCode(locale) & (FAST_CACHE_SIZE - 1);
45
GJLocaleSymbols symbols = cFastCache[index];
46
if (symbols != null && symbols.iLocale.get() == locale) {
49
synchronized (cCache) {
50
symbols = (GJLocaleSymbols) cCache.get(locale);
51
if (symbols == null) {
52
symbols = new GJLocaleSymbols(locale);
53
cCache.put(locale, symbols);
56
cFastCache[index] = symbols;
60
private static String[] realignMonths(String[] months) {
61
String[] a = new String[13];
62
for (int i=1; i<13; i++) {
68
private static String[] realignDaysOfWeek(String[] daysOfWeek) {
69
String[] a = new String[8];
70
for (int i=1; i<8; i++) {
71
a[i] = daysOfWeek[(i < 7) ? i + 1 : 1];
76
private static void addSymbols(TreeMap map, String[] symbols, Integer[] integers) {
77
for (int i=symbols.length; --i>=0; ) {
78
String symbol = symbols[i];
80
map.put(symbol, integers[i]);
85
private static void addNumerals(TreeMap map, int start, int end, Integer[] integers) {
86
for (int i=start; i<=end; i++) {
87
map.put(String.valueOf(i).intern(), integers[i]);
91
private static int maxLength(String[] a) {
93
for (int i=a.length; --i>=0; ) {
105
private final WeakReference iLocale;
107
private final String[] iEras;
108
private final String[] iDaysOfWeek;
109
private final String[] iShortDaysOfWeek;
110
private final String[] iMonths;
111
private final String[] iShortMonths;
112
private final String[] iHalfday;
114
// These map Strings to Integers.
115
private final TreeMap iParseEras;
116
private final TreeMap iParseDaysOfWeek;
117
private final TreeMap iParseMonths;
119
private final int iMaxEraLength;
120
private final int iMaxDayOfWeekLength;
121
private final int iMaxShortDayOfWeekLength;
122
private final int iMaxMonthLength;
123
private final int iMaxShortMonthLength;
124
private final int iMaxHalfdayLength;
127
* @param locale must not be null
129
private GJLocaleSymbols(Locale locale) {
130
iLocale = new WeakReference(locale);
132
DateFormatSymbols dfs = new DateFormatSymbols(locale);
134
iEras = dfs.getEras();
135
iDaysOfWeek = realignDaysOfWeek(dfs.getWeekdays());
136
iShortDaysOfWeek = realignDaysOfWeek(dfs.getShortWeekdays());
137
iMonths = realignMonths(dfs.getMonths());
138
iShortMonths = realignMonths(dfs.getShortMonths());
139
iHalfday = dfs.getAmPmStrings();
141
Integer[] integers = new Integer[13];
142
for (int i=0; i<13; i++) {
143
integers[i] = new Integer(i);
146
iParseEras = new TreeMap(String.CASE_INSENSITIVE_ORDER);
147
addSymbols(iParseEras, iEras, integers);
148
if ("en".equals(locale.getLanguage())) {
149
// Include support for parsing "BCE" and "CE" if the language is
150
// English. At some point Joda-Time will need an independent set of
151
// localized symbols and not depend on java.text.DateFormatSymbols.
152
iParseEras.put("BCE", integers[0]);
153
iParseEras.put("CE", integers[1]);
156
iParseDaysOfWeek = new TreeMap(String.CASE_INSENSITIVE_ORDER);
157
addSymbols(iParseDaysOfWeek, iDaysOfWeek, integers);
158
addSymbols(iParseDaysOfWeek, iShortDaysOfWeek, integers);
159
addNumerals(iParseDaysOfWeek, 1, 7, integers);
161
iParseMonths = new TreeMap(String.CASE_INSENSITIVE_ORDER);
162
addSymbols(iParseMonths, iMonths, integers);
163
addSymbols(iParseMonths, iShortMonths, integers);
164
addNumerals(iParseMonths, 1, 12, integers);
166
iMaxEraLength = maxLength(iEras);
167
iMaxDayOfWeekLength = maxLength(iDaysOfWeek);
168
iMaxShortDayOfWeekLength = maxLength(iShortDaysOfWeek);
169
iMaxMonthLength = maxLength(iMonths);
170
iMaxShortMonthLength = maxLength(iShortMonths);
171
iMaxHalfdayLength = maxLength(iHalfday);
174
public String eraValueToText(int value) {
178
public int eraTextToValue(String text) {
179
Integer era = (Integer) iParseEras.get(text);
181
return era.intValue();
183
throw new IllegalFieldValueException(DateTimeFieldType.era(), text);
186
public int getEraMaxTextLength() {
187
return iMaxEraLength;
190
public String monthOfYearValueToText(int value) {
191
return iMonths[value];
194
public String monthOfYearValueToShortText(int value) {
195
return iShortMonths[value];
198
public int monthOfYearTextToValue(String text) {
199
Integer month = (Integer) iParseMonths.get(text);
201
return month.intValue();
203
throw new IllegalFieldValueException(DateTimeFieldType.monthOfYear(), text);
206
public int getMonthMaxTextLength() {
207
return iMaxMonthLength;
210
public int getMonthMaxShortTextLength() {
211
return iMaxShortMonthLength;
214
public String dayOfWeekValueToText(int value) {
215
return iDaysOfWeek[value];
218
public String dayOfWeekValueToShortText(int value) {
219
return iShortDaysOfWeek[value];
222
public int dayOfWeekTextToValue(String text) {
223
Integer day = (Integer) iParseDaysOfWeek.get(text);
225
return day.intValue();
227
throw new IllegalFieldValueException(DateTimeFieldType.dayOfWeek(), text);
230
public int getDayOfWeekMaxTextLength() {
231
return iMaxDayOfWeekLength;
234
public int getDayOfWeekMaxShortTextLength() {
235
return iMaxShortDayOfWeekLength;
238
public String halfdayValueToText(int value) {
239
return iHalfday[value];
242
public int halfdayTextToValue(String text) {
243
String[] halfday = iHalfday;
244
for (int i = halfday.length; --i>=0; ) {
245
if (halfday[i].equalsIgnoreCase(text)) {
249
throw new IllegalFieldValueException(DateTimeFieldType.halfdayOfDay(), text);
252
public int getHalfdayMaxTextLength() {
253
return iMaxHalfdayLength;