Search in sources :

Example 56 with TimeZone

use of android.icu.util.TimeZone in project j2objc by google.

the class TimeZoneFormat method parse.

/**
 * Returns a <code>TimeZone</code> for the given text.
 * <p>
 * <b>Note</b>: The behavior of this method is equivalent to {@link #parse(String, ParsePosition)}.
 * @param text the time zone string
 * @return A <code>TimeZone</code>.
 * @throws ParseException when the input could not be parsed as a time zone string.
 * @see #parse(String, ParsePosition)
 */
public final TimeZone parse(String text) throws ParseException {
    ParsePosition pos = new ParsePosition(0);
    TimeZone tz = parse(text, pos);
    if (pos.getErrorIndex() >= 0) {
        throw new ParseException("Unparseable time zone: \"" + text + "\"", 0);
    }
    assert (tz != null);
    return tz;
}
Also used : TimeZone(android.icu.util.TimeZone) ParseException(java.text.ParseException) ParsePosition(java.text.ParsePosition)

Example 57 with TimeZone

use of android.icu.util.TimeZone in project j2objc by google.

the class TimeZoneFormat method format.

/**
 * {@inheritDoc}
 */
@Override
public StringBuffer format(Object obj, StringBuffer toAppendTo, FieldPosition pos) {
    TimeZone tz = null;
    long date = System.currentTimeMillis();
    if (obj instanceof TimeZone) {
        tz = (TimeZone) obj;
    } else if (obj instanceof Calendar) {
        tz = ((Calendar) obj).getTimeZone();
        date = ((Calendar) obj).getTimeInMillis();
    } else {
        throw new IllegalArgumentException("Cannot format given Object (" + obj.getClass().getName() + ") as a time zone");
    }
    assert (tz != null);
    String result = formatOffsetLocalizedGMT(tz.getOffset(date));
    toAppendTo.append(result);
    if (pos.getFieldAttribute() == DateFormat.Field.TIME_ZONE || pos.getField() == DateFormat.TIMEZONE_FIELD) {
        pos.setBeginIndex(0);
        pos.setEndIndex(result.length());
    }
    return toAppendTo;
}
Also used : TimeZone(android.icu.util.TimeZone) Calendar(android.icu.util.Calendar) AttributedString(java.text.AttributedString)

Example 58 with TimeZone

use of android.icu.util.TimeZone in project j2objc by google.

the class SimpleDateFormat method subFormat.

/**
 * Formats a single field; useFastFormat variant.  Reuses a
 * StringBuffer for results instead of creating a String on the
 * heap for each call.
 *
 * NOTE We don't really need the beginOffset parameter, EXCEPT for
 * the need to support the slow subFormat variant (above) which
 * has to pass it in to us.
 *
 * @deprecated This API is ICU internal only.
 * @hide original deprecated declaration
 * @hide draft / provisional / internal are hidden on Android
 */
