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