com.adobe.xfa.ut.DateTimeUtil Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of aem-sdk-api Show documentation
Show all versions of aem-sdk-api Show documentation
The Adobe Experience Manager SDK
/*
* ADOBE CONFIDENTIAL
*
* Copyright 2005 Adobe Systems Incorporated All Rights Reserved.
*
* NOTICE: All information contained herein is, and remains the property of
* Adobe Systems Incorporated and its suppliers, if any. The intellectual and
* technical concepts contained herein are proprietary to Adobe Systems
* Incorporated and its suppliers and may be covered by U.S. and Foreign
* Patents, patents in process, and are protected by trade secret or copyright
* law. Dissemination of this information or reproduction of this material
* is strictly forbidden unless prior written permission is obtained from
* Adobe Systems Incorporated.
*/
package com.adobe.xfa.ut;
/**
* This class implements static utility methods used by the LcDate and LcTime classes.
*
* @exclude from published api -- Mike Tardif, May 2006.
*/
public final class DateTimeUtil {
/*
* Disallow instances of this class
*/
private DateTimeUtil() {
// empty
}
/**
* Table of Kanji ideographic numeric characters
* as used in Japanese and Simplified Chinese locales.
*/
static final char Kanji_Num[] = {
/* 0 */ '\u3007',
/* 1 */ '\u4E00',
/* 2 */ '\u4E8C',
/* 3 */ '\u4E09',
/* 4 */ '\u56DB',
/* 5 */ '\u4E94',
/* 6 */ '\u516D',
/* 7 */ '\u4E03',
/* 8 */ '\u516B',
/* 9 */ '\u4E5D',
/* 10 */ '\u5341',
/* 100 */ '\u767E',
/* 1000 */ '\u5343'
};
/**
* Table of Hanja ideographic numeric characters
* as used in Korean and Traditional Chinese locales.
*/
static final char Hanja_Num[] = {
/* 0 */ '\u96F6', // Watson 1213930 prevents us from using U+F9B2.
/* 1 */ '\u4E00',
/* 2 */ '\u4E8C',
/* 3 */ '\u4E09',
/* 4 */ '\u56DB',
/* 5 */ '\u4E94',
/* 6 */ '\u516D',
/* 7 */ '\u4E03',
/* 8 */ '\u516B',
/* 9 */ '\u4E5D',
/* 10 */ '\u5341',
/* 100 */ '\u767E',
/* 1000 */ '\u5343'
};
/**
* Table of Hangul ideographic numeric characters
* as used in Korean locales.
*/
static final char Hangul_Num[] = {
/* 0 */ '\uC601',
/* 1 */ '\uC77C',
/* 2 */ '\uC774',
/* 3 */ '\uC0BC',
/* 4 */ '\uC0AC',
/* 5 */ '\uC624',
/* 6 */ '\uC721',
/* 7 */ '\uCE60',
/* 8 */ '\uD314',
/* 9 */ '\uAD6C',
/* 10 */ '\uC2ED',
/* 100 */ '\uBC31',
/* 1000 */ '\uCC9C'
};
/*
* Get a (previously matched) number of digits from a given start
* position to a given end position of the given string.
*
* @param src the string to parse.
* @param begPos the beginning parsing position within the string.
* @param endPos the ending parsing position within the string.
* @param fw get using fullwidth (instead of ASCII) digits when true.
* @param zero the native zero digit.
*
* @return the integral value of the number of digits matched.
*/
static int getNum(String src, int begPos, int endPos,
boolean fw, char zero) {
assert(begPos < endPos);
int n = 0;
while (begPos < endPos && begPos < src.length()) {
char chr = src.charAt(begPos++);
n *= 10;
if (fw)
n += chr - 0xFF10;
else
n += chr - zero;
}
return n;
}
/*
* Get a number using the given table of ideographic numeric characters
* from a given start position to a given end position of the given string
* in accordance to (or not) ten's rules.
*
* @param src the string to parse.
* @param begPos the beginning parsing position within the string.
* @param endPos the ending parsing position within the string.
* @param num the table of ideographic numbers.
* @param tr get using ten's rule when true.
*
* @return the integral value of the number of digits matched.
*/
static int getNum(String src, int begPos, int endPos,
char num[], boolean tr) {
assert(begPos < endPos);
int n = 0;
if (tr) { // w/ ten's rule.
int mils = 0, cens = 0, tens = 0, ones = 0;
while (begPos < endPos && begPos < src.length()) {
char chr = src.charAt(begPos++);
for (int p = 0; p < num.length; p++) {
if (chr == num[p]) {
if (p == 12) { // thousand
mils = ones > 0 ? ones : 1;
ones = 0;
}
else if (p == 11) { // hundred
cens = ones > 0 ? ones : 1;
ones = 0;
}
else if (p == 10) { // ten
tens = ones > 0 ? ones : 1;
ones = 0;
}
else if (p <= 9) { // ones
ones = p;
}
break;
}
}
}
n = mils * 1000 + cens * 100 + tens * 10 + ones;
}
else { // w/o ten's rule.
while (begPos < endPos && begPos < src.length()) {
char chr = src.charAt(begPos++);
int p = 0;
for (; p < num.length; p++) {
if (chr == num[p] && p <= 9) {
n *= 10;
n += p;
break;
}
}
if (p == num.length)
break;
}
}
return n;
}
/**
* Format a given number into a given string of given width. This is the
* equivalent of printf("%.d", w, n)
*
* @param w the width of string.
* @param n the number to format.
* @param fw format using fullwidth (instead of ASCII) digits when true.
* @param zero the native zero digit.
*
* @return the formatted string.
*/
static String fmtNum(int w, int n, boolean fw, char zero) {
assert(n >= 0 && w > 0);
StringBuilder s = new StringBuilder();
for (int i = w - 1; i >= 0; i--) {
char d = (char)(zero + n % 10);
if (fw)
d += 0xFEE0;
s.insert(0, d);
n /= 10;
}
return s.toString();
}
/*
* Format a given number into a given string of given width,
* using the given table of ideographic numeric characters
* in accordance to (or not) ten's rules.
* Ten's rules is described at Wikipedia under Chinese numerals,
* Japanese numerals and Korean numerals.
*
* @param d the number of digits to format.
* @param n the number to format.
* @param num the table of ideographic numbers.
* @param tr format using ten's rule digits when set:
* 1 for Chinese rules and
* -1 for Japanese rules.
*
* @return the formatted string.
*/
static String fmtNum(int d, int n, char num[], int tr) {
StringBuilder s = new StringBuilder();
if (num == null)
return "";
assert(n >= 0 && 1 <= d && d <= 4);
int mils = n / 1000;
int cens = (n - mils * 1000) / 100;
int tens = (n - mils * 1000 - cens * 100) / 10;
int ones = (n - mils * 1000 - cens * 100 - tens * 10);
if (tr != 0) { // w/ ten's rule.
boolean prevIsZero = false;
if (mils > 0) {
if (tr > 0 || mils > 1)
s.append(num[mils]);
s.append(num[12]);
}
if (cens > 0) {
if (tr > 0 || cens > 1)
s.append(num[cens]);
s.append(num[11]);
}
else if (tr > 0) {
if (! prevIsZero && tens > 0 && ones > 0 && !StringUtils.isEmpty(s)) {
s.append(num[0]);
prevIsZero = true;
}
}
if (tens > 0) {
if (tens > 1)
s.append(num[tens]);
s.append(num[10]);
}
else if (tr > 0) {
if (! prevIsZero && ones > 0 && !StringUtils.isEmpty(s)) {
s.append(num[0]);
prevIsZero = true;
}
}
if (StringUtils.isEmpty(s) || ones > 0)
s.append(num[ones]);
}
else { // w/o ten's rule.
if (mils > 0)
s.append(num[mils]);
if (s.length() > 0 || cens > 0)
s.append(num[cens]);
if (s.length() > 0 || tens > 0)
s.append(num[tens]);
s.append(num[ones]);
}
return s.toString();
}
/*
* Format a given number into a given string of given maximal width.
* This is the equivalent of printf("%d", n)
*
* @param w the maximal width of string.
* @param n the number to format.
* @param fw format using fullwidth (instead of ASCII) digits when true.
* @param zero the native zero digit.
*
* @return the formatted string.
*/
static String fmtPlainNum(int w, int n, boolean fw, char zero) {
assert (n >= 0 && w > 0);
StringBuilder s = new StringBuilder();
for (int i = w - 1; i >= 0; i--) {
char d = (char)(zero + n % 10);
if (fw)
d += 0xFEE0;
s.insert(0, d);
n /= 10;
if (n == 0)
break;
}
return s.toString();
}
/*
* Format a given string using fullwidth characters.
*
* @param src the source string.
* @param fw format using fullwidth characters when true.
*
* @return the formatted string.
*/
static String fmtStr(String src, boolean fw /* =false */) {
StringBuilder s = new StringBuilder();
for (int i = 0, n = src.length(); i < n; i++)
s.append(matchChr(src.charAt(i), fw));
return s.toString();
}
/*
* Match a name at a given position of the given string from
* a list of given names.
* Perform a case insensitive search for the best match.
*
* @param src the string to match.
* @param srcPos the starting position within the string.
* @param names the array of the names to match from.
* @param is do case insensitive search for the best match when true.
*
* @return the index within names that was matched, and -1 otherwise.
*/
static int matchName(String src, int srcPos,
String[] names, boolean is) {
//
// There may be multiple strings in the names[] array which have
// the same prefix, so we keep track of the longest match, and
// return that. This requires us to check all array elements.
//
int matchIdx = -1;
int matchLen = -1;
String pSrc = src.substring(srcPos);
for (int i = 0; i < names.length; i++) {
//
// Always check if we have no match yet; otherwise
// only compare potentially longer matches.
//
if (names[i] == null)
continue;
int len = names[i].length();
if (len <= matchLen)
continue;
else if (len == 0 || pSrc.startsWith(names[i])) {
matchIdx = i;
matchLen = len;
}
}
return matchIdx;
}
/*
* Match a number using the given table of ideographic numeric
* characters from a given start position to a given end position
* of the given string.
*
* @param src the string to match.
* @param begPos the beginning parsing position within the string.
* @param endPos the ending parsing position within the string.
* @param num the table of ideographic numbers.
* @param tr match using ten's rule digits when true.
*
* @return the number of digits matched, or -1 otherwise.
*/
static int matchNum(String src, int begPos, int endPos,
char num[], boolean tr) {
if (num == null)
return -1;
assert(begPos < endPos);
int srcLen = src.length();
int nDigitsSeen = 0;
if (tr) { // w/ ten's rule.
int mils = 0, cens = 0, tens = 0, ones = 1;
while (begPos < srcLen) {
char chr = src.charAt(begPos++);
if (chr == '\u5143')
return (nDigitsSeen > 0) ? nDigitsSeen : 1;
int p = 0;
for (; p < num.length; p++) {
if (chr == num[p]) {
if (p == 12) { // thousands
if (mils > 0 || cens > 0 || tens > 0)
return (nDigitsSeen > 0) ? nDigitsSeen : -1;
mils = ones; ones = 1;
}
else if (p == 11) { // hundreds
if (cens > 0 || tens > 0)
return (nDigitsSeen > 0) ? nDigitsSeen : -1;
cens = ones; ones = 1;
}
else if (p == 10) { // tens
if (tens > 0)
return (nDigitsSeen > 0) ? nDigitsSeen : -1;
tens = ones; ones = 1;
}
else if (p <= 9) { // ones
if (ones != 1)
return (nDigitsSeen > 0) ? nDigitsSeen : -1;
ones = p;
}
nDigitsSeen++;
break;
}
}
if (p == num.length)
break;
}
}
else { // w/o ten's rule.
int end = begPos;
for (int beg = begPos; beg < endPos; beg++) {
if (end < src.length())
end++;
}
endPos = end;
while (begPos < endPos /* && begPos < src.length() */) {
char chr = src.charAt(begPos++);
if (chr == '\u5143')
return (nDigitsSeen > 0) ? nDigitsSeen : 1;
int p = 0;
for (; p <= 9; p++) {
if (chr == num[p]) {
nDigitsSeen++;
break;
}
}
if (p == 10)
break;
}
}
return (nDigitsSeen > 0) ? nDigitsSeen : -1;
}
/*
* Match a number of digits from a given start position
* to a given end position of the given string.
*
* @param src the string to match.
* @param begPos the beginning parsing position within the string.
* @param endPos the ending parsing position within the string.
* @param fw use fullwidth (instead of ASCII) digits when true.
* @param zero the native zero digit.
*
* @return the number of digits matched, or -1 otherwise.
*/
static int matchNum(String src, int begPos, int endPos,
boolean fw, char zero) {
assert(begPos < endPos);
int nDigitsSeen = 0;
int end = begPos;
for (int beg = begPos; beg < endPos; beg++) {
if (end < src.length())
end++;
}
endPos = end;
while (begPos < endPos && begPos < src.length()) {
char chr = src.charAt(begPos++);
if (! fw && (zero > chr || chr > zero + 9))
break;
if (fw && (0xFF10 > chr || chr > 0xFF19))
break;
nDigitsSeen++;
}
return (nDigitsSeen > 0) ? nDigitsSeen : -1;
}
/*
* Match a given string from the given start position
* of the given source string. The matching can be made
* fullwidth sensitive.
*
* @param src the source string to match.
* @param srcPos the beginning matching position within the source string.
* @param str the string to look for.
* @param fw use fullwidth (instead of ASCII) matching when true.
*
* @return the number of digits matched, or -1 otherwise.
*/
static int matchStr(String src, int srcPos, String str, boolean fw) {
for (int i = 0, n = str.length(); i < n; ) {
char chr = (srcPos < src.length()) ? src.charAt(srcPos++) : 0;
if (fw) {
if (0xFF01 <= chr && chr <= 0xFF5E) {
chr -= 0xFFE0;
chr &= 0x00FF;
}
else if (chr == 0x3000) {
chr = ' ';
}
}
if (str.charAt(i++) != chr)
return -1;
}
return srcPos;
}
/*
* Increment the position given a Unicode character increment
* along the given start position of a given string.
*
* @param src the source string.
* @param srcPos the starting position within the source string.
* @param inc the Unicode character increment.
*
* @return the incremented byte position within the string.
*/
static int incPos(String src, int srcPos, int inc) {
assert(inc > 0);
for (int i = 0; i < inc; i++)
src.charAt(srcPos++);
return srcPos;
}
/*
* Match a given string to a given Unicode character.
* The match is fullwidth character insensitive!
*
* @param src the string to search.
* @param chr the Unicode character to find.
* @return boolean true if found, and false otherwise.
*/
static boolean matchChr(String src, char chr) {
if (0xFF01 <= chr && chr <= 0xFF5E) {
chr -= 0xFFE0;
chr &= 0x00FF;
}
else if (chr == 0x3000) {
chr = ' ';
}
for (int i = 0, n = src.length(); i < n; i++)
if (src.charAt(i) == chr)
return true;
return false;
}
/*
* Return a (fullwidth) Unicode character.
*
* @param chr the ASCII character to return.
* @param fw use fullwidth (instead of ASCII) characters when true.
*
* @return the character to matched.
*/
static char matchChr(char chr, boolean fw) {
if (fw) {
if (0x0021 <= chr && chr <= 0x007E)
chr += 0xFEE0;
else if (chr == ' ')
chr = 0x3000;
}
return chr;
}
/*
* Match a given string at a given position to a given Unicode character.
* The match is fullwidth character sensitive!
*
* @param src the string to search.
* @param srcPos the starting position within the string.
* @param chr the Unicode character to find.
* @param fw use fullwidth (instead of ASCII) characters when true.
* @return Boolean true if matched, and false otherwise.
*/
static boolean matchChr(String src, int srcPos,
char chr, boolean fw) {
if (srcPos >= src.length())
return false;
return (matchChr(src.charAt(srcPos), fw) == chr);
}
}