@Deprecated
@SuppressWarnings("fallthrough")
protected void subFormat(StringBuffer buf, char ch, int count, int beginOffset, int fieldNum, DisplayContext capitalizationContext, FieldPosition pos, Calendar cal) {
    final int maxIntCount = Integer.MAX_VALUE;
    final int bufstart = buf.length();
    TimeZone tz = cal.getTimeZone();
    long date = cal.getTimeInMillis();
    String result = null;
    int patternCharIndex = getIndexFromChar(ch);
    if (patternCharIndex == -1) {
        if (ch == 'l') {
            // (SMALL LETTER L) deprecated placeholder for leap month marker, ignore
            return;
        } else {
            throw new IllegalArgumentException("Illegal pattern character " + "'" + ch + "' in \"" + pattern + '"');
        }
    }
    final int field = PATTERN_INDEX_TO_CALENDAR_FIELD[patternCharIndex];
    int value = 0;
    // Don't get value unless it is useful
    if (field >= 0) {
        value = (patternCharIndex != DateFormat.RELATED_YEAR) ? cal.get(field) : cal.getRelatedYear();
    }
    NumberFormat currentNumberFormat = getNumberFormat(ch);
    DateFormatSymbols.CapitalizationContextUsage capContextUsageType = DateFormatSymbols.CapitalizationContextUsage.OTHER;
    switch(patternCharIndex) {
        case // 'G' - ERA
        0:
            if (cal.getType().equals("chinese") || cal.getType().equals("dangi")) {
                // moved from ChineseDateFormat
                zeroPaddingNumber(currentNumberFormat, buf, value, 1, 9);
            } else {
                if (count == 5) {
                    safeAppend(formatData.narrowEras, value, buf);
                    capContextUsageType = DateFormatSymbols.CapitalizationContextUsage.ERA_NARROW;
                } else if (count == 4) {
                    safeAppend(formatData.eraNames, value, buf);
                    capContextUsageType = DateFormatSymbols.CapitalizationContextUsage.ERA_WIDE;
                } else {
                    safeAppend(formatData.eras, value, buf);
                    capContextUsageType = DateFormatSymbols.CapitalizationContextUsage.ERA_ABBREV;
                }
            }
            break;
        case // 'U' - YEAR_NAME_FIELD
        30:
            if (formatData.shortYearNames != null && value <= formatData.shortYearNames.length) {
                safeAppend(formatData.shortYearNames, value - 1, buf);
                break;
            }
        // 'y' - YEAR
        case 1:
        case // 'Y' - YEAR_WOY
        18:
            if (override != null && (override.compareTo("hebr") == 0 || override.indexOf("y=hebr") >= 0) && value > HEBREW_CAL_CUR_MILLENIUM_START_YEAR && value < HEBREW_CAL_CUR_MILLENIUM_END_YEAR) {
                value -= HEBREW_CAL_CUR_MILLENIUM_START_YEAR;
            }
            /* According to the specification, if the number of pattern letters ('y') is 2,
             * the year is truncated to 2 digits; otherwise it is interpreted as a number.
             * But the original code process 'y', 'yy', 'yyy' in the same way. and process
             * patterns with 4 or more than 4 'y' characters in the same way.
             * So I change the codes to meet the specification. [Richard/GCl]
             */
            if (count == 2) {
                // clip 1996 to 96
                zeroPaddingNumber(currentNumberFormat, buf, value, 2, 2);
            } else {
                // count = 1 or count > 2
                zeroPaddingNumber(currentNumberFormat, buf, value, count, maxIntCount);
            }
            break;
        // 'M' - MONTH
        case 2:
        case // 'L' - STANDALONE MONTH
        26:
            if (cal.getType().equals("hebrew")) {
                boolean isLeap = HebrewCalendar.isLeapYear(cal.get(Calendar.YEAR));
                if (isLeap && value == 6 && count >= 3) {
                    // Show alternate form for Adar II in leap years in Hebrew calendar.
                    value = 13;
                }
                if (!isLeap && value >= 6 && count < 3) {
                    // Adjust the month number down 1 in Hebrew non-leap years, i.e. Adar is 6, not 7.
                    value--;
                }
            }
            int isLeapMonth = (formatData.leapMonthPatterns != null && formatData.leapMonthPatterns.length >= DateFormatSymbols.DT_MONTH_PATTERN_COUNT) ? cal.get(Calendar.IS_LEAP_MONTH) : 0;
            // should consolidate the next section by using arrays of pointers & counts for the right symbols...
            if (count == 5) {
                if (patternCharIndex == 2) {
                    safeAppendWithMonthPattern(formatData.narrowMonths, value, buf, (isLeapMonth != 0) ? formatData.leapMonthPatterns[DateFormatSymbols.DT_LEAP_MONTH_PATTERN_FORMAT_NARROW] : null);
                } else {
                    safeAppendWithMonthPattern(formatData.standaloneNarrowMonths, value, buf, (isLeapMonth != 0) ? formatData.leapMonthPatterns[DateFormatSymbols.DT_LEAP_MONTH_PATTERN_STANDALONE_NARROW] : null);
                }
                capContextUsageType = DateFormatSymbols.CapitalizationContextUsage.MONTH_NARROW;
            } else if (count == 4) {
                if (patternCharIndex == 2) {
                    safeAppendWithMonthPattern(formatData.months, value, buf, (isLeapMonth != 0) ? formatData.leapMonthPatterns[DateFormatSymbols.DT_LEAP_MONTH_PATTERN_FORMAT_WIDE] : null);
                    capContextUsageType = DateFormatSymbols.CapitalizationContextUsage.MONTH_FORMAT;
                } else {
                    safeAppendWithMonthPattern(formatData.standaloneMonths, value, buf, (isLeapMonth != 0) ? formatData.leapMonthPatterns[DateFormatSymbols.DT_LEAP_MONTH_PATTERN_STANDALONE_WIDE] : null);
                    capContextUsageType = DateFormatSymbols.CapitalizationContextUsage.MONTH_STANDALONE;
                }
            } else if (count == 3) {
                if (patternCharIndex == 2) {
                    safeAppendWithMonthPattern(formatData.shortMonths, value, buf, (isLeapMonth != 0) ? formatData.leapMonthPatterns[DateFormatSymbols.DT_LEAP_MONTH_PATTERN_FORMAT_ABBREV] : null);
                    capContextUsageType = DateFormatSymbols.CapitalizationContextUsage.MONTH_FORMAT;
                } else {
                    safeAppendWithMonthPattern(formatData.standaloneShortMonths, value, buf, (isLeapMonth != 0) ? formatData.leapMonthPatterns[DateFormatSymbols.DT_LEAP_MONTH_PATTERN_STANDALONE_ABBREV] : null);
                    capContextUsageType = DateFormatSymbols.CapitalizationContextUsage.MONTH_STANDALONE;
                }
            } else {
                StringBuffer monthNumber = new StringBuffer();
                zeroPaddingNumber(currentNumberFormat, monthNumber, value + 1, count, maxIntCount);
                String[] monthNumberStrings = new String[1];
                monthNumberStrings[0] = monthNumber.toString();
                safeAppendWithMonthPattern(monthNumberStrings, 0, buf, (isLeapMonth != 0) ? formatData.leapMonthPatterns[DateFormatSymbols.DT_LEAP_MONTH_PATTERN_NUMERIC] : null);
            }
            break;
        case // 'k' - HOUR_OF_DAY (1..24)
        4:
            if (value == 0) {
                zeroPaddingNumber(currentNumberFormat, buf, cal.getMaximum(Calendar.HOUR_OF_DAY) + 1, count, maxIntCount);
            } else {
                zeroPaddingNumber(currentNumberFormat, buf, value, count, maxIntCount);
            }
            break;
        case // 'S' - FRACTIONAL_SECOND
        8:
            // Fractional seconds left-justify
            {
                numberFormat.setMinimumIntegerDigits(Math.min(3, count));
                numberFormat.setMaximumIntegerDigits(maxIntCount);
                if (count == 1) {
                    value /= 100;
                } else if (count == 2) {
                    value /= 10;
                }
                FieldPosition p = new FieldPosition(-1);
                numberFormat.format(value, buf, p);
                if (count > 3) {
                    numberFormat.setMinimumIntegerDigits(count - 3);
                    numberFormat.format(0L, buf, p);
                }
            }
            break;
        case // 'e' - DOW_LOCAL (use DOW_LOCAL for numeric, DAY_OF_WEEK for format names)
        19:
            if (count < 3) {
                zeroPaddingNumber(currentNumberFormat, buf, value, count, maxIntCount);
                break;
            }
            // For alpha day-of-week, we don't want DOW_LOCAL,
            // we need the standard DAY_OF_WEEK.
            value = cal.get(Calendar.DAY_OF_WEEK);
        // fall through, do not break here
        case // 'E' - DAY_OF_WEEK
        9:
            if (count == 5) {
                safeAppend(formatData.narrowWeekdays, value, buf);
                capContextUsageType = DateFormatSymbols.CapitalizationContextUsage.DAY_NARROW;
            } else if (count == 4) {
                safeAppend(formatData.weekdays, value, buf);
                capContextUsageType = DateFormatSymbols.CapitalizationContextUsage.DAY_FORMAT;
            } else if (count == 6 && formatData.shorterWeekdays != null) {
                safeAppend(formatData.shorterWeekdays, value, buf);
                capContextUsageType = DateFormatSymbols.CapitalizationContextUsage.DAY_FORMAT;
            } else {
                // count <= 3, use abbreviated form if exists
                safeAppend(formatData.shortWeekdays, value, buf);
                capContextUsageType = DateFormatSymbols.CapitalizationContextUsage.DAY_FORMAT;
            }
            break;
        case // 'a' - AM_PM
        14:
            // formatData.ampmsNarrow may be null when deserializing DateFormatSymbolsfrom old version
            if (count < 5 || formatData.ampmsNarrow == null) {
                safeAppend(formatData.ampms, value, buf);
            } else {
                safeAppend(formatData.ampmsNarrow, value, buf);
            }
            break;
        case // 'h' - HOUR (1..12)
        15:
            if (value == 0) {
                zeroPaddingNumber(currentNumberFormat, buf, cal.getLeastMaximum(Calendar.HOUR) + 1, count, maxIntCount);
            } else {
                zeroPaddingNumber(currentNumberFormat, buf, value, count, maxIntCount);
            }
            break;
        case // 'z' - TIMEZONE_FIELD
        17:
            if (count < 4) {
                // "z", "zz", "zzz"
                result = tzFormat().format(Style.SPECIFIC_SHORT, tz, date);
                capContextUsageType = DateFormatSymbols.CapitalizationContextUsage.METAZONE_SHORT;
            } else {
                result = tzFormat().format(Style.SPECIFIC_LONG, tz, date);
                capContextUsageType = DateFormatSymbols.CapitalizationContextUsage.METAZONE_LONG;
            }
            buf.append(result);
            break;
        case // 'Z' - TIMEZONE_RFC_FIELD
        23:
            if (count < 4) {
                // RFC822 format - equivalent to ISO 8601 local offset fixed width format
                result = tzFormat().format(Style.ISO_BASIC_LOCAL_FULL, tz, date);
            } else if (count == 5) {
                // ISO 8601 extended format
                result = tzFormat().format(Style.ISO_EXTENDED_FULL, tz, date);
            } else {
                // long form, localized GMT pattern
                result = tzFormat().format(Style.LOCALIZED_GMT, tz, date);
            }
            buf.append(result);
            break;
        case // 'v' - TIMEZONE_GENERIC_FIELD
        24:
            if (count == 1) {
                // "v"
                result = tzFormat().format(Style.GENERIC_SHORT, tz, date);
                capContextUsageType = DateFormatSymbols.CapitalizationContextUsage.METAZONE_SHORT;
            } else if (count == 4) {
                // "vvvv"
                result = tzFormat().format(Style.GENERIC_LONG, tz, date);
                capContextUsageType = DateFormatSymbols.CapitalizationContextUsage.METAZONE_LONG;
            }
            buf.append(result);
            break;
        case // 'V' - TIMEZONE_SPECIAL_FIELD
        29:
            if (count == 1) {
                // "V"
                result = tzFormat().format(Style.ZONE_ID_SHORT, tz, date);
            } else if (count == 2) {
                // "VV"
                result = tzFormat().format(Style.ZONE_ID, tz, date);
            } else if (count == 3) {
                // "VVV"
                result = tzFormat().format(Style.EXEMPLAR_LOCATION, tz, date);
            } else if (count == 4) {
                // "VVVV"
                result = tzFormat().format(Style.GENERIC_LOCATION, tz, date);
                capContextUsageType = DateFormatSymbols.CapitalizationContextUsage.ZONE_LONG;
            }
            buf.append(result);
            break;
        case // 'O' - TIMEZONE_LOCALIZED_GMT_OFFSET_FIELD
        31:
            if (count == 1) {
                // "O" - Short Localized GMT format
                result = tzFormat().format(Style.LOCALIZED_GMT_SHORT, tz, date);
            } else if (count == 4) {
                // "OOOO" - Localized GMT format
                result = tzFormat().format(Style.LOCALIZED_GMT, tz, date);
            }
            buf.append(result);
            break;
        case // 'X' - TIMEZONE_ISO_FIELD
        32:
            if (count == 1) {
                // "X" - ISO Basic/Short
                result = tzFormat().format(Style.ISO_BASIC_SHORT, tz, date);
            } else if (count == 2) {
                // "XX" - ISO Basic/Fixed
                result = tzFormat().format(Style.ISO_BASIC_FIXED, tz, date);
            } else if (count == 3) {
                // "XXX" - ISO Extended/Fixed
                result = tzFormat().format(Style.ISO_EXTENDED_FIXED, tz, date);
            } else if (count == 4) {
                // "XXXX" - ISO Basic/Optional second field
                result = tzFormat().format(Style.ISO_BASIC_FULL, tz, date);
            } else if (count == 5) {
                // "XXXXX" - ISO Extended/Optional second field
                result = tzFormat().format(Style.ISO_EXTENDED_FULL, tz, date);
            }
            buf.append(result);
            break;
        case // 'x' - TIMEZONE_ISO_LOCAL_FIELD
        33:
            if (count == 1) {
                // "x" - ISO Local Basic/Short
                result = tzFormat().format(Style.ISO_BASIC_LOCAL_SHORT, tz, date);
            } else if (count == 2) {
                // "x" - ISO Local Basic/Fixed
                result = tzFormat().format(Style.ISO_BASIC_LOCAL_FIXED, tz, date);
            } else if (count == 3) {
                // "xxx" - ISO Local Extended/Fixed
                result = tzFormat().format(Style.ISO_EXTENDED_LOCAL_FIXED, tz, date);
            } else if (count == 4) {
                // "xxxx" - ISO Local Basic/Optional second field
                result = tzFormat().format(Style.ISO_BASIC_LOCAL_FULL, tz, date);
            } else if (count == 5) {
                // "xxxxx" - ISO Local Extended/Optional second field
                result = tzFormat().format(Style.ISO_EXTENDED_LOCAL_FULL, tz, date);
            }
            buf.append(result);
            break;
        case // 'c' - STANDALONE DAY (use DOW_LOCAL for numeric, DAY_OF_WEEK for standalone)
        25:
            if (count < 3) {
                zeroPaddingNumber(currentNumberFormat, buf, value, 1, maxIntCount);
                break;
            }
            // For alpha day-of-week, we don't want DOW_LOCAL,
            // we need the standard DAY_OF_WEEK.
            value = cal.get(Calendar.DAY_OF_WEEK);
            if (count == 5) {
                safeAppend(formatData.standaloneNarrowWeekdays, value, buf);
                capContextUsageType = DateFormatSymbols.CapitalizationContextUsage.DAY_NARROW;
            } else if (count == 4) {
                safeAppend(formatData.standaloneWeekdays, value, buf);
                capContextUsageType = DateFormatSymbols.CapitalizationContextUsage.DAY_STANDALONE;
            } else if (count == 6 && formatData.standaloneShorterWeekdays != null) {
                safeAppend(formatData.standaloneShorterWeekdays, value, buf);
                capContextUsageType = DateFormatSymbols.CapitalizationContextUsage.DAY_STANDALONE;
            } else {
                // count == 3
                safeAppend(formatData.standaloneShortWeekdays, value, buf);
                capContextUsageType = DateFormatSymbols.CapitalizationContextUsage.DAY_STANDALONE;
            }
            break;
        case // 'Q' - QUARTER
        27:
            if (count >= 4) {
                safeAppend(formatData.quarters, value / 3, buf);
            } else if (count == 3) {
                safeAppend(formatData.shortQuarters, value / 3, buf);
            } else {
                zeroPaddingNumber(currentNumberFormat, buf, (value / 3) + 1, count, maxIntCount);
            }
            break;
        case // 'q' - STANDALONE QUARTER
        28:
            if (count >= 4) {
                safeAppend(formatData.standaloneQuarters, value / 3, buf);
            } else if (count == 3) {
                safeAppend(formatData.standaloneShortQuarters, value / 3, buf);
            } else {
                zeroPaddingNumber(currentNumberFormat, buf, (value / 3) + 1, count, maxIntCount);
            }
            break;
        case // 'b' - am/pm/noon/midnight
        35:
            {
                // Note: "midnight" can be ambiguous as to whether it refers to beginning of day or end of day.
                // For ICU 57 output of "midnight" is temporarily suppressed.
                int hour = cal.get(Calendar.HOUR_OF_DAY);
                String toAppend = null;
                // This means minutes and seconds, if present, must be zero.
                if ((/*hour == 0 ||*/
                hour == 12) && (!hasMinute || cal.get(Calendar.MINUTE) == 0) && (!hasSecond || cal.get(Calendar.SECOND) == 0)) {
                    // Stealing am/pm value to use as our array index.
                    // It works out: am/midnight are both 0, pm/noon are both 1,
                    // 12 am is 12 midnight, and 12 pm is 12 noon.
                    value = cal.get(Calendar.AM_PM);
                    if (count == 3) {
                        toAppend = formatData.abbreviatedDayPeriods[value];
                    } else if (count == 4 || count > 5) {
                        toAppend = formatData.wideDayPeriods[value];
                    } else {
                        // count == 5
                        toAppend = formatData.narrowDayPeriods[value];
                    }
                }
                if (toAppend == null) {
                    // Time isn't exactly midnight or noon (as displayed) or localized string doesn't
                    // exist for requested period. Fall back to am/pm instead.
                    subFormat(buf, 'a', count, beginOffset, fieldNum, capitalizationContext, pos, cal);
                } else {
                    buf.append(toAppend);
                }
                break;
            }
        case // 'B' - flexible day period
        36:
            {
                // TODO: Maybe fetch the DayperiodRules during initialization (instead of at the first
                // loading of an instance) if a relevant pattern character (b or B) is used.
                DayPeriodRules ruleSet = DayPeriodRules.getInstance(getLocale());
                if (ruleSet == null) {
                    // Data doesn't exist for the locale we're looking for.
                    // Fall back to am/pm.
                    subFormat(buf, 'a', count, beginOffset, fieldNum, capitalizationContext, pos, cal);
                    break;
                }
                // Get current display time.
                int hour = cal.get(Calendar.HOUR_OF_DAY);
                int minute = 0;
                int second = 0;
                if (hasMinute) {
                    minute = cal.get(Calendar.MINUTE);
                }
                if (hasSecond) {
                    second = cal.get(Calendar.SECOND);
                }
                // Determine day period.
                DayPeriodRules.DayPeriod periodType;
                if (hour == 0 && minute == 0 && second == 0 && ruleSet.hasMidnight()) {
                    periodType = DayPeriodRules.DayPeriod.MIDNIGHT;
                } else if (hour == 12 && minute == 0 && second == 0 && ruleSet.hasNoon()) {
                    periodType = DayPeriodRules.DayPeriod.NOON;
                } else {
                    periodType = ruleSet.getDayPeriodForHour(hour);
                }
                // Get localized string.
                assert (periodType != null);
                String toAppend = null;
                int index;
                if (periodType != DayPeriodRules.DayPeriod.AM && periodType != DayPeriodRules.DayPeriod.PM && periodType != DayPeriodRules.DayPeriod.MIDNIGHT) {
                    index = periodType.ordinal();
                    if (count <= 3) {
                        // i.e. short
                        toAppend = formatData.abbreviatedDayPeriods[index];
                    } else if (count == 4 || count > 5) {
                        toAppend = formatData.wideDayPeriods[index];
                    } else {
                        // count == 5
                        toAppend = formatData.narrowDayPeriods[index];
                    }
                }
                // Midnight/Noon -> General Periods.
                if (toAppend == null && (periodType == DayPeriodRules.DayPeriod.MIDNIGHT || periodType == DayPeriodRules.DayPeriod.NOON)) {
                    periodType = ruleSet.getDayPeriodForHour(hour);
                    index = periodType.ordinal();
                    if (count <= 3) {
                        // i.e. short
                        toAppend = formatData.abbreviatedDayPeriods[index];
                    } else if (count == 4 || count > 5) {
                        toAppend = formatData.wideDayPeriods[index];
                    } else {
                        // count == 5
                        toAppend = formatData.narrowDayPeriods[index];
                    }
                }
                // General Periods -> AM/PM.
                if (periodType == DayPeriodRules.DayPeriod.AM || periodType == DayPeriodRules.DayPeriod.PM || toAppend == null) {
                    subFormat(buf, 'a', count, beginOffset, fieldNum, capitalizationContext, pos, cal);
                } else {
                    buf.append(toAppend);
                }
                break;
            }
        case // TIME SEPARATOR (no pattern character currently defined, we should
        37:
            // not get here but leave support in for future definition.
            buf.append(formatData.getTimeSeparatorString());
            break;
        default:
            // case 3: // 'd' - DATE
            // case 5: // 'H' - HOUR_OF_DAY (0..23)
            // case 6: // 'm' - MINUTE
            // case 7: // 's' - SECOND
            // case 10: // 'D' - DAY_OF_YEAR
            // case 11: // 'F' - DAY_OF_WEEK_IN_MONTH
            // case 12: // 'w' - WEEK_OF_YEAR
            // case 13: // 'W' - WEEK_OF_MONTH
            // case 16: // 'K' - HOUR (0..11)
            // case 20: // 'u' - EXTENDED_YEAR
            // case 21: // 'g' - JULIAN_DAY
            // case 22: // 'A' - MILLISECONDS_IN_DAY
            zeroPaddingNumber(currentNumberFormat, buf, value, count, maxIntCount);
            break;
    }
    if (fieldNum == 0 && capitalizationContext != null && UCharacter.isLowerCase(buf.codePointAt(bufstart))) {
        boolean titlecase = false;
        switch(capitalizationContext) {
            case CAPITALIZATION_FOR_BEGINNING_OF_SENTENCE:
                titlecase = true;
                break;
            case CAPITALIZATION_FOR_UI_LIST_OR_MENU:
            case CAPITALIZATION_FOR_STANDALONE:
                if (formatData.capitalization != null) {
                    boolean[] transforms = formatData.capitalization.get(capContextUsageType);
                    titlecase = (capitalizationContext == DisplayContext.CAPITALIZATION_FOR_UI_LIST_OR_MENU) ? transforms[0] : transforms[1];
                }
                break;
            default:
                break;
        }
        if (titlecase) {
            if (capitalizationBrkIter == null) {
                // should only happen when deserializing, etc.
                capitalizationBrkIter = BreakIterator.getSentenceInstance(locale);
            }
            // bufstart or beginOffset, should be the same
            String firstField = buf.substring(bufstart);
            String firstFieldTitleCase = UCharacter.toTitleCase(locale, firstField, capitalizationBrkIter, UCharacter.TITLECASE_NO_LOWERCASE | UCharacter.TITLECASE_NO_BREAK_ADJUSTMENT);
            buf.replace(bufstart, buf.length(), firstFieldTitleCase);
        }
    }
    // Set the FieldPosition (for the first occurrence only)
    if (pos.getBeginIndex() == pos.getEndIndex()) {
        if (pos.getField() == PATTERN_INDEX_TO_DATE_FORMAT_FIELD[patternCharIndex]) {
            pos.setBeginIndex(beginOffset);
            pos.setEndIndex(beginOffset + buf.length() - bufstart);
        } else if (pos.getFieldAttribute() == PATTERN_INDEX_TO_DATE_FORMAT_ATTRIBUTE[patternCharIndex]) {
            pos.setBeginIndex(beginOffset);
            pos.setEndIndex(beginOffset + buf.length() - bufstart);
        }
    }
}
Also used : DayPeriodRules(android.icu.impl.DayPeriodRules) AttributedString(java.text.AttributedString) FieldPosition(java.text.FieldPosition) TimeZone(android.icu.util.TimeZone) BasicTimeZone(android.icu.util.BasicTimeZone) DateNumberFormat(android.icu.impl.DateNumberFormat)

