3 *******************************************************************************
4 * Copyright (C) 2007-2009, International Business Machines
5 * Corporation and others. All Rights Reserved.
6 *******************************************************************************
8 package com.ibm.icu.impl;
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;
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;
23 * NumberFormat implementation dedicated/optimized for DateFormat,
24 * used by SimpleDateFormat implementation.
26 public final class DateNumberFormat extends NumberFormat {
28 private static final long serialVersionUID = -6315692826916346953L;
30 private char zeroDigit;
31 private char minusSign;
32 private boolean positiveOnly = false;
34 private transient char[] decimalBuf = new char[20]; // 20 digits is good enough to store Long.MAX_VALUE
36 private static SimpleCache CACHE = new SimpleCache();
38 private int maxIntDigits;
39 private int minIntDigits;
41 public DateNumberFormat(ULocale loc, char zeroDigitIn) {
42 initialize(loc,zeroDigitIn);
45 /* public DateNumberFormat(char zeroDigit, char minusSign) {
46 this.zeroDigit = zeroDigit;
47 this.minusSign = minusSign;
51 private void initialize(ULocale loc,char zeroDigitIn) {
52 char[] elems = (char[])CACHE.get(loc);
55 ICUResourceBundle rb = (ICUResourceBundle)UResourceBundle.getBundleInstance(ICUResourceBundle.ICU_BASE_NAME, loc);
56 String[] numberElements = rb.getStringArray("NumberElements");
58 elems[0] = zeroDigitIn;
59 elems[1] = numberElements[6].charAt(0);
60 CACHE.put(loc, elems);
66 public void setMaximumIntegerDigits(int newValue) {
67 maxIntDigits = newValue;
70 public int getMaximumIntegerDigits() {
74 public void setMinimumIntegerDigits(int newValue) {
75 minIntDigits = newValue;
78 public int getMinimumIntegerDigits() {
82 /* For supporting SimpleDateFormat.parseInt */
83 public void setParsePositiveOnly(boolean isPositiveOnly) {
84 positiveOnly = isPositiveOnly;
87 public char getZeroDigit() {
91 public void setZeroDigit(char zero) {
95 public StringBuffer format(double number, StringBuffer toAppendTo,
97 throw new UnsupportedOperationException("StringBuffer format(double, StringBuffer, FieldPostion) is not implemented");
100 public StringBuffer format(long numberL, StringBuffer toAppendTo,
105 toAppendTo.append(minusSign);
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;
113 int limit = decimalBuf.length < maxIntDigits ? decimalBuf.length : maxIntDigits;
114 int index = limit - 1;
116 decimalBuf[index] = (char)((number % 10) + zeroDigit);
118 if (index == 0 || number == 0) {
123 int padding = minIntDigits - (limit - index);
124 for (; padding > 0; padding--) {
125 decimalBuf[--index] = zeroDigit;
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);
138 public StringBuffer format(BigInteger number, StringBuffer toAppendTo,
140 throw new UnsupportedOperationException("StringBuffer format(BigInteger, StringBuffer, FieldPostion) is not implemented");
143 //#if defined(FOUNDATION10)
145 public StringBuffer format(java.math.BigDecimal number, StringBuffer toAppendTo,
147 throw new UnsupportedOperationException("StringBuffer format(BigDecimal, StringBuffer, FieldPostion) is not implemented");
151 public StringBuffer format(BigDecimal number,
152 StringBuffer toAppendTo, FieldPosition pos) {
153 throw new UnsupportedOperationException("StringBuffer format(BigDecimal, StringBuffer, FieldPostion) is not implemented");
157 * Note: This method only parse integer numbers which can be represented by long
159 public Number parse(String text, ParsePosition parsePosition) {
161 boolean sawNumber = false;
162 boolean negative = false;
163 int base = parsePosition.getIndex();
165 for (; base + offset < text.length(); offset++) {
166 char ch = text.charAt(base + offset);
167 if (offset == 0 && ch == minusSign) {
173 int digit = ch - zeroDigit;
174 if (digit < 0 || 9 < digit) {
175 digit = UCharacter.digit(ch);
177 if (0 <= digit && digit <= 9) {
179 num = num * 10 + digit;
185 Number result = null;
187 num = negative ? num * (-1) : num;
188 result = new Long(num);
189 parsePosition.setIndex(base + offset);
194 public boolean equals(Object obj) {
195 if (obj == null || !super.equals(obj) || !(obj instanceof DateNumberFormat)) {
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);
206 private void readObject(ObjectInputStream stream) throws IOException, ClassNotFoundException {
207 stream.defaultReadObject();
208 // re-allocate the work buffer
209 decimalBuf = new char[20];