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