![JAR search and dependency download from the Maven repository](/logo.png)
com.ibm.icu.impl.duration.impl.Utils Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of icu4j Show documentation
Show all versions of icu4j Show documentation
International Component for Unicode for Java (ICU4J) is a mature, widely used Java library
providing Unicode and Globalization support
// © 2016 and later: Unicode, Inc. and others.
// License & terms of use: http://www.unicode.org/copyright.html#License
/*
******************************************************************************
* Copyright (C) 2007-2012, International Business Machines Corporation and *
* others. All Rights Reserved. *
******************************************************************************
*/
package com.ibm.icu.impl.duration.impl;
import java.util.Locale;
public class Utils {
public static final Locale localeFromString(String s) {
String language = s;
String region = "";
String variant = "";
int x = language.indexOf("_");
if (x != -1) {
region = language.substring(x+1);
language = language.substring(0, x);
}
x = region.indexOf("_");
if (x != -1) {
variant = region.substring(x+1);
region = region.substring(0, x);
}
return new Locale(language, region, variant);
}
/*
public static T[] arraycopy(T[] src) {
T[] result = (T[])Array.newInstance(src.getClass().getComponentType(), src.length); // can we do this without casting?
for (int i = 0; i < src.length; ++i) {
result[i] = src[i];
}
return result;
}
*/
/**
* Interesting features of chinese numbers:
* - Each digit is followed by a unit symbol (10's, 100's, 1000's).
* - Units repeat in levels of 10,000, there are symbols for each level too (except 1's).
* - The digit 2 has a special form before the 10 symbol and at the end of the number.
* - If the first digit in the number is 1 and its unit is 10, the 1 is omitted.
* - Sequences of 0 digits and their units are replaced by a single 0 and no unit.
* - If there are two such sequences of 0 digits in a level (1000's and 10's), the 1000's 0 is also omitted.
* - The 1000's 0 is also omitted in alternating levels, such that it is omitted in the rightmost
* level with a 10's 0, or if none, in the rightmost level.
* - Level symbols are omitted if all of their units are omitted
*/
public static String chineseNumber(long n, ChineseDigits zh) {
if (n < 0) {
n = -n;
}
if (n <= 10) {
if (n == 2) {
return String.valueOf(zh.liang);
}
return String.valueOf(zh.digits[(int)n]);
}
// 9223372036854775807
char[] buf = new char[40]; // as long as we get, and actually we can't get this high, no units past zhao
char[] digits = String.valueOf(n).toCharArray();
// first, generate all the digits in place
// convert runs of zeros into a single zero, but keep places
//
boolean inZero = true; // true if we should zap zeros in this block, resets at start of block
boolean forcedZero = false; // true if we have a 0 in tens's place
int x = buf.length;
for (int i = digits.length, u = -1, l = -1; --i >= 0;) {
if (u == -1) {
if (l != -1) {
buf[--x] = zh.levels[l];
inZero = true;
forcedZero = false;
}
++u;
} else {
buf[--x] = zh.units[u++];
if (u == 3) {
u = -1;
++l;
}
}
int d = digits[i] - '0';
if (d == 0) {
if (x < buf.length-1 && u != 0) {
buf[x] = '*';
}
if (inZero || forcedZero) {
buf[--x] = '*';
} else {
buf[--x] = zh.digits[0];
inZero = true;
forcedZero = u == 1;
}
} else {
inZero = false;
buf[--x] = zh.digits[d];
}
}
// scanning from right, find first required 'ling'
// we only care if n > 101,0000 as this is the first case where
// it might shift. remove optional lings in alternating blocks.
if (n > 1000000) {
boolean last = true;
int i = buf.length - 3;
do {
if (buf[i] == '0') {
break;
}
i -= 8;
last = !last;
} while (i > x);
i = buf.length - 7;
do {
if (buf[i] == zh.digits[0] && !last) {
buf[i] = '*';
}
i -= 8;
last = !last;
} while (i > x);
// remove levels for empty blocks
if (n >= 100000000) {
i = buf.length - 8;
do {
boolean empty = true;
for (int j = i-1, e = Math.max(x-1, i-8); j > e; --j) {
if (buf[j] != '*') {
empty = false;
break;
}
}
if (empty) {
if (buf[i+1] != '*' && buf[i+1] != zh.digits[0]) {
buf[i] = zh.digits[0];
} else {
buf[i] = '*';
}
}
i -= 8;
} while (i > x);
}
}
// replace er by liang except before or after shi or after ling
for (int i = x; i < buf.length; ++i) {
if (buf[i] != zh.digits[2]) continue;
if (i < buf.length - 1 && buf[i+1] == zh.units[0]) continue;
if (i > x && (buf[i-1] == zh.units[0] || buf[i-1] == zh.digits[0] || buf[i-1] == '*')) continue;
buf[i] = zh.liang;
}
// eliminate leading 1 if following unit is shi
if (buf[x] == zh.digits[1] && (zh.ko || buf[x+1] == zh.units[0])) {
++x;
}
// now, compress out the '*'
int w = x;
for (int r = x; r < buf.length; ++r) {
if (buf[r] != '*') {
buf[w++] = buf[r];
}
}
return new String(buf, x, w-x);
}
// public static void main(String[] args) {
// for (int i = 0; i < args.length; ++i) {
// String arg = args[i];
// System.out.print(arg);
// System.out.print(" > ");
// long n = Long.parseLong(arg);
// System.out.println(chineseNumber(n, ChineseDigits.DEBUG));
// }
// }
public static class ChineseDigits {
final char[] digits;
final char[] units;
final char[] levels;
final char liang;
final boolean ko;
ChineseDigits(String digits, String units, String levels, char liang, boolean ko) {
this.digits = digits.toCharArray();
this.units = units.toCharArray();
this.levels = levels.toCharArray();
this.liang = liang;
this.ko = ko;
}
public static final ChineseDigits DEBUG =
new ChineseDigits("0123456789s", "sbq", "WYZ", 'L', false);
public static final ChineseDigits TRADITIONAL =
new ChineseDigits("\u96f6\u4e00\u4e8c\u4e09\u56db\u4e94\u516d\u4e03\u516b\u4e5d\u5341", // to shi
"\u5341\u767e\u5343", // shi, bai, qian
"\u842c\u5104\u5146", // wan, yi, zhao
'\u5169', false); // liang
public static final ChineseDigits SIMPLIFIED =
new ChineseDigits("\u96f6\u4e00\u4e8c\u4e09\u56db\u4e94\u516d\u4e03\u516b\u4e5d\u5341", // to shi
"\u5341\u767e\u5343", // shi, bai, qian
"\u4e07\u4ebf\u5146", // wan, yi, zhao
'\u4e24', false); // liang
// no 1 before first unit no matter what it is
// not sure if there are 'ling' units
public static final ChineseDigits KOREAN =
new ChineseDigits("\uc601\uc77c\uc774\uc0bc\uc0ac\uc624\uc721\uce60\ud314\uad6c\uc2ed", // to ten
"\uc2ed\ubc31\ucc9c", // 10, 100, 1000
"\ub9cc\uc5b5?", // 10^4, 10^8, 10^12
'\uc774', true);
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy