Search in sources :

Example 1 with Style

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;
    }
}
Also used : TimeZone(android.icu.util.TimeZone) BasicTimeZone(android.icu.util.BasicTimeZone) ArrayList(java.util.ArrayList) Style(android.icu.text.TimeZoneFormat.Style) AttributedString(java.text.AttributedString) DateNumberFormat(android.icu.impl.DateNumberFormat) ParsePosition(java.text.ParsePosition)

Example 2 with Style

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 + "]");
        }
    }
}
Also used : ULocale(android.icu.util.ULocale) EnumSet(java.util.EnumSet) TimeZoneFormat(android.icu.text.TimeZoneFormat) TimeType(android.icu.text.TimeZoneFormat.TimeType) AtomicInteger(java.util.concurrent.atomic.AtomicInteger) SimpleTimeZone(android.icu.util.SimpleTimeZone) TimeZone(android.icu.util.TimeZone) BasicTimeZone(android.icu.util.BasicTimeZone) Output(android.icu.util.Output) Style(android.icu.text.TimeZoneFormat.Style) ParseOption(android.icu.text.TimeZoneFormat.ParseOption) ParsePosition(java.text.ParsePosition) Test(org.junit.Test)

Example 3 with 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 + "]");
        }
    }
}
Also used : Locale(java.util.Locale) ULocale(android.icu.util.ULocale) ULocale(android.icu.util.ULocale) TimeZoneFormat(android.icu.text.TimeZoneFormat) Date(java.util.Date) TimeType(android.icu.text.TimeZoneFormat.TimeType) SimpleTimeZone(android.icu.util.SimpleTimeZone) TimeZone(android.icu.util.TimeZone) BasicTimeZone(android.icu.util.BasicTimeZone) Output(android.icu.util.Output) Style(android.icu.text.TimeZoneFormat.Style) Test(org.junit.Test)

Aggregations

Style (android.icu.text.TimeZoneFormat.Style)3 BasicTimeZone (android.icu.util.BasicTimeZone)3 TimeZone (android.icu.util.TimeZone)3 TimeZoneFormat (android.icu.text.TimeZoneFormat)2 TimeType (android.icu.text.TimeZoneFormat.TimeType)2 Output (android.icu.util.Output)2 SimpleTimeZone (android.icu.util.SimpleTimeZone)2 ULocale (android.icu.util.ULocale)2 ParsePosition (java.text.ParsePosition)2 Test (org.junit.Test)2 DateNumberFormat (android.icu.impl.DateNumberFormat)1 ParseOption (android.icu.text.TimeZoneFormat.ParseOption)1 AttributedString (java.text.AttributedString)1 ArrayList (java.util.ArrayList)1 Date (java.util.Date)1 EnumSet (java.util.EnumSet)1 Locale (java.util.Locale)1 AtomicInteger (java.util.concurrent.atomic.AtomicInteger)1