use of android.icu.text.TimeZoneFormat.Style in project j2objc by google.
the class SimpleDateFormat method subParse.
/**
* Protected method that converts one field of the input string into a
* numeric field value in <code>cal</code>. Returns -start (for
* ParsePosition) if failed. Subclasses may override this method to
* modify or add parsing capabilities.
* @param text the time text to be parsed.
* @param start where to start parsing.
* @param ch the pattern character for the date field text to be parsed.
* @param count the count of a pattern character.
* @param obeyCount if true, then the next field directly abuts this one,
* and we should use the count to know when to stop parsing.
* @param ambiguousYear return parameter; upon return, if ambiguousYear[0]
* is true, then a two-digit year was parsed and may need to be readjusted.
* @param cal
* @param numericLeapMonthFormatter if non-null, used to parse numeric leap months.
* @param tzTimeType the type of parsed time zone - standard, daylight or unknown (output).
* This parameter can be null if caller does not need the information.
* @return the new start position if matching succeeded; a negative
* number indicating matching failure, otherwise. As a side effect,
* set the appropriate field of <code>cal</code> with the parsed
* value.
* @deprecated This API is ICU internal only.
* @hide draft / provisional / internal are hidden on Android
*/
@Deprecated
@SuppressWarnings("fallthrough")
private int subParse(String text, int start, char ch, int count, boolean obeyCount, boolean allowNegative, boolean[] ambiguousYear, Calendar cal, MessageFormat numericLeapMonthFormatter, Output<TimeType> tzTimeType, Output<DayPeriodRules.DayPeriod> dayPeriod) {
Number number = null;
NumberFormat currentNumberFormat = null;
int value = 0;
int i;
ParsePosition pos = new ParsePosition(0);
int patternCharIndex = getIndexFromChar(ch);
if (patternCharIndex == -1) {
return ~start;
}
currentNumberFormat = getNumberFormat(ch);
// -1 if irrelevant
int field = PATTERN_INDEX_TO_CALENDAR_FIELD[patternCharIndex];
if (numericLeapMonthFormatter != null) {
numericLeapMonthFormatter.setFormatByArgumentIndex(0, currentNumberFormat);
}
boolean isChineseCalendar = (cal.getType().equals("chinese") || cal.getType().equals("dangi"));
// of the string, then fail.
for (; ; ) {
if (start >= text.length()) {
return ~start;
}
int c = UTF16.charAt(text, start);
if (!UCharacter.isUWhiteSpace(c) || !PatternProps.isWhiteSpace(c)) {
break;
}
start += UTF16.getCharCount(c);
}
pos.setIndex(start);
// the parsed value.
if (patternCharIndex == 4 || /*'k' HOUR_OF_DAY1_FIELD*/
patternCharIndex == 15 || /*'h' HOUR1_FIELD*/
(patternCharIndex == 2 && /*'M' MONTH_FIELD*/
count <= 2) || patternCharIndex == 26 || /*'L' STAND_ALONE_MONTH*/
patternCharIndex == 19 || /*'e' DOW_LOCAL*/
patternCharIndex == 25 || /*'c' STAND_ALONE_DAY_OF_WEEK*/
patternCharIndex == 1 || /*'y' YEAR */
patternCharIndex == 18 || /*'Y' YEAR_WOY */
patternCharIndex == 30 || /*'U' YEAR_NAME_FIELD, falls back to numeric */
(patternCharIndex == 0 && /*'G' ERA */
isChineseCalendar) || patternCharIndex == 27 || /* 'Q' - QUARTER*/
patternCharIndex == 28 || /* 'q' - STANDALONE QUARTER*/
patternCharIndex == 8) /*'S' FRACTIONAL_SECOND */
{
// It would be good to unify this with the obeyCount logic below,
// but that's going to be difficult.
boolean parsedNumericLeapMonth = false;
if (numericLeapMonthFormatter != null && (patternCharIndex == 2 || patternCharIndex == 26)) {
// First see if we can parse month number with leap month pattern
Object[] args = numericLeapMonthFormatter.parse(text, pos);
if (args != null && pos.getIndex() > start && (args[0] instanceof Number)) {
parsedNumericLeapMonth = true;
number = (Number) args[0];
cal.set(Calendar.IS_LEAP_MONTH, 1);
} else {
pos.setIndex(start);
cal.set(Calendar.IS_LEAP_MONTH, 0);
}
}
if (!parsedNumericLeapMonth) {
if (obeyCount) {
if ((start + count) > text.length()) {
return ~start;
}
number = parseInt(text, count, pos, allowNegative, currentNumberFormat);
} else {
number = parseInt(text, pos, allowNegative, currentNumberFormat);
}
if (number == null && !allowNumericFallback(patternCharIndex)) {
// only return if pattern is NOT one that allows numeric fallback
return ~start;
}
}
if (number != null) {
value = number.intValue();
}
}
switch(patternCharIndex) {
case // 'G' - ERA
0:
if (isChineseCalendar) {
// Numeric era handling moved from ChineseDateFormat,
// If we didn't have a number, already returned -start above
cal.set(Calendar.ERA, value);
return pos.getIndex();
}
int ps = 0;
if (count == 5) {
ps = matchString(text, start, Calendar.ERA, formatData.narrowEras, null, cal);
} else if (count == 4) {
ps = matchString(text, start, Calendar.ERA, formatData.eraNames, null, cal);
} else {
ps = matchString(text, start, Calendar.ERA, formatData.eras, null, cal);
}
// verify no year information also
if (ps == ~start)
ps = ISOSpecialEra;
return ps;
// 'y' - YEAR
case 1:
case // 'Y' - YEAR_WOY
18:
/* Skip this for Chinese calendar, moved from ChineseDateFormat */
if (override != null && (override.compareTo("hebr") == 0 || override.indexOf("y=hebr") >= 0) && value < 1000) {
value += HEBREW_CAL_CUR_MILLENIUM_START_YEAR;
} else if (count == 2 && (pos.getIndex() - start) == 2 && cal.haveDefaultCentury() && UCharacter.isDigit(text.charAt(start)) && UCharacter.isDigit(text.charAt(start + 1))) {
// Assume for example that the defaultCenturyStart is 6/18/1903.
// This means that two-digit years will be forced into the range
// 6/18/1903 to 6/17/2003. As a result, years 00, 01, and 02
// correspond to 2000, 2001, and 2002. Years 04, 05, etc. correspond
// to 1904, 1905, etc. If the year is 03, then it is 2003 if the
// other fields specify a date before 6/18, or 1903 if they specify a
// date afterwards. As a result, 03 is an ambiguous year. All other
// two-digit years are unambiguous.
int ambiguousTwoDigitYear = getDefaultCenturyStartYear() % 100;
ambiguousYear[0] = value == ambiguousTwoDigitYear;
value += (getDefaultCenturyStartYear() / 100) * 100 + (value < ambiguousTwoDigitYear ? 100 : 0);
}
cal.set(field, value);
// Delayed checking for adjustment of Hebrew month numbers in non-leap years.
if (DelayedHebrewMonthCheck) {
if (!HebrewCalendar.isLeapYear(value)) {
cal.add(Calendar.MONTH, 1);
}
DelayedHebrewMonthCheck = false;
}
return pos.getIndex();
case // 'U' - YEAR_NAME_FIELD
30:
if (formatData.shortYearNames != null) {
int newStart = matchString(text, start, Calendar.YEAR, formatData.shortYearNames, null, cal);
if (newStart > 0) {
return newStart;
}
}
if (number != null && (getBooleanAttribute(DateFormat.BooleanAttribute.PARSE_ALLOW_NUMERIC) || formatData.shortYearNames == null || value > formatData.shortYearNames.length)) {
cal.set(Calendar.YEAR, value);
return pos.getIndex();
}
return ~start;
// 'M' - MONTH
case 2:
case // 'L' - STAND_ALONE_MONTH
26:
if (count <= 2 || (number != null && getBooleanAttribute(DateFormat.BooleanAttribute.PARSE_ALLOW_NUMERIC))) {
// i.e., M/MM, L/LL or lenient & have a number
// Don't want to parse the month if it is a string
// while pattern uses numeric style: M/MM, L/LL.
// [We computed 'value' above.]
cal.set(Calendar.MONTH, value - 1);
// checking until the year is parsed.
if (cal.getType().equals("hebrew") && value >= 6) {
if (cal.isSet(Calendar.YEAR)) {
if (!HebrewCalendar.isLeapYear(cal.get(Calendar.YEAR))) {
cal.set(Calendar.MONTH, value);
}
} else {
DelayedHebrewMonthCheck = true;
}
}
return pos.getIndex();
} else {
// count >= 3 // i.e., MMM/MMMM or LLL/LLLL
// Want to be able to parse both short and long forms.
boolean haveMonthPat = (formatData.leapMonthPatterns != null && formatData.leapMonthPatterns.length >= DateFormatSymbols.DT_MONTH_PATTERN_COUNT);
// Try count == 4 first:, unless we're strict
int newStart = 0;
if (getBooleanAttribute(DateFormat.BooleanAttribute.PARSE_MULTIPLE_PATTERNS_FOR_MATCH) || count == 4) {
newStart = (patternCharIndex == 2) ? matchString(text, start, Calendar.MONTH, formatData.months, (haveMonthPat) ? formatData.leapMonthPatterns[DateFormatSymbols.DT_LEAP_MONTH_PATTERN_FORMAT_WIDE] : null, cal) : matchString(text, start, Calendar.MONTH, formatData.standaloneMonths, (haveMonthPat) ? formatData.leapMonthPatterns[DateFormatSymbols.DT_LEAP_MONTH_PATTERN_STANDALONE_WIDE] : null, cal);
if (newStart > 0) {
return newStart;
}
}
// count == 4 failed, now try count == 3
if (getBooleanAttribute(DateFormat.BooleanAttribute.PARSE_MULTIPLE_PATTERNS_FOR_MATCH) || count == 3) {
return (patternCharIndex == 2) ? matchString(text, start, Calendar.MONTH, formatData.shortMonths, (haveMonthPat) ? formatData.leapMonthPatterns[DateFormatSymbols.DT_LEAP_MONTH_PATTERN_FORMAT_ABBREV] : null, cal) : matchString(text, start, Calendar.MONTH, formatData.standaloneShortMonths, (haveMonthPat) ? formatData.leapMonthPatterns[DateFormatSymbols.DT_LEAP_MONTH_PATTERN_STANDALONE_ABBREV] : null, cal);
}
return newStart;
}
case // 'k' - HOUR_OF_DAY (1..24)
4:
// [We computed 'value' above.]
if (value == cal.getMaximum(Calendar.HOUR_OF_DAY) + 1) {
value = 0;
}
cal.set(Calendar.HOUR_OF_DAY, value);
return pos.getIndex();
case // 'S' - FRACTIONAL_SECOND
8:
// Fractional seconds left-justify
i = pos.getIndex() - start;
if (i < 3) {
while (i < 3) {
value *= 10;
i++;
}
} else {
int a = 1;
while (i > 3) {
a *= 10;
i--;
}
value /= a;
}
cal.set(Calendar.MILLISECOND, value);
return pos.getIndex();
case // 'e' - DOW_LOCAL
19:
if (count <= 2 || (number != null && (getBooleanAttribute(DateFormat.BooleanAttribute.PARSE_ALLOW_NUMERIC)))) {
// i.e. e/ee or lenient and have a number
cal.set(field, value);
return pos.getIndex();
}
// $FALL-THROUGH$
case 9:
{
// 'E' - DAY_OF_WEEK
// Want to be able to parse at least wide, abbrev, short, and narrow forms.
int newStart = 0;
if (getBooleanAttribute(DateFormat.BooleanAttribute.PARSE_MULTIPLE_PATTERNS_FOR_MATCH) || count == 4) {
if ((newStart = matchString(text, start, Calendar.DAY_OF_WEEK, formatData.weekdays, null, cal)) > 0) {
// try EEEE wide
return newStart;
}
}
if (getBooleanAttribute(DateFormat.BooleanAttribute.PARSE_MULTIPLE_PATTERNS_FOR_MATCH) || count == 3) {
if ((newStart = matchString(text, start, Calendar.DAY_OF_WEEK, formatData.shortWeekdays, null, cal)) > 0) {
// try EEE abbrev
return newStart;
}
}
if (getBooleanAttribute(DateFormat.BooleanAttribute.PARSE_MULTIPLE_PATTERNS_FOR_MATCH) || count == 6) {
if (formatData.shorterWeekdays != null) {
if ((newStart = matchString(text, start, Calendar.DAY_OF_WEEK, formatData.shorterWeekdays, null, cal)) > 0) {
// try EEEEEE short
return newStart;
}
}
}
if (getBooleanAttribute(DateFormat.BooleanAttribute.PARSE_MULTIPLE_PATTERNS_FOR_MATCH) || count == 5) {
if (formatData.narrowWeekdays != null) {
if ((newStart = matchString(text, start, Calendar.DAY_OF_WEEK, formatData.narrowWeekdays, null, cal)) > 0) {
// try EEEEE narrow
return newStart;
}
}
}
return newStart;
}
case 25:
{
// 'c' - STAND_ALONE_DAY_OF_WEEK
if (count == 1 || (number != null && (getBooleanAttribute(DateFormat.BooleanAttribute.PARSE_ALLOW_NUMERIC)))) {
// i.e. c or lenient and have a number
cal.set(field, value);
return pos.getIndex();
}
// Want to be able to parse at least wide, abbrev, short forms.
int newStart = 0;
if (getBooleanAttribute(DateFormat.BooleanAttribute.PARSE_MULTIPLE_PATTERNS_FOR_MATCH) || count == 4) {
if ((newStart = matchString(text, start, Calendar.DAY_OF_WEEK, formatData.standaloneWeekdays, null, cal)) > 0) {
// try cccc wide
return newStart;
}
}
if (getBooleanAttribute(DateFormat.BooleanAttribute.PARSE_MULTIPLE_PATTERNS_FOR_MATCH) || count == 3) {
if ((newStart = matchString(text, start, Calendar.DAY_OF_WEEK, formatData.standaloneShortWeekdays, null, cal)) > 0) {
// try ccc abbrev
return newStart;
}
}
if (getBooleanAttribute(DateFormat.BooleanAttribute.PARSE_MULTIPLE_PATTERNS_FOR_MATCH) || count == 6) {
if (formatData.standaloneShorterWeekdays != null) {
// try cccccc short
return matchString(text, start, Calendar.DAY_OF_WEEK, formatData.standaloneShorterWeekdays, null, cal);
}
}
return newStart;
}
case 14:
{
// 'a' - AM_PM
// Optionally try both wide/abbrev and narrow forms.
// formatData.ampmsNarrow may be null when deserializing DateFormatSymbolsfrom old version,
// in which case our only option is wide form
int newStart = 0;
// try wide/abbrev a-aaaa
if (formatData.ampmsNarrow == null || count < 5 || getBooleanAttribute(DateFormat.BooleanAttribute.PARSE_MULTIPLE_PATTERNS_FOR_MATCH)) {
if ((newStart = matchString(text, start, Calendar.AM_PM, formatData.ampms, null, cal)) > 0) {
return newStart;
}
}
// try narrow aaaaa
if (formatData.ampmsNarrow != null && (count >= 5 || getBooleanAttribute(DateFormat.BooleanAttribute.PARSE_MULTIPLE_PATTERNS_FOR_MATCH))) {
if ((newStart = matchString(text, start, Calendar.AM_PM, formatData.ampmsNarrow, null, cal)) > 0) {
return newStart;
}
}
// no matches for given options
return ~start;
}
case // 'h' - HOUR (1..12)
15:
// [We computed 'value' above.]
if (value == cal.getLeastMaximum(Calendar.HOUR) + 1) {
value = 0;
}
cal.set(Calendar.HOUR, value);
return pos.getIndex();
case // 'z' - ZONE_OFFSET
17:
{
Style style = (count < 4) ? Style.SPECIFIC_SHORT : Style.SPECIFIC_LONG;
TimeZone tz = tzFormat().parse(style, text, pos, tzTimeType);
if (tz != null) {
cal.setTimeZone(tz);
return pos.getIndex();
}
return ~start;
}
case // 'Z' - TIMEZONE_RFC
23:
{
Style style = (count < 4) ? Style.ISO_BASIC_LOCAL_FULL : ((count == 5) ? Style.ISO_EXTENDED_FULL : Style.LOCALIZED_GMT);
TimeZone tz = tzFormat().parse(style, text, pos, tzTimeType);
if (tz != null) {
cal.setTimeZone(tz);
return pos.getIndex();
}
return ~start;
}
case // 'v' - TIMEZONE_GENERIC
24:
{
// Note: 'v' only supports count 1 and 4
Style style = (count < 4) ? Style.GENERIC_SHORT : Style.GENERIC_LONG;
TimeZone tz = tzFormat().parse(style, text, pos, tzTimeType);
if (tz != null) {
cal.setTimeZone(tz);
return pos.getIndex();
}
return ~start;
}
case // 'V' - TIMEZONE_SPECIAL
29:
{
Style style = null;
switch(count) {
case 1:
style = Style.ZONE_ID_SHORT;
break;
case 2:
style = Style.ZONE_ID;
break;
case 3:
style = Style.EXEMPLAR_LOCATION;
break;
default:
style = Style.GENERIC_LOCATION;
break;
}
TimeZone tz = tzFormat().parse(style, text, pos, tzTimeType);
if (tz != null) {
cal.setTimeZone(tz);
return pos.getIndex();
}
return ~start;
}
case // 'O' - TIMEZONE_LOCALIZED_GMT_OFFSET
31:
{
Style style = (count < 4) ? Style.LOCALIZED_GMT_SHORT : Style.LOCALIZED_GMT;
TimeZone tz = tzFormat().parse(style, text, pos, tzTimeType);
if (tz != null) {
cal.setTimeZone(tz);
return pos.getIndex();
}
return ~start;
}
case // 'X' - TIMEZONE_ISO
32:
{
Style style;
switch(count) {
case 1:
style = Style.ISO_BASIC_SHORT;
break;
case 2:
style = Style.ISO_BASIC_FIXED;
break;
case 3:
style = Style.ISO_EXTENDED_FIXED;
break;
case 4:
style = Style.ISO_BASIC_FULL;
break;
default:
// count >= 5
style = Style.ISO_EXTENDED_FULL;
break;
}
TimeZone tz = tzFormat().parse(style, text, pos, tzTimeType);
if (tz != null) {
cal.setTimeZone(tz);
return pos.getIndex();
}
return ~start;
}
case // 'x' - TIMEZONE_ISO_LOCAL
33:
{
Style style;
switch(count) {
case 1:
style = Style.ISO_BASIC_LOCAL_SHORT;
break;
case 2:
style = Style.ISO_BASIC_LOCAL_FIXED;
break;
case 3:
style = Style.ISO_EXTENDED_LOCAL_FIXED;
break;
case 4:
style = Style.ISO_BASIC_LOCAL_FULL;
break;
default:
// count >= 5
style = Style.ISO_EXTENDED_LOCAL_FULL;
break;
}
TimeZone tz = tzFormat().parse(style, text, pos, tzTimeType);
if (tz != null) {
cal.setTimeZone(tz);
return pos.getIndex();
}
return ~start;
}
case // 'Q' - QUARTER
27:
if (count <= 2 || (number != null && getBooleanAttribute(DateFormat.BooleanAttribute.PARSE_ALLOW_NUMERIC))) {
// i.e., Q or QQ. or lenient & have number
// Don't want to parse the quarter if it is a string
// while pattern uses numeric style: Q or QQ.
// [We computed 'value' above.]
cal.set(Calendar.MONTH, (value - 1) * 3);
return pos.getIndex();
} else {
// count >= 3 // i.e., QQQ or QQQQ
// Want to be able to parse both short and long forms.
// Try count == 4 first:
int newStart = 0;
if (getBooleanAttribute(DateFormat.BooleanAttribute.PARSE_MULTIPLE_PATTERNS_FOR_MATCH) || count == 4) {
if ((newStart = matchQuarterString(text, start, Calendar.MONTH, formatData.quarters, cal)) > 0) {
return newStart;
}
}
// count == 4 failed, now try count == 3
if (getBooleanAttribute(DateFormat.BooleanAttribute.PARSE_MULTIPLE_PATTERNS_FOR_MATCH) || count == 3) {
return matchQuarterString(text, start, Calendar.MONTH, formatData.shortQuarters, cal);
}
return newStart;
}
case // 'q' - STANDALONE QUARTER
28:
if (count <= 2 || (number != null && getBooleanAttribute(DateFormat.BooleanAttribute.PARSE_ALLOW_NUMERIC))) {
// i.e., q or qq. or lenient & have number
// Don't want to parse the quarter if it is a string
// while pattern uses numeric style: q or qq.
// [We computed 'value' above.]
cal.set(Calendar.MONTH, (value - 1) * 3);
return pos.getIndex();
} else {
// count >= 3 // i.e., qqq or qqqq
// Want to be able to parse both short and long forms.
// Try count == 4 first:
int newStart = 0;
if (getBooleanAttribute(DateFormat.BooleanAttribute.PARSE_MULTIPLE_PATTERNS_FOR_MATCH) || count == 4) {
if ((newStart = matchQuarterString(text, start, Calendar.MONTH, formatData.standaloneQuarters, cal)) > 0) {
return newStart;
}
}
// count == 4 failed, now try count == 3
if (getBooleanAttribute(DateFormat.BooleanAttribute.PARSE_MULTIPLE_PATTERNS_FOR_MATCH) || count == 3) {
return matchQuarterString(text, start, Calendar.MONTH, formatData.standaloneShortQuarters, cal);
}
return newStart;
}
case // TIME SEPARATOR (no pattern character currently defined, we should
37:
// not get here but leave support in for future definition.
{
// Try matching a time separator.
ArrayList<String> data = new ArrayList<String>(3);
data.add(formatData.getTimeSeparatorString());
// Add the default, if different from the locale.
if (!formatData.getTimeSeparatorString().equals(DateFormatSymbols.DEFAULT_TIME_SEPARATOR)) {
data.add(DateFormatSymbols.DEFAULT_TIME_SEPARATOR);
}
// If lenient, add also the alternate, if different from the locale.
if (getBooleanAttribute(DateFormat.BooleanAttribute.PARSE_PARTIAL_LITERAL_MATCH) && !formatData.getTimeSeparatorString().equals(DateFormatSymbols.ALTERNATE_TIME_SEPARATOR)) {
data.add(DateFormatSymbols.ALTERNATE_TIME_SEPARATOR);
}
return matchString(text, start, -1, /* => nothing to set */
data.toArray(new String[0]), cal);
}
case // 'b' -- fixed day period (am/pm/midnight/noon)
35:
{
int ampmStart = subParse(text, start, 'a', count, obeyCount, allowNegative, ambiguousYear, cal, numericLeapMonthFormatter, tzTimeType, dayPeriod);
if (ampmStart > 0) {
return ampmStart;
} else {
int newStart = 0;
if (getBooleanAttribute(DateFormat.BooleanAttribute.PARSE_MULTIPLE_PATTERNS_FOR_MATCH) || count == 3) {
if ((newStart = matchDayPeriodString(text, start, formatData.abbreviatedDayPeriods, 2, dayPeriod)) > 0) {
return newStart;
}
}
if (getBooleanAttribute(DateFormat.BooleanAttribute.PARSE_MULTIPLE_PATTERNS_FOR_MATCH) || count == 4) {
if ((newStart = matchDayPeriodString(text, start, formatData.wideDayPeriods, 2, dayPeriod)) > 0) {
return newStart;
}
}
if (getBooleanAttribute(DateFormat.BooleanAttribute.PARSE_MULTIPLE_PATTERNS_FOR_MATCH) || count == 4) {
if ((newStart = matchDayPeriodString(text, start, formatData.narrowDayPeriods, 2, dayPeriod)) > 0) {
return newStart;
}
}
return newStart;
}
}
case // 'B' -- flexible day period
36:
{
int newStart = 0;
if (getBooleanAttribute(DateFormat.BooleanAttribute.PARSE_MULTIPLE_PATTERNS_FOR_MATCH) || count == 3) {
if ((newStart = matchDayPeriodString(text, start, formatData.abbreviatedDayPeriods, formatData.abbreviatedDayPeriods.length, dayPeriod)) > 0) {
return newStart;
}
}
if (getBooleanAttribute(DateFormat.BooleanAttribute.PARSE_MULTIPLE_PATTERNS_FOR_MATCH) || count == 4) {
if ((newStart = matchDayPeriodString(text, start, formatData.wideDayPeriods, formatData.wideDayPeriods.length, dayPeriod)) > 0) {
return newStart;
}
}
if (getBooleanAttribute(DateFormat.BooleanAttribute.PARSE_MULTIPLE_PATTERNS_FOR_MATCH) || count == 4) {
if ((newStart = matchDayPeriodString(text, start, formatData.narrowDayPeriods, formatData.narrowDayPeriods.length, dayPeriod)) > 0) {
return newStart;
}
}
return newStart;
}
default:
// Handle "generic" fields
if (obeyCount) {
if ((start + count) > text.length())
return -start;
number = parseInt(text, count, pos, allowNegative, currentNumberFormat);
} else {
number = parseInt(text, pos, allowNegative, currentNumberFormat);
}
if (number != null) {
if (patternCharIndex != DateFormat.RELATED_YEAR) {
cal.set(field, number.intValue());
} else {
cal.setRelatedYear(number.intValue());
}
return pos.getIndex();
}
return ~start;
}
}
use of android.icu.text.TimeZoneFormat.Style in project j2objc by google.
the class TimeZoneFormatTest method TestParse.
@Test
public void TestParse() {
final Object[][] DATA = { // parseOptions expected outpos time type
{ "Z", 0, "en_US", Style.ISO_EXTENDED_FULL, null, "Etc/GMT", 1, TimeType.UNKNOWN }, { "Z", 0, "en_US", Style.SPECIFIC_LONG, null, "Etc/GMT", 1, TimeType.UNKNOWN }, { "Zambia time", 0, "en_US", Style.ISO_EXTENDED_FULL, EnumSet.of(ParseOption.ALL_STYLES), "Etc/GMT", 1, TimeType.UNKNOWN }, { "Zambia time", 0, "en_US", Style.GENERIC_LOCATION, null, "Africa/Lusaka", 11, TimeType.UNKNOWN }, { "Zambia time", 0, "en_US", Style.ISO_BASIC_LOCAL_FULL, EnumSet.of(ParseOption.ALL_STYLES), "Africa/Lusaka", 11, TimeType.UNKNOWN }, { "+00:00", 0, "en_US", Style.ISO_EXTENDED_FULL, null, "Etc/GMT", 6, TimeType.UNKNOWN }, { "-01:30:45", 0, "en_US", Style.ISO_EXTENDED_FULL, null, "GMT-01:30:45", 9, TimeType.UNKNOWN }, { "-7", 0, "en_US", Style.ISO_BASIC_LOCAL_FULL, null, "GMT-07:00", 2, TimeType.UNKNOWN }, { "-2222", 0, "en_US", Style.ISO_BASIC_LOCAL_FULL, null, "GMT-22:22", 5, TimeType.UNKNOWN }, { "-3333", 0, "en_US", Style.ISO_BASIC_LOCAL_FULL, null, "GMT-03:33", 4, TimeType.UNKNOWN }, { "XXX+01:30YYY", 3, "en_US", Style.LOCALIZED_GMT, null, "GMT+01:30", 9, TimeType.UNKNOWN }, { "GMT0", 0, "en_US", Style.SPECIFIC_SHORT, null, "Etc/GMT", 3, TimeType.UNKNOWN }, { "EST", 0, "en_US", Style.SPECIFIC_SHORT, null, "America/New_York", 3, TimeType.STANDARD }, { "ESTx", 0, "en_US", Style.SPECIFIC_SHORT, null, "America/New_York", 3, TimeType.STANDARD }, { "EDTx", 0, "en_US", Style.SPECIFIC_SHORT, null, "America/New_York", 3, TimeType.DAYLIGHT }, { "EST", 0, "en_US", Style.SPECIFIC_LONG, null, null, 0, TimeType.UNKNOWN }, { "EST", 0, "en_US", Style.SPECIFIC_LONG, EnumSet.of(ParseOption.ALL_STYLES), "America/New_York", 3, TimeType.STANDARD }, { "EST", 0, "en_CA", Style.SPECIFIC_SHORT, null, "America/Toronto", 3, TimeType.STANDARD }, { "CST", 0, "en_US", Style.SPECIFIC_SHORT, null, "America/Chicago", 3, TimeType.STANDARD }, { "CST", 0, "en_GB", Style.SPECIFIC_SHORT, null, null, 0, TimeType.UNKNOWN }, { "CST", 0, "en_GB", Style.SPECIFIC_SHORT, EnumSet.of(ParseOption.TZ_DATABASE_ABBREVIATIONS), "America/Chicago", 3, TimeType.STANDARD }, { "--CST--", 2, "en_GB", Style.SPECIFIC_SHORT, EnumSet.of(ParseOption.TZ_DATABASE_ABBREVIATIONS), "America/Chicago", 5, TimeType.STANDARD }, { "CST", 0, "zh_CN", Style.SPECIFIC_SHORT, EnumSet.of(ParseOption.TZ_DATABASE_ABBREVIATIONS), "Asia/Shanghai", 3, TimeType.STANDARD }, { "AEST", 0, "en_AU", Style.SPECIFIC_SHORT, EnumSet.of(ParseOption.TZ_DATABASE_ABBREVIATIONS), "Australia/Sydney", 4, TimeType.STANDARD }, { "AST", 0, "ar_SA", Style.SPECIFIC_SHORT, EnumSet.of(ParseOption.TZ_DATABASE_ABBREVIATIONS), "Asia/Riyadh", 3, TimeType.STANDARD }, { "AQTST", 0, "en", Style.SPECIFIC_LONG, null, null, 0, TimeType.UNKNOWN }, { "AQTST", 0, "en", Style.SPECIFIC_LONG, EnumSet.of(ParseOption.ALL_STYLES), null, 0, TimeType.UNKNOWN }, { "AQTST", 0, "en", Style.SPECIFIC_LONG, EnumSet.of(ParseOption.ALL_STYLES, ParseOption.TZ_DATABASE_ABBREVIATIONS), "Asia/Aqtobe", 5, TimeType.DAYLIGHT }, { "hora de verano británica", 0, "es", Style.SPECIFIC_LONG, null, "Europe/London", 24, TimeType.DAYLIGHT } };
for (Object[] test : DATA) {
String text = (String) test[0];
int inPos = (Integer) test[1];
ULocale loc = new ULocale((String) test[2]);
Style style = (Style) test[3];
EnumSet<ParseOption> options = (EnumSet<ParseOption>) test[4];
String expID = (String) test[5];
int expPos = (Integer) test[6];
TimeType expType = (TimeType) test[7];
TimeZoneFormat tzfmt = TimeZoneFormat.getInstance(loc);
Output<TimeType> timeType = new Output<TimeType>(TimeType.UNKNOWN);
ParsePosition pos = new ParsePosition(inPos);
TimeZone tz = tzfmt.parse(style, text, pos, options, timeType);
String errMsg = null;
if (tz == null) {
if (expID != null) {
errMsg = "Parse failure - expected: " + expID;
}
} else if (!tz.getID().equals(expID)) {
errMsg = "Time zone ID: " + tz.getID() + " - expected: " + expID;
} else if (pos.getIndex() != expPos) {
errMsg = "Parsed pos: " + pos.getIndex() + " - expected: " + expPos;
} else if (timeType.value != expType) {
errMsg = "Time type: " + timeType + " - expected: " + expType;
}
if (errMsg != null) {
errln("Fail: " + errMsg + " [text=" + text + ", pos=" + inPos + ", locale=" + loc + ", style=" + style + "]");
}
}
}
use of android.icu.text.TimeZoneFormat.Style in project j2objc by google.
the class TimeZoneFormatTest method TestFormat.
@Test
public void TestFormat() {
// 2013-01-15T00:00:00Z
final Date dateJan = new Date(1358208000000L);
// 2013-07-15T00:00:00Z
final Date dateJul = new Date(1373846400000L);
final Object[][] TESTDATA = { { "en", "America/Los_Angeles", dateJan, Style.GENERIC_LOCATION, "Los Angeles Time", TimeType.UNKNOWN }, { "en", "America/Los_Angeles", dateJan, Style.GENERIC_LONG, "Pacific Time", TimeType.UNKNOWN }, { "en", "America/Los_Angeles", dateJan, Style.SPECIFIC_LONG, "Pacific Standard Time", TimeType.STANDARD }, { "en", "America/Los_Angeles", dateJul, Style.SPECIFIC_LONG, "Pacific Daylight Time", TimeType.DAYLIGHT }, { "ja", "America/Los_Angeles", dateJan, Style.ZONE_ID, "America/Los_Angeles", TimeType.UNKNOWN }, { "fr", "America/Los_Angeles", dateJul, Style.ZONE_ID_SHORT, "uslax", TimeType.UNKNOWN }, { "en", "America/Los_Angeles", dateJan, Style.EXEMPLAR_LOCATION, "Los Angeles", TimeType.UNKNOWN }, { "ja", "Asia/Tokyo", dateJan, Style.GENERIC_LONG, // "日本標準時"
"\u65E5\u672C\u6A19\u6E96\u6642", TimeType.UNKNOWN } };
for (Object[] testCase : TESTDATA) {
TimeZone tz = TimeZone.getTimeZone((String) testCase[1]);
Output<TimeType> timeType = new Output<TimeType>();
ULocale uloc = new ULocale((String) testCase[0]);
TimeZoneFormat tzfmt = TimeZoneFormat.getInstance(uloc);
String out = tzfmt.format((Style) testCase[3], tz, ((Date) testCase[2]).getTime(), timeType);
if (!out.equals(testCase[4]) || timeType.value != testCase[5]) {
errln("Format result for [locale=" + testCase[0] + ",tzid=" + testCase[1] + ",date=" + testCase[2] + ",style=" + testCase[3] + "]: expected [output=" + testCase[4] + ",type=" + testCase[5] + "]; actual [output=" + out + ",type=" + timeType.value + "]");
}
// with equivalent Java Locale
Locale loc = uloc.toLocale();
tzfmt = TimeZoneFormat.getInstance(loc);
out = tzfmt.format((Style) testCase[3], tz, ((Date) testCase[2]).getTime(), timeType);
if (!out.equals(testCase[4]) || timeType.value != testCase[5]) {
errln("Format result for [locale(Java)=" + testCase[0] + ",tzid=" + testCase[1] + ",date=" + testCase[2] + ",style=" + testCase[3] + "]: expected [output=" + testCase[4] + ",type=" + testCase[5] + "]; actual [output=" + out + ",type=" + timeType.value + "]");
}
}
}
Aggregations