]> gitweb.fperrin.net Git - Dictionary.git/blob - jars/icu4j-4_4_2-src/main/classes/core/src/com/ibm/icu/impl/DateNumberFormat.java
go
[Dictionary.git] / jars / icu4j-4_4_2-src / main / classes / core / src / com / ibm / icu / impl / DateNumberFormat.java
1 /*\r
2 *******************************************************************************\r
3 *   Copyright (C) 2007-2009, International Business Machines\r
4 *   Corporation and others.  All Rights Reserved.\r
5 *******************************************************************************\r
6 */\r
7 package com.ibm.icu.impl;\r
8 \r
9 import java.io.IOException;\r
10 import java.io.ObjectInputStream;\r
11 import java.math.BigInteger;\r
12 import java.text.FieldPosition;\r
13 import java.text.ParsePosition;\r
14 \r
15 import com.ibm.icu.lang.UCharacter;\r
16 import com.ibm.icu.math.BigDecimal;\r
17 import com.ibm.icu.text.NumberFormat;\r
18 import com.ibm.icu.util.ULocale;\r
19 import com.ibm.icu.util.UResourceBundle;\r
20 \r
21 /*\r
22  * NumberFormat implementation dedicated/optimized for DateFormat,\r
23  * used by SimpleDateFormat implementation.\r
24  */\r
25 public final class DateNumberFormat extends NumberFormat {\r
26 \r
27     private static final long serialVersionUID = -6315692826916346953L;\r
28 \r
29     private char zeroDigit;\r
30     private char minusSign;\r
31     private boolean positiveOnly = false;\r
32 \r
33     private transient char[] decimalBuf = new char[20]; // 20 digits is good enough to store Long.MAX_VALUE\r
34 \r
35     private static SimpleCache<ULocale, char[]> CACHE = new SimpleCache<ULocale, char[]>();\r
36 \r
37     private int maxIntDigits;\r
38     private int minIntDigits;\r
39  \r
40     public DateNumberFormat(ULocale loc, char zeroDigitIn) {\r
41         initialize(loc,zeroDigitIn);\r
42     }\r
43 \r
44 /*    public DateNumberFormat(char zeroDigit, char minusSign) {\r
45         this.zeroDigit = zeroDigit;\r
46         this.minusSign = minusSign;\r
47     }\r
48 */\r
49 \r
50     private void initialize(ULocale loc,char zeroDigitIn) {\r
51         char[] elems = CACHE.get(loc);\r
52         if (elems == null) {\r
53             // Missed cache\r
54             ICUResourceBundle rb = (ICUResourceBundle)UResourceBundle.getBundleInstance(ICUResourceBundle.ICU_BASE_NAME, loc);\r
55             String[] numberElements = rb.getStringArray("NumberElements");\r
56             elems = new char[2];\r
57             elems[0] = zeroDigitIn;\r
58             elems[1] = numberElements[6].charAt(0);\r
59             CACHE.put(loc, elems);\r
60         }\r
61         zeroDigit = elems[0];\r
62         minusSign = elems[1];\r
63     }\r
64 \r
65     public void setMaximumIntegerDigits(int newValue) {\r
66         maxIntDigits = newValue;\r
67     }\r
68 \r
69     public int getMaximumIntegerDigits() {\r
70         return maxIntDigits;\r
71     }\r
72 \r
73     public void setMinimumIntegerDigits(int newValue) {\r
74         minIntDigits = newValue;\r
75     }\r
76 \r
77     public int getMinimumIntegerDigits() {\r
78         return minIntDigits;\r
79     }\r
80 \r
81     /* For supporting SimpleDateFormat.parseInt */\r
82     public void setParsePositiveOnly(boolean isPositiveOnly) {\r
83         positiveOnly = isPositiveOnly;\r
84     }\r
85 \r
86     public char getZeroDigit() {\r
87         return zeroDigit;\r
88     }\r
89 \r
90     public void setZeroDigit(char zero) {\r
91         zeroDigit = zero;\r
92     }\r
93 \r
94     public StringBuffer format(double number, StringBuffer toAppendTo,\r
95             FieldPosition pos) {\r
96         throw new UnsupportedOperationException("StringBuffer format(double, StringBuffer, FieldPostion) is not implemented");\r
97     }\r
98 \r
99     public StringBuffer format(long numberL, StringBuffer toAppendTo,\r
100             FieldPosition pos) {\r
101 \r
102         if (numberL < 0) {\r
103             // negative\r
104             toAppendTo.append(minusSign);\r
105         }\r
106 \r
107         // Note: NumberFormat used by DateFormat only uses int numbers.\r
108         // Remainder operation on 32bit platform using long is significantly slower\r
109         // than int.  So, this method casts long number into int.\r
110         int number = (int)numberL;\r
111 \r
112         int limit = decimalBuf.length < maxIntDigits ? decimalBuf.length : maxIntDigits;\r
113         int index = limit - 1;\r
114         while (true) {\r
115             decimalBuf[index] = (char)((number % 10) + zeroDigit);\r
116             number /= 10;\r
117             if (index == 0 || number == 0) {\r
118                 break;\r
119             }\r
120             index--;\r
121         }\r
122         int padding = minIntDigits - (limit - index);\r
123         for (; padding > 0; padding--) {\r
124             decimalBuf[--index] = zeroDigit;\r
125         }\r
126         int length = limit - index;\r
127         toAppendTo.append(decimalBuf, index, length);\r
128         pos.setBeginIndex(0);\r
129         if (pos.getField() == NumberFormat.INTEGER_FIELD) {\r
130             pos.setEndIndex(length);\r
131         } else {\r
132             pos.setEndIndex(0);\r
133         }\r
134         return toAppendTo;\r
135     }\r
136     \r
137     public StringBuffer format(BigInteger number, StringBuffer toAppendTo,\r
138             FieldPosition pos) {\r
139         throw new UnsupportedOperationException("StringBuffer format(BigInteger, StringBuffer, FieldPostion) is not implemented");\r
140     }\r
141 \r
142     public StringBuffer format(java.math.BigDecimal number, StringBuffer toAppendTo,\r
143             FieldPosition pos) {\r
144         throw new UnsupportedOperationException("StringBuffer format(BigDecimal, StringBuffer, FieldPostion) is not implemented");\r
145     }\r
146 \r
147     public StringBuffer format(BigDecimal number,\r
148             StringBuffer toAppendTo, FieldPosition pos) {\r
149         throw new UnsupportedOperationException("StringBuffer format(BigDecimal, StringBuffer, FieldPostion) is not implemented");\r
150     }\r
151 \r
152     /*\r
153      * Note: This method only parse integer numbers which can be represented by long\r
154      */\r
155     public Number parse(String text, ParsePosition parsePosition) {\r
156         long num = 0;\r
157         boolean sawNumber = false;\r
158         boolean negative = false;\r
159         int base = parsePosition.getIndex();\r
160         int offset = 0;\r
161         for (; base + offset < text.length(); offset++) {\r
162             char ch = text.charAt(base + offset);\r
163             if (offset == 0 && ch == minusSign) {\r
164                 if (positiveOnly) {\r
165                     break;\r
166                 }\r
167                 negative = true;\r
168             } else {\r
169                 int digit = ch - zeroDigit;\r
170                 if (digit < 0 || 9 < digit) {\r
171                     digit = UCharacter.digit(ch);\r
172                 }\r
173                 if (0 <= digit && digit <= 9) {\r
174                     sawNumber = true;\r
175                     num = num * 10 + digit;\r
176                 } else {\r
177                     break;\r
178                 }\r
179             }\r
180         }\r
181         Number result = null;\r
182         if (sawNumber) {\r
183             num = negative ? num * (-1) : num;\r
184             result = new Long(num);\r
185             parsePosition.setIndex(base + offset);\r
186         }\r
187         return result;\r
188     }\r
189 \r
190     public boolean equals(Object obj) {\r
191         if (obj == null || !super.equals(obj) || !(obj instanceof DateNumberFormat)) {\r
192             return false;\r
193         }\r
194         DateNumberFormat other = (DateNumberFormat)obj;\r
195         return (this.maxIntDigits == other.maxIntDigits\r
196                 && this.minIntDigits == other.minIntDigits\r
197                 && this.zeroDigit == other.zeroDigit\r
198                 && this.minusSign == other.minusSign\r
199                 && this.positiveOnly == other.positiveOnly);\r
200     }\r
201 \r
202     private void readObject(ObjectInputStream stream) throws IOException, ClassNotFoundException {\r
203         stream.defaultReadObject();\r
204         // re-allocate the work buffer\r
205         decimalBuf = new char[20];\r
206     }\r
207 }\r
208 \r
209 //eof\r