3 *******************************************************************************
\r
4 * Copyright (C) 2007-2009, International Business Machines
\r
5 * Corporation and others. All Rights Reserved.
\r
6 *******************************************************************************
\r
8 package com.ibm.icu.impl;
\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
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
23 * NumberFormat implementation dedicated/optimized for DateFormat,
\r
24 * used by SimpleDateFormat implementation.
\r
26 public final class DateNumberFormat extends NumberFormat {
\r
28 private static final long serialVersionUID = -6315692826916346953L;
\r
30 private char zeroDigit;
\r
31 private char minusSign;
\r
32 private boolean positiveOnly = false;
\r
34 private transient char[] decimalBuf = new char[20]; // 20 digits is good enough to store Long.MAX_VALUE
\r
36 private static SimpleCache CACHE = new SimpleCache();
\r
38 private int maxIntDigits;
\r
39 private int minIntDigits;
\r
41 public DateNumberFormat(ULocale loc, char zeroDigitIn) {
\r
42 initialize(loc,zeroDigitIn);
\r
45 /* public DateNumberFormat(char zeroDigit, char minusSign) {
\r
46 this.zeroDigit = zeroDigit;
\r
47 this.minusSign = minusSign;
\r
51 private void initialize(ULocale loc,char zeroDigitIn) {
\r
52 char[] elems = (char[])CACHE.get(loc);
\r
53 if (elems == null) {
\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
62 zeroDigit = elems[0];
\r
63 minusSign = elems[1];
\r
66 public void setMaximumIntegerDigits(int newValue) {
\r
67 maxIntDigits = newValue;
\r
70 public int getMaximumIntegerDigits() {
\r
71 return maxIntDigits;
\r
74 public void setMinimumIntegerDigits(int newValue) {
\r
75 minIntDigits = newValue;
\r
78 public int getMinimumIntegerDigits() {
\r
79 return minIntDigits;
\r
82 /* For supporting SimpleDateFormat.parseInt */
\r
83 public void setParsePositiveOnly(boolean isPositiveOnly) {
\r
84 positiveOnly = isPositiveOnly;
\r
87 public char getZeroDigit() {
\r
91 public void setZeroDigit(char zero) {
\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
100 public StringBuffer format(long numberL, StringBuffer toAppendTo,
\r
101 FieldPosition pos) {
\r
105 toAppendTo.append(minusSign);
\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
113 int limit = decimalBuf.length < maxIntDigits ? decimalBuf.length : maxIntDigits;
\r
114 int index = limit - 1;
\r
116 decimalBuf[index] = (char)((number % 10) + zeroDigit);
\r
118 if (index == 0 || number == 0) {
\r
123 int padding = minIntDigits - (limit - index);
\r
124 for (; padding > 0; padding--) {
\r
125 decimalBuf[--index] = zeroDigit;
\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
133 pos.setEndIndex(0);
\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
143 //#if defined(FOUNDATION10)
\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
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
157 * Note: This method only parse integer numbers which can be represented by long
\r
159 public Number parse(String text, ParsePosition parsePosition) {
\r
161 boolean sawNumber = false;
\r
162 boolean negative = false;
\r
163 int base = parsePosition.getIndex();
\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
173 int digit = ch - zeroDigit;
\r
174 if (digit < 0 || 9 < digit) {
\r
175 digit = UCharacter.digit(ch);
\r
177 if (0 <= digit && digit <= 9) {
\r
179 num = num * 10 + digit;
\r
185 Number result = null;
\r
187 num = negative ? num * (-1) : num;
\r
188 result = new Long(num);
\r
189 parsePosition.setIndex(base + offset);
\r
194 public boolean equals(Object obj) {
\r
195 if (obj == null || !super.equals(obj) || !(obj instanceof DateNumberFormat)) {
\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
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