Example 59 with TimeZone

use of android.icu.util.TimeZone 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 60 with TimeZone

use of android.icu.util.TimeZone in project j2objc by google.

the class SimpleDateFormat method format.

/**
 * Formats a date or time, which is the standard millis
 * since January 1, 1970, 00:00:00 GMT.
 * <p>Example: using the US locale:
 * "yyyy.MM.dd G 'at' HH:mm:ss zzz" -&gt;&gt; 1996.07.10 AD at 15:08:56 PDT
 * @param cal the calendar whose date-time value is to be formatted into a date-time string
 * @param toAppendTo where the new date-time text is to be appended
 * @param pos the formatting position. On input: an alignment field,
 * if desired. On output: the offsets of the alignment field.
 * @return the formatted date-time string.
 * @see DateFormat
 */
@Override
public StringBuffer format(Calendar cal, StringBuffer toAppendTo, FieldPosition pos) {
    TimeZone backupTZ = null;
    if (cal != calendar && !cal.getType().equals(calendar.getType())) {
        // Different calendar type
        // We use the time and time zone from the input calendar, but
        // do not use the input calendar for field calculation.
        calendar.setTimeInMillis(cal.getTimeInMillis());
        backupTZ = calendar.getTimeZone();
        calendar.setTimeZone(cal.getTimeZone());
        cal = calendar;
    }
    StringBuffer result = format(cal, getContext(DisplayContext.Type.CAPITALIZATION), toAppendTo, pos, null);
    if (backupTZ != null) {
        // Restore the original time zone
        calendar.setTimeZone(backupTZ);
    }
    return result;
}
Also used : TimeZone(android.icu.util.TimeZone) BasicTimeZone(android.icu.util.BasicTimeZone)

Aggregations

TimeZone (android.icu.util.TimeZone)125 Test (org.junit.Test)98 SimpleTimeZone (android.icu.util.SimpleTimeZone)76 Date (java.util.Date)63 GregorianCalendar (android.icu.util.GregorianCalendar)49 Calendar (android.icu.util.Calendar)42 BasicTimeZone (android.icu.util.BasicTimeZone)41 SimpleDateFormat (android.icu.text.SimpleDateFormat)36 ULocale (android.icu.util.ULocale)31 RuleBasedTimeZone (android.icu.util.RuleBasedTimeZone)24 VTimeZone (android.icu.util.VTimeZone)23 DateFormat (android.icu.text.DateFormat)19 JavaTimeZone (android.icu.impl.JavaTimeZone)18 NativeTimeZone (com.google.j2objc.util.NativeTimeZone)18 JapaneseCalendar (android.icu.util.JapaneseCalendar)15 FieldPosition (java.text.FieldPosition)15 BuddhistCalendar (android.icu.util.BuddhistCalendar)13 ParsePosition (java.text.ParsePosition)13 ChineseCalendar (android.icu.util.ChineseCalendar)12 ParseException (java.text.ParseException)12