13b852e3489e995600fce19dfdbf3a5d769374d74Neil Fuller/* 23b852e3489e995600fce19dfdbf3a5d769374d74Neil Fuller * Based on the UCB version of strftime.c with the copyright notice appearing below. 33b852e3489e995600fce19dfdbf3a5d769374d74Neil Fuller */ 43b852e3489e995600fce19dfdbf3a5d769374d74Neil Fuller 53b852e3489e995600fce19dfdbf3a5d769374d74Neil Fuller/* 63b852e3489e995600fce19dfdbf3a5d769374d74Neil Fuller** Copyright (c) 1989 The Regents of the University of California. 73b852e3489e995600fce19dfdbf3a5d769374d74Neil Fuller** All rights reserved. 83b852e3489e995600fce19dfdbf3a5d769374d74Neil Fuller** 93b852e3489e995600fce19dfdbf3a5d769374d74Neil Fuller** Redistribution and use in source and binary forms are permitted 103b852e3489e995600fce19dfdbf3a5d769374d74Neil Fuller** provided that the above copyright notice and this paragraph are 113b852e3489e995600fce19dfdbf3a5d769374d74Neil Fuller** duplicated in all such forms and that any documentation, 123b852e3489e995600fce19dfdbf3a5d769374d74Neil Fuller** advertising materials, and other materials related to such 133b852e3489e995600fce19dfdbf3a5d769374d74Neil Fuller** distribution and use acknowledge that the software was developed 143b852e3489e995600fce19dfdbf3a5d769374d74Neil Fuller** by the University of California, Berkeley. The name of the 153b852e3489e995600fce19dfdbf3a5d769374d74Neil Fuller** University may not be used to endorse or promote products derived 163b852e3489e995600fce19dfdbf3a5d769374d74Neil Fuller** from this software without specific prior written permission. 173b852e3489e995600fce19dfdbf3a5d769374d74Neil Fuller** THIS SOFTWARE IS PROVIDED "AS IS" AND WITHOUT ANY EXPRESS OR 183b852e3489e995600fce19dfdbf3a5d769374d74Neil Fuller** IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED 193b852e3489e995600fce19dfdbf3a5d769374d74Neil Fuller** WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. 203b852e3489e995600fce19dfdbf3a5d769374d74Neil Fuller*/ 213b852e3489e995600fce19dfdbf3a5d769374d74Neil Fullerpackage android.text.format; 223b852e3489e995600fce19dfdbf3a5d769374d74Neil Fuller 233b852e3489e995600fce19dfdbf3a5d769374d74Neil Fullerimport android.content.res.Resources; 243b852e3489e995600fce19dfdbf3a5d769374d74Neil Fuller 2516566656cd2f81f62c8693e64de68062f2680161Neil Fullerimport java.nio.CharBuffer; 263b852e3489e995600fce19dfdbf3a5d769374d74Neil Fullerimport java.util.Formatter; 273b852e3489e995600fce19dfdbf3a5d769374d74Neil Fullerimport java.util.Locale; 283b852e3489e995600fce19dfdbf3a5d769374d74Neil Fullerimport java.util.TimeZone; 293b852e3489e995600fce19dfdbf3a5d769374d74Neil Fullerimport libcore.icu.LocaleData; 303b852e3489e995600fce19dfdbf3a5d769374d74Neil Fullerimport libcore.util.ZoneInfo; 313b852e3489e995600fce19dfdbf3a5d769374d74Neil Fuller 323b852e3489e995600fce19dfdbf3a5d769374d74Neil Fuller/** 3316566656cd2f81f62c8693e64de68062f2680161Neil Fuller * Formatting logic for {@link Time}. Contains a port of Bionic's broken strftime_tz to Java. 343b852e3489e995600fce19dfdbf3a5d769374d74Neil Fuller * 353b852e3489e995600fce19dfdbf3a5d769374d74Neil Fuller * <p>This class is not thread safe. 363b852e3489e995600fce19dfdbf3a5d769374d74Neil Fuller */ 373b852e3489e995600fce19dfdbf3a5d769374d74Neil Fullerclass TimeFormatter { 3816566656cd2f81f62c8693e64de68062f2680161Neil Fuller // An arbitrary value outside the range representable by a char. 3916566656cd2f81f62c8693e64de68062f2680161Neil Fuller private static final int FORCE_LOWER_CASE = -1; 403b852e3489e995600fce19dfdbf3a5d769374d74Neil Fuller 413b852e3489e995600fce19dfdbf3a5d769374d74Neil Fuller private static final int SECSPERMIN = 60; 423b852e3489e995600fce19dfdbf3a5d769374d74Neil Fuller private static final int MINSPERHOUR = 60; 433b852e3489e995600fce19dfdbf3a5d769374d74Neil Fuller private static final int DAYSPERWEEK = 7; 443b852e3489e995600fce19dfdbf3a5d769374d74Neil Fuller private static final int MONSPERYEAR = 12; 453b852e3489e995600fce19dfdbf3a5d769374d74Neil Fuller private static final int HOURSPERDAY = 24; 463b852e3489e995600fce19dfdbf3a5d769374d74Neil Fuller private static final int DAYSPERLYEAR = 366; 473b852e3489e995600fce19dfdbf3a5d769374d74Neil Fuller private static final int DAYSPERNYEAR = 365; 483b852e3489e995600fce19dfdbf3a5d769374d74Neil Fuller 493b852e3489e995600fce19dfdbf3a5d769374d74Neil Fuller /** 503b852e3489e995600fce19dfdbf3a5d769374d74Neil Fuller * The Locale for which the cached LocaleData and formats have been loaded. 513b852e3489e995600fce19dfdbf3a5d769374d74Neil Fuller */ 523b852e3489e995600fce19dfdbf3a5d769374d74Neil Fuller private static Locale sLocale; 533b852e3489e995600fce19dfdbf3a5d769374d74Neil Fuller private static LocaleData sLocaleData; 543b852e3489e995600fce19dfdbf3a5d769374d74Neil Fuller private static String sTimeOnlyFormat; 553b852e3489e995600fce19dfdbf3a5d769374d74Neil Fuller private static String sDateOnlyFormat; 563b852e3489e995600fce19dfdbf3a5d769374d74Neil Fuller private static String sDateTimeFormat; 573b852e3489e995600fce19dfdbf3a5d769374d74Neil Fuller 583b852e3489e995600fce19dfdbf3a5d769374d74Neil Fuller private final LocaleData localeData; 593b852e3489e995600fce19dfdbf3a5d769374d74Neil Fuller private final String dateTimeFormat; 603b852e3489e995600fce19dfdbf3a5d769374d74Neil Fuller private final String timeOnlyFormat; 613b852e3489e995600fce19dfdbf3a5d769374d74Neil Fuller private final String dateOnlyFormat; 623b852e3489e995600fce19dfdbf3a5d769374d74Neil Fuller 633b852e3489e995600fce19dfdbf3a5d769374d74Neil Fuller private StringBuilder outputBuilder; 6416566656cd2f81f62c8693e64de68062f2680161Neil Fuller private Formatter numberFormatter; 653b852e3489e995600fce19dfdbf3a5d769374d74Neil Fuller 663b852e3489e995600fce19dfdbf3a5d769374d74Neil Fuller public TimeFormatter() { 673b852e3489e995600fce19dfdbf3a5d769374d74Neil Fuller synchronized (TimeFormatter.class) { 683b852e3489e995600fce19dfdbf3a5d769374d74Neil Fuller Locale locale = Locale.getDefault(); 693b852e3489e995600fce19dfdbf3a5d769374d74Neil Fuller 703b852e3489e995600fce19dfdbf3a5d769374d74Neil Fuller if (sLocale == null || !(locale.equals(sLocale))) { 713b852e3489e995600fce19dfdbf3a5d769374d74Neil Fuller sLocale = locale; 723b852e3489e995600fce19dfdbf3a5d769374d74Neil Fuller sLocaleData = LocaleData.get(locale); 733b852e3489e995600fce19dfdbf3a5d769374d74Neil Fuller 743b852e3489e995600fce19dfdbf3a5d769374d74Neil Fuller Resources r = Resources.getSystem(); 753b852e3489e995600fce19dfdbf3a5d769374d74Neil Fuller sTimeOnlyFormat = r.getString(com.android.internal.R.string.time_of_day); 763b852e3489e995600fce19dfdbf3a5d769374d74Neil Fuller sDateOnlyFormat = r.getString(com.android.internal.R.string.month_day_year); 773b852e3489e995600fce19dfdbf3a5d769374d74Neil Fuller sDateTimeFormat = r.getString(com.android.internal.R.string.date_and_time); 783b852e3489e995600fce19dfdbf3a5d769374d74Neil Fuller } 793b852e3489e995600fce19dfdbf3a5d769374d74Neil Fuller 803b852e3489e995600fce19dfdbf3a5d769374d74Neil Fuller this.dateTimeFormat = sDateTimeFormat; 813b852e3489e995600fce19dfdbf3a5d769374d74Neil Fuller this.timeOnlyFormat = sTimeOnlyFormat; 823b852e3489e995600fce19dfdbf3a5d769374d74Neil Fuller this.dateOnlyFormat = sDateOnlyFormat; 833b852e3489e995600fce19dfdbf3a5d769374d74Neil Fuller localeData = sLocaleData; 843b852e3489e995600fce19dfdbf3a5d769374d74Neil Fuller } 853b852e3489e995600fce19dfdbf3a5d769374d74Neil Fuller } 863b852e3489e995600fce19dfdbf3a5d769374d74Neil Fuller 873b852e3489e995600fce19dfdbf3a5d769374d74Neil Fuller /** 883b852e3489e995600fce19dfdbf3a5d769374d74Neil Fuller * Format the specified {@code wallTime} using {@code pattern}. The output is returned. 893b852e3489e995600fce19dfdbf3a5d769374d74Neil Fuller */ 903b852e3489e995600fce19dfdbf3a5d769374d74Neil Fuller public String format(String pattern, ZoneInfo.WallTime wallTime, ZoneInfo zoneInfo) { 913b852e3489e995600fce19dfdbf3a5d769374d74Neil Fuller try { 923b852e3489e995600fce19dfdbf3a5d769374d74Neil Fuller StringBuilder stringBuilder = new StringBuilder(); 933b852e3489e995600fce19dfdbf3a5d769374d74Neil Fuller 943b852e3489e995600fce19dfdbf3a5d769374d74Neil Fuller outputBuilder = stringBuilder; 9516566656cd2f81f62c8693e64de68062f2680161Neil Fuller // This uses the US locale because number localization is handled separately (see below) 9616566656cd2f81f62c8693e64de68062f2680161Neil Fuller // and locale sensitive strings are output directly using outputBuilder. 9716566656cd2f81f62c8693e64de68062f2680161Neil Fuller numberFormatter = new Formatter(stringBuilder, Locale.US); 983b852e3489e995600fce19dfdbf3a5d769374d74Neil Fuller 993b852e3489e995600fce19dfdbf3a5d769374d74Neil Fuller formatInternal(pattern, wallTime, zoneInfo); 1003b852e3489e995600fce19dfdbf3a5d769374d74Neil Fuller String result = stringBuilder.toString(); 1013b852e3489e995600fce19dfdbf3a5d769374d74Neil Fuller // This behavior is the source of a bug since some formats are defined as being 10216566656cd2f81f62c8693e64de68062f2680161Neil Fuller // in ASCII and not localized. 1033b852e3489e995600fce19dfdbf3a5d769374d74Neil Fuller if (localeData.zeroDigit != '0') { 1043b852e3489e995600fce19dfdbf3a5d769374d74Neil Fuller result = localizeDigits(result); 1053b852e3489e995600fce19dfdbf3a5d769374d74Neil Fuller } 1063b852e3489e995600fce19dfdbf3a5d769374d74Neil Fuller return result; 1073b852e3489e995600fce19dfdbf3a5d769374d74Neil Fuller } finally { 1083b852e3489e995600fce19dfdbf3a5d769374d74Neil Fuller outputBuilder = null; 10916566656cd2f81f62c8693e64de68062f2680161Neil Fuller numberFormatter = null; 1103b852e3489e995600fce19dfdbf3a5d769374d74Neil Fuller } 1113b852e3489e995600fce19dfdbf3a5d769374d74Neil Fuller } 1123b852e3489e995600fce19dfdbf3a5d769374d74Neil Fuller 1133b852e3489e995600fce19dfdbf3a5d769374d74Neil Fuller private String localizeDigits(String s) { 1143b852e3489e995600fce19dfdbf3a5d769374d74Neil Fuller int length = s.length(); 1153b852e3489e995600fce19dfdbf3a5d769374d74Neil Fuller int offsetToLocalizedDigits = localeData.zeroDigit - '0'; 1163b852e3489e995600fce19dfdbf3a5d769374d74Neil Fuller StringBuilder result = new StringBuilder(length); 1173b852e3489e995600fce19dfdbf3a5d769374d74Neil Fuller for (int i = 0; i < length; ++i) { 1183b852e3489e995600fce19dfdbf3a5d769374d74Neil Fuller char ch = s.charAt(i); 1193b852e3489e995600fce19dfdbf3a5d769374d74Neil Fuller if (ch >= '0' && ch <= '9') { 1203b852e3489e995600fce19dfdbf3a5d769374d74Neil Fuller ch += offsetToLocalizedDigits; 1213b852e3489e995600fce19dfdbf3a5d769374d74Neil Fuller } 1223b852e3489e995600fce19dfdbf3a5d769374d74Neil Fuller result.append(ch); 1233b852e3489e995600fce19dfdbf3a5d769374d74Neil Fuller } 1243b852e3489e995600fce19dfdbf3a5d769374d74Neil Fuller return result.toString(); 1253b852e3489e995600fce19dfdbf3a5d769374d74Neil Fuller } 1263b852e3489e995600fce19dfdbf3a5d769374d74Neil Fuller 1273b852e3489e995600fce19dfdbf3a5d769374d74Neil Fuller /** 1283b852e3489e995600fce19dfdbf3a5d769374d74Neil Fuller * Format the specified {@code wallTime} using {@code pattern}. The output is written to 1293b852e3489e995600fce19dfdbf3a5d769374d74Neil Fuller * {@link #outputBuilder}. 1303b852e3489e995600fce19dfdbf3a5d769374d74Neil Fuller */ 1313b852e3489e995600fce19dfdbf3a5d769374d74Neil Fuller private void formatInternal(String pattern, ZoneInfo.WallTime wallTime, ZoneInfo zoneInfo) { 13216566656cd2f81f62c8693e64de68062f2680161Neil Fuller CharBuffer formatBuffer = CharBuffer.wrap(pattern); 1333b852e3489e995600fce19dfdbf3a5d769374d74Neil Fuller while (formatBuffer.remaining() > 0) { 13416566656cd2f81f62c8693e64de68062f2680161Neil Fuller boolean outputCurrentChar = true; 13516566656cd2f81f62c8693e64de68062f2680161Neil Fuller char currentChar = formatBuffer.get(formatBuffer.position()); 13616566656cd2f81f62c8693e64de68062f2680161Neil Fuller if (currentChar == '%') { 13716566656cd2f81f62c8693e64de68062f2680161Neil Fuller outputCurrentChar = handleToken(formatBuffer, wallTime, zoneInfo); 1383b852e3489e995600fce19dfdbf3a5d769374d74Neil Fuller } 13916566656cd2f81f62c8693e64de68062f2680161Neil Fuller if (outputCurrentChar) { 14016566656cd2f81f62c8693e64de68062f2680161Neil Fuller outputBuilder.append(formatBuffer.get(formatBuffer.position())); 1413b852e3489e995600fce19dfdbf3a5d769374d74Neil Fuller } 1423b852e3489e995600fce19dfdbf3a5d769374d74Neil Fuller formatBuffer.position(formatBuffer.position() + 1); 1433b852e3489e995600fce19dfdbf3a5d769374d74Neil Fuller } 1443b852e3489e995600fce19dfdbf3a5d769374d74Neil Fuller } 1453b852e3489e995600fce19dfdbf3a5d769374d74Neil Fuller 14616566656cd2f81f62c8693e64de68062f2680161Neil Fuller private boolean handleToken(CharBuffer formatBuffer, ZoneInfo.WallTime wallTime, 1473b852e3489e995600fce19dfdbf3a5d769374d74Neil Fuller ZoneInfo zoneInfo) { 1483b852e3489e995600fce19dfdbf3a5d769374d74Neil Fuller 14916566656cd2f81f62c8693e64de68062f2680161Neil Fuller // The char at formatBuffer.position() is expected to be '%' at this point. 1503b852e3489e995600fce19dfdbf3a5d769374d74Neil Fuller int modifier = 0; 1513b852e3489e995600fce19dfdbf3a5d769374d74Neil Fuller while (formatBuffer.remaining() > 1) { 15216566656cd2f81f62c8693e64de68062f2680161Neil Fuller // Increment the position then get the new current char. 1533b852e3489e995600fce19dfdbf3a5d769374d74Neil Fuller formatBuffer.position(formatBuffer.position() + 1); 15416566656cd2f81f62c8693e64de68062f2680161Neil Fuller char currentChar = formatBuffer.get(formatBuffer.position()); 15516566656cd2f81f62c8693e64de68062f2680161Neil Fuller switch (currentChar) { 1563b852e3489e995600fce19dfdbf3a5d769374d74Neil Fuller case 'A': 1573b852e3489e995600fce19dfdbf3a5d769374d74Neil Fuller modifyAndAppend((wallTime.getWeekDay() < 0 1583b852e3489e995600fce19dfdbf3a5d769374d74Neil Fuller || wallTime.getWeekDay() >= DAYSPERWEEK) 1593b852e3489e995600fce19dfdbf3a5d769374d74Neil Fuller ? "?" : localeData.longWeekdayNames[wallTime.getWeekDay() + 1], 1603b852e3489e995600fce19dfdbf3a5d769374d74Neil Fuller modifier); 1613b852e3489e995600fce19dfdbf3a5d769374d74Neil Fuller return false; 1623b852e3489e995600fce19dfdbf3a5d769374d74Neil Fuller case 'a': 1633b852e3489e995600fce19dfdbf3a5d769374d74Neil Fuller modifyAndAppend((wallTime.getWeekDay() < 0 1643b852e3489e995600fce19dfdbf3a5d769374d74Neil Fuller || wallTime.getWeekDay() >= DAYSPERWEEK) 1653b852e3489e995600fce19dfdbf3a5d769374d74Neil Fuller ? "?" : localeData.shortWeekdayNames[wallTime.getWeekDay() + 1], 1663b852e3489e995600fce19dfdbf3a5d769374d74Neil Fuller modifier); 1673b852e3489e995600fce19dfdbf3a5d769374d74Neil Fuller return false; 1683b852e3489e995600fce19dfdbf3a5d769374d74Neil Fuller case 'B': 1693b852e3489e995600fce19dfdbf3a5d769374d74Neil Fuller if (modifier == '-') { 1703b852e3489e995600fce19dfdbf3a5d769374d74Neil Fuller modifyAndAppend((wallTime.getMonth() < 0 1713b852e3489e995600fce19dfdbf3a5d769374d74Neil Fuller || wallTime.getMonth() >= MONSPERYEAR) 1723b852e3489e995600fce19dfdbf3a5d769374d74Neil Fuller ? "?" 1733b852e3489e995600fce19dfdbf3a5d769374d74Neil Fuller : localeData.longStandAloneMonthNames[wallTime.getMonth()], 1743b852e3489e995600fce19dfdbf3a5d769374d74Neil Fuller modifier); 1753b852e3489e995600fce19dfdbf3a5d769374d74Neil Fuller } else { 1763b852e3489e995600fce19dfdbf3a5d769374d74Neil Fuller modifyAndAppend((wallTime.getMonth() < 0 1773b852e3489e995600fce19dfdbf3a5d769374d74Neil Fuller || wallTime.getMonth() >= MONSPERYEAR) 1783b852e3489e995600fce19dfdbf3a5d769374d74Neil Fuller ? "?" : localeData.longMonthNames[wallTime.getMonth()], 1793b852e3489e995600fce19dfdbf3a5d769374d74Neil Fuller modifier); 1803b852e3489e995600fce19dfdbf3a5d769374d74Neil Fuller } 1813b852e3489e995600fce19dfdbf3a5d769374d74Neil Fuller return false; 1823b852e3489e995600fce19dfdbf3a5d769374d74Neil Fuller case 'b': 1833b852e3489e995600fce19dfdbf3a5d769374d74Neil Fuller case 'h': 1843b852e3489e995600fce19dfdbf3a5d769374d74Neil Fuller modifyAndAppend((wallTime.getMonth() < 0 || wallTime.getMonth() >= MONSPERYEAR) 1853b852e3489e995600fce19dfdbf3a5d769374d74Neil Fuller ? "?" : localeData.shortMonthNames[wallTime.getMonth()], 1863b852e3489e995600fce19dfdbf3a5d769374d74Neil Fuller modifier); 1873b852e3489e995600fce19dfdbf3a5d769374d74Neil Fuller return false; 1883b852e3489e995600fce19dfdbf3a5d769374d74Neil Fuller case 'C': 1893b852e3489e995600fce19dfdbf3a5d769374d74Neil Fuller outputYear(wallTime.getYear(), true, false, modifier); 1903b852e3489e995600fce19dfdbf3a5d769374d74Neil Fuller return false; 1913b852e3489e995600fce19dfdbf3a5d769374d74Neil Fuller case 'c': 1923b852e3489e995600fce19dfdbf3a5d769374d74Neil Fuller formatInternal(dateTimeFormat, wallTime, zoneInfo); 1933b852e3489e995600fce19dfdbf3a5d769374d74Neil Fuller return false; 1943b852e3489e995600fce19dfdbf3a5d769374d74Neil Fuller case 'D': 1953b852e3489e995600fce19dfdbf3a5d769374d74Neil Fuller formatInternal("%m/%d/%y", wallTime, zoneInfo); 1963b852e3489e995600fce19dfdbf3a5d769374d74Neil Fuller return false; 1973b852e3489e995600fce19dfdbf3a5d769374d74Neil Fuller case 'd': 19816566656cd2f81f62c8693e64de68062f2680161Neil Fuller numberFormatter.format(getFormat(modifier, "%02d", "%2d", "%d", "%02d"), 1993b852e3489e995600fce19dfdbf3a5d769374d74Neil Fuller wallTime.getMonthDay()); 2003b852e3489e995600fce19dfdbf3a5d769374d74Neil Fuller return false; 2013b852e3489e995600fce19dfdbf3a5d769374d74Neil Fuller case 'E': 2023b852e3489e995600fce19dfdbf3a5d769374d74Neil Fuller case 'O': 2033b852e3489e995600fce19dfdbf3a5d769374d74Neil Fuller // C99 locale modifiers are not supported. 2043b852e3489e995600fce19dfdbf3a5d769374d74Neil Fuller continue; 2053b852e3489e995600fce19dfdbf3a5d769374d74Neil Fuller case '_': 2063b852e3489e995600fce19dfdbf3a5d769374d74Neil Fuller case '-': 2073b852e3489e995600fce19dfdbf3a5d769374d74Neil Fuller case '0': 2083b852e3489e995600fce19dfdbf3a5d769374d74Neil Fuller case '^': 2093b852e3489e995600fce19dfdbf3a5d769374d74Neil Fuller case '#': 21016566656cd2f81f62c8693e64de68062f2680161Neil Fuller modifier = currentChar; 2113b852e3489e995600fce19dfdbf3a5d769374d74Neil Fuller continue; 2123b852e3489e995600fce19dfdbf3a5d769374d74Neil Fuller case 'e': 21316566656cd2f81f62c8693e64de68062f2680161Neil Fuller numberFormatter.format(getFormat(modifier, "%2d", "%2d", "%d", "%02d"), 2143b852e3489e995600fce19dfdbf3a5d769374d74Neil Fuller wallTime.getMonthDay()); 2153b852e3489e995600fce19dfdbf3a5d769374d74Neil Fuller return false; 2163b852e3489e995600fce19dfdbf3a5d769374d74Neil Fuller case 'F': 2173b852e3489e995600fce19dfdbf3a5d769374d74Neil Fuller formatInternal("%Y-%m-%d", wallTime, zoneInfo); 2183b852e3489e995600fce19dfdbf3a5d769374d74Neil Fuller return false; 2193b852e3489e995600fce19dfdbf3a5d769374d74Neil Fuller case 'H': 22016566656cd2f81f62c8693e64de68062f2680161Neil Fuller numberFormatter.format(getFormat(modifier, "%02d", "%2d", "%d", "%02d"), 2213b852e3489e995600fce19dfdbf3a5d769374d74Neil Fuller wallTime.getHour()); 2223b852e3489e995600fce19dfdbf3a5d769374d74Neil Fuller return false; 2233b852e3489e995600fce19dfdbf3a5d769374d74Neil Fuller case 'I': 2243b852e3489e995600fce19dfdbf3a5d769374d74Neil Fuller int hour = (wallTime.getHour() % 12 != 0) ? (wallTime.getHour() % 12) : 12; 22516566656cd2f81f62c8693e64de68062f2680161Neil Fuller numberFormatter.format(getFormat(modifier, "%02d", "%2d", "%d", "%02d"), hour); 2263b852e3489e995600fce19dfdbf3a5d769374d74Neil Fuller return false; 2273b852e3489e995600fce19dfdbf3a5d769374d74Neil Fuller case 'j': 2283b852e3489e995600fce19dfdbf3a5d769374d74Neil Fuller int yearDay = wallTime.getYearDay() + 1; 22916566656cd2f81f62c8693e64de68062f2680161Neil Fuller numberFormatter.format(getFormat(modifier, "%03d", "%3d", "%d", "%03d"), 2303b852e3489e995600fce19dfdbf3a5d769374d74Neil Fuller yearDay); 2313b852e3489e995600fce19dfdbf3a5d769374d74Neil Fuller return false; 2323b852e3489e995600fce19dfdbf3a5d769374d74Neil Fuller case 'k': 23316566656cd2f81f62c8693e64de68062f2680161Neil Fuller numberFormatter.format(getFormat(modifier, "%2d", "%2d", "%d", "%02d"), 2343b852e3489e995600fce19dfdbf3a5d769374d74Neil Fuller wallTime.getHour()); 2353b852e3489e995600fce19dfdbf3a5d769374d74Neil Fuller return false; 2363b852e3489e995600fce19dfdbf3a5d769374d74Neil Fuller case 'l': 2373b852e3489e995600fce19dfdbf3a5d769374d74Neil Fuller int n2 = (wallTime.getHour() % 12 != 0) ? (wallTime.getHour() % 12) : 12; 23816566656cd2f81f62c8693e64de68062f2680161Neil Fuller numberFormatter.format(getFormat(modifier, "%2d", "%2d", "%d", "%02d"), n2); 2393b852e3489e995600fce19dfdbf3a5d769374d74Neil Fuller return false; 2403b852e3489e995600fce19dfdbf3a5d769374d74Neil Fuller case 'M': 24116566656cd2f81f62c8693e64de68062f2680161Neil Fuller numberFormatter.format(getFormat(modifier, "%02d", "%2d", "%d", "%02d"), 2423b852e3489e995600fce19dfdbf3a5d769374d74Neil Fuller wallTime.getMinute()); 2433b852e3489e995600fce19dfdbf3a5d769374d74Neil Fuller return false; 2443b852e3489e995600fce19dfdbf3a5d769374d74Neil Fuller case 'm': 24516566656cd2f81f62c8693e64de68062f2680161Neil Fuller numberFormatter.format(getFormat(modifier, "%02d", "%2d", "%d", "%02d"), 2463b852e3489e995600fce19dfdbf3a5d769374d74Neil Fuller wallTime.getMonth() + 1); 2473b852e3489e995600fce19dfdbf3a5d769374d74Neil Fuller return false; 2483b852e3489e995600fce19dfdbf3a5d769374d74Neil Fuller case 'n': 24916566656cd2f81f62c8693e64de68062f2680161Neil Fuller outputBuilder.append('\n'); 2503b852e3489e995600fce19dfdbf3a5d769374d74Neil Fuller return false; 2513b852e3489e995600fce19dfdbf3a5d769374d74Neil Fuller case 'p': 2523b852e3489e995600fce19dfdbf3a5d769374d74Neil Fuller modifyAndAppend((wallTime.getHour() >= (HOURSPERDAY / 2)) ? localeData.amPm[1] 2533b852e3489e995600fce19dfdbf3a5d769374d74Neil Fuller : localeData.amPm[0], modifier); 2543b852e3489e995600fce19dfdbf3a5d769374d74Neil Fuller return false; 2553b852e3489e995600fce19dfdbf3a5d769374d74Neil Fuller case 'P': 2563b852e3489e995600fce19dfdbf3a5d769374d74Neil Fuller modifyAndAppend((wallTime.getHour() >= (HOURSPERDAY / 2)) ? localeData.amPm[1] 2573b852e3489e995600fce19dfdbf3a5d769374d74Neil Fuller : localeData.amPm[0], FORCE_LOWER_CASE); 2583b852e3489e995600fce19dfdbf3a5d769374d74Neil Fuller return false; 2593b852e3489e995600fce19dfdbf3a5d769374d74Neil Fuller case 'R': 2603b852e3489e995600fce19dfdbf3a5d769374d74Neil Fuller formatInternal("%H:%M", wallTime, zoneInfo); 2613b852e3489e995600fce19dfdbf3a5d769374d74Neil Fuller return false; 2623b852e3489e995600fce19dfdbf3a5d769374d74Neil Fuller case 'r': 2633b852e3489e995600fce19dfdbf3a5d769374d74Neil Fuller formatInternal("%I:%M:%S %p", wallTime, zoneInfo); 2643b852e3489e995600fce19dfdbf3a5d769374d74Neil Fuller return false; 2653b852e3489e995600fce19dfdbf3a5d769374d74Neil Fuller case 'S': 26616566656cd2f81f62c8693e64de68062f2680161Neil Fuller numberFormatter.format(getFormat(modifier, "%02d", "%2d", "%d", "%02d"), 2673b852e3489e995600fce19dfdbf3a5d769374d74Neil Fuller wallTime.getSecond()); 2683b852e3489e995600fce19dfdbf3a5d769374d74Neil Fuller return false; 2693b852e3489e995600fce19dfdbf3a5d769374d74Neil Fuller case 's': 2703b852e3489e995600fce19dfdbf3a5d769374d74Neil Fuller int timeInSeconds = wallTime.mktime(zoneInfo); 27116566656cd2f81f62c8693e64de68062f2680161Neil Fuller outputBuilder.append(Integer.toString(timeInSeconds)); 2723b852e3489e995600fce19dfdbf3a5d769374d74Neil Fuller return false; 2733b852e3489e995600fce19dfdbf3a5d769374d74Neil Fuller case 'T': 2743b852e3489e995600fce19dfdbf3a5d769374d74Neil Fuller formatInternal("%H:%M:%S", wallTime, zoneInfo); 2753b852e3489e995600fce19dfdbf3a5d769374d74Neil Fuller return false; 2763b852e3489e995600fce19dfdbf3a5d769374d74Neil Fuller case 't': 27716566656cd2f81f62c8693e64de68062f2680161Neil Fuller outputBuilder.append('\t'); 2783b852e3489e995600fce19dfdbf3a5d769374d74Neil Fuller return false; 2793b852e3489e995600fce19dfdbf3a5d769374d74Neil Fuller case 'U': 28016566656cd2f81f62c8693e64de68062f2680161Neil Fuller numberFormatter.format(getFormat(modifier, "%02d", "%2d", "%d", "%02d"), 2813b852e3489e995600fce19dfdbf3a5d769374d74Neil Fuller (wallTime.getYearDay() + DAYSPERWEEK - wallTime.getWeekDay()) 2823b852e3489e995600fce19dfdbf3a5d769374d74Neil Fuller / DAYSPERWEEK); 2833b852e3489e995600fce19dfdbf3a5d769374d74Neil Fuller return false; 2843b852e3489e995600fce19dfdbf3a5d769374d74Neil Fuller case 'u': 2853b852e3489e995600fce19dfdbf3a5d769374d74Neil Fuller int day = (wallTime.getWeekDay() == 0) ? DAYSPERWEEK : wallTime.getWeekDay(); 28616566656cd2f81f62c8693e64de68062f2680161Neil Fuller numberFormatter.format("%d", day); 2873b852e3489e995600fce19dfdbf3a5d769374d74Neil Fuller return false; 2883b852e3489e995600fce19dfdbf3a5d769374d74Neil Fuller case 'V': /* ISO 8601 week number */ 2893b852e3489e995600fce19dfdbf3a5d769374d74Neil Fuller case 'G': /* ISO 8601 year (four digits) */ 2903b852e3489e995600fce19dfdbf3a5d769374d74Neil Fuller case 'g': /* ISO 8601 year (two digits) */ 2913b852e3489e995600fce19dfdbf3a5d769374d74Neil Fuller { 2923b852e3489e995600fce19dfdbf3a5d769374d74Neil Fuller int year = wallTime.getYear(); 2933b852e3489e995600fce19dfdbf3a5d769374d74Neil Fuller int yday = wallTime.getYearDay(); 2943b852e3489e995600fce19dfdbf3a5d769374d74Neil Fuller int wday = wallTime.getWeekDay(); 2953b852e3489e995600fce19dfdbf3a5d769374d74Neil Fuller int w; 2963b852e3489e995600fce19dfdbf3a5d769374d74Neil Fuller while (true) { 2973b852e3489e995600fce19dfdbf3a5d769374d74Neil Fuller int len = isLeap(year) ? DAYSPERLYEAR : DAYSPERNYEAR; 2983b852e3489e995600fce19dfdbf3a5d769374d74Neil Fuller // What yday (-3 ... 3) does the ISO year begin on? 2993b852e3489e995600fce19dfdbf3a5d769374d74Neil Fuller int bot = ((yday + 11 - wday) % DAYSPERWEEK) - 3; 3003b852e3489e995600fce19dfdbf3a5d769374d74Neil Fuller // What yday does the NEXT ISO year begin on? 3013b852e3489e995600fce19dfdbf3a5d769374d74Neil Fuller int top = bot - (len % DAYSPERWEEK); 3023b852e3489e995600fce19dfdbf3a5d769374d74Neil Fuller if (top < -3) { 3033b852e3489e995600fce19dfdbf3a5d769374d74Neil Fuller top += DAYSPERWEEK; 3043b852e3489e995600fce19dfdbf3a5d769374d74Neil Fuller } 3053b852e3489e995600fce19dfdbf3a5d769374d74Neil Fuller top += len; 3063b852e3489e995600fce19dfdbf3a5d769374d74Neil Fuller if (yday >= top) { 3073b852e3489e995600fce19dfdbf3a5d769374d74Neil Fuller ++year; 3083b852e3489e995600fce19dfdbf3a5d769374d74Neil Fuller w = 1; 3093b852e3489e995600fce19dfdbf3a5d769374d74Neil Fuller break; 3103b852e3489e995600fce19dfdbf3a5d769374d74Neil Fuller } 3113b852e3489e995600fce19dfdbf3a5d769374d74Neil Fuller if (yday >= bot) { 3123b852e3489e995600fce19dfdbf3a5d769374d74Neil Fuller w = 1 + ((yday - bot) / DAYSPERWEEK); 3133b852e3489e995600fce19dfdbf3a5d769374d74Neil Fuller break; 3143b852e3489e995600fce19dfdbf3a5d769374d74Neil Fuller } 3153b852e3489e995600fce19dfdbf3a5d769374d74Neil Fuller --year; 3163b852e3489e995600fce19dfdbf3a5d769374d74Neil Fuller yday += isLeap(year) ? DAYSPERLYEAR : DAYSPERNYEAR; 3173b852e3489e995600fce19dfdbf3a5d769374d74Neil Fuller } 31816566656cd2f81f62c8693e64de68062f2680161Neil Fuller if (currentChar == 'V') { 31916566656cd2f81f62c8693e64de68062f2680161Neil Fuller numberFormatter.format(getFormat(modifier, "%02d", "%2d", "%d", "%02d"), w); 32016566656cd2f81f62c8693e64de68062f2680161Neil Fuller } else if (currentChar == 'g') { 3213b852e3489e995600fce19dfdbf3a5d769374d74Neil Fuller outputYear(year, false, true, modifier); 3223b852e3489e995600fce19dfdbf3a5d769374d74Neil Fuller } else { 3233b852e3489e995600fce19dfdbf3a5d769374d74Neil Fuller outputYear(year, true, true, modifier); 3243b852e3489e995600fce19dfdbf3a5d769374d74Neil Fuller } 3253b852e3489e995600fce19dfdbf3a5d769374d74Neil Fuller return false; 3263b852e3489e995600fce19dfdbf3a5d769374d74Neil Fuller } 3273b852e3489e995600fce19dfdbf3a5d769374d74Neil Fuller case 'v': 3283b852e3489e995600fce19dfdbf3a5d769374d74Neil Fuller formatInternal("%e-%b-%Y", wallTime, zoneInfo); 3293b852e3489e995600fce19dfdbf3a5d769374d74Neil Fuller return false; 3303b852e3489e995600fce19dfdbf3a5d769374d74Neil Fuller case 'W': 3313b852e3489e995600fce19dfdbf3a5d769374d74Neil Fuller int n = (wallTime.getYearDay() + DAYSPERWEEK - ( 3323b852e3489e995600fce19dfdbf3a5d769374d74Neil Fuller wallTime.getWeekDay() != 0 ? (wallTime.getWeekDay() - 1) 3333b852e3489e995600fce19dfdbf3a5d769374d74Neil Fuller : (DAYSPERWEEK - 1))) / DAYSPERWEEK; 33416566656cd2f81f62c8693e64de68062f2680161Neil Fuller numberFormatter.format(getFormat(modifier, "%02d", "%2d", "%d", "%02d"), n); 3353b852e3489e995600fce19dfdbf3a5d769374d74Neil Fuller return false; 3363b852e3489e995600fce19dfdbf3a5d769374d74Neil Fuller case 'w': 33716566656cd2f81f62c8693e64de68062f2680161Neil Fuller numberFormatter.format("%d", wallTime.getWeekDay()); 3383b852e3489e995600fce19dfdbf3a5d769374d74Neil Fuller return false; 3393b852e3489e995600fce19dfdbf3a5d769374d74Neil Fuller case 'X': 3403b852e3489e995600fce19dfdbf3a5d769374d74Neil Fuller formatInternal(timeOnlyFormat, wallTime, zoneInfo); 3413b852e3489e995600fce19dfdbf3a5d769374d74Neil Fuller return false; 3423b852e3489e995600fce19dfdbf3a5d769374d74Neil Fuller case 'x': 3433b852e3489e995600fce19dfdbf3a5d769374d74Neil Fuller formatInternal(dateOnlyFormat, wallTime, zoneInfo); 3443b852e3489e995600fce19dfdbf3a5d769374d74Neil Fuller return false; 3453b852e3489e995600fce19dfdbf3a5d769374d74Neil Fuller case 'y': 3463b852e3489e995600fce19dfdbf3a5d769374d74Neil Fuller outputYear(wallTime.getYear(), false, true, modifier); 3473b852e3489e995600fce19dfdbf3a5d769374d74Neil Fuller return false; 3483b852e3489e995600fce19dfdbf3a5d769374d74Neil Fuller case 'Y': 3493b852e3489e995600fce19dfdbf3a5d769374d74Neil Fuller outputYear(wallTime.getYear(), true, true, modifier); 3503b852e3489e995600fce19dfdbf3a5d769374d74Neil Fuller return false; 3513b852e3489e995600fce19dfdbf3a5d769374d74Neil Fuller case 'Z': 3523b852e3489e995600fce19dfdbf3a5d769374d74Neil Fuller if (wallTime.getIsDst() < 0) { 3533b852e3489e995600fce19dfdbf3a5d769374d74Neil Fuller return false; 3543b852e3489e995600fce19dfdbf3a5d769374d74Neil Fuller } 3553b852e3489e995600fce19dfdbf3a5d769374d74Neil Fuller boolean isDst = wallTime.getIsDst() != 0; 3563b852e3489e995600fce19dfdbf3a5d769374d74Neil Fuller modifyAndAppend(zoneInfo.getDisplayName(isDst, TimeZone.SHORT), modifier); 3573b852e3489e995600fce19dfdbf3a5d769374d74Neil Fuller return false; 3583b852e3489e995600fce19dfdbf3a5d769374d74Neil Fuller case 'z': { 3593b852e3489e995600fce19dfdbf3a5d769374d74Neil Fuller if (wallTime.getIsDst() < 0) { 3603b852e3489e995600fce19dfdbf3a5d769374d74Neil Fuller return false; 3613b852e3489e995600fce19dfdbf3a5d769374d74Neil Fuller } 3623b852e3489e995600fce19dfdbf3a5d769374d74Neil Fuller int diff = wallTime.getGmtOffset(); 36316566656cd2f81f62c8693e64de68062f2680161Neil Fuller char sign; 3643b852e3489e995600fce19dfdbf3a5d769374d74Neil Fuller if (diff < 0) { 36516566656cd2f81f62c8693e64de68062f2680161Neil Fuller sign = '-'; 3663b852e3489e995600fce19dfdbf3a5d769374d74Neil Fuller diff = -diff; 3673b852e3489e995600fce19dfdbf3a5d769374d74Neil Fuller } else { 36816566656cd2f81f62c8693e64de68062f2680161Neil Fuller sign = '+'; 3693b852e3489e995600fce19dfdbf3a5d769374d74Neil Fuller } 37016566656cd2f81f62c8693e64de68062f2680161Neil Fuller outputBuilder.append(sign); 3713b852e3489e995600fce19dfdbf3a5d769374d74Neil Fuller diff /= SECSPERMIN; 3723b852e3489e995600fce19dfdbf3a5d769374d74Neil Fuller diff = (diff / MINSPERHOUR) * 100 + (diff % MINSPERHOUR); 37316566656cd2f81f62c8693e64de68062f2680161Neil Fuller numberFormatter.format(getFormat(modifier, "%04d", "%4d", "%d", "%04d"), diff); 3743b852e3489e995600fce19dfdbf3a5d769374d74Neil Fuller return false; 3753b852e3489e995600fce19dfdbf3a5d769374d74Neil Fuller } 3763b852e3489e995600fce19dfdbf3a5d769374d74Neil Fuller case '+': 3773b852e3489e995600fce19dfdbf3a5d769374d74Neil Fuller formatInternal("%a %b %e %H:%M:%S %Z %Y", wallTime, zoneInfo); 3783b852e3489e995600fce19dfdbf3a5d769374d74Neil Fuller return false; 3793b852e3489e995600fce19dfdbf3a5d769374d74Neil Fuller case '%': 3803b852e3489e995600fce19dfdbf3a5d769374d74Neil Fuller // If conversion char is undefined, behavior is undefined. Print out the 3813b852e3489e995600fce19dfdbf3a5d769374d74Neil Fuller // character itself. 3823b852e3489e995600fce19dfdbf3a5d769374d74Neil Fuller default: 3833b852e3489e995600fce19dfdbf3a5d769374d74Neil Fuller return true; 3843b852e3489e995600fce19dfdbf3a5d769374d74Neil Fuller } 3853b852e3489e995600fce19dfdbf3a5d769374d74Neil Fuller } 3863b852e3489e995600fce19dfdbf3a5d769374d74Neil Fuller return true; 3873b852e3489e995600fce19dfdbf3a5d769374d74Neil Fuller } 3883b852e3489e995600fce19dfdbf3a5d769374d74Neil Fuller 3893b852e3489e995600fce19dfdbf3a5d769374d74Neil Fuller private void modifyAndAppend(CharSequence str, int modifier) { 3903b852e3489e995600fce19dfdbf3a5d769374d74Neil Fuller switch (modifier) { 3913b852e3489e995600fce19dfdbf3a5d769374d74Neil Fuller case FORCE_LOWER_CASE: 3923b852e3489e995600fce19dfdbf3a5d769374d74Neil Fuller for (int i = 0; i < str.length(); i++) { 3933b852e3489e995600fce19dfdbf3a5d769374d74Neil Fuller outputBuilder.append(brokenToLower(str.charAt(i))); 3943b852e3489e995600fce19dfdbf3a5d769374d74Neil Fuller } 3953b852e3489e995600fce19dfdbf3a5d769374d74Neil Fuller break; 3963b852e3489e995600fce19dfdbf3a5d769374d74Neil Fuller case '^': 3973b852e3489e995600fce19dfdbf3a5d769374d74Neil Fuller for (int i = 0; i < str.length(); i++) { 3983b852e3489e995600fce19dfdbf3a5d769374d74Neil Fuller outputBuilder.append(brokenToUpper(str.charAt(i))); 3993b852e3489e995600fce19dfdbf3a5d769374d74Neil Fuller } 4003b852e3489e995600fce19dfdbf3a5d769374d74Neil Fuller break; 4013b852e3489e995600fce19dfdbf3a5d769374d74Neil Fuller case '#': 4023b852e3489e995600fce19dfdbf3a5d769374d74Neil Fuller for (int i = 0; i < str.length(); i++) { 4033b852e3489e995600fce19dfdbf3a5d769374d74Neil Fuller char c = str.charAt(i); 4043b852e3489e995600fce19dfdbf3a5d769374d74Neil Fuller if (brokenIsUpper(c)) { 4053b852e3489e995600fce19dfdbf3a5d769374d74Neil Fuller c = brokenToLower(c); 4063b852e3489e995600fce19dfdbf3a5d769374d74Neil Fuller } else if (brokenIsLower(c)) { 4073b852e3489e995600fce19dfdbf3a5d769374d74Neil Fuller c = brokenToUpper(c); 4083b852e3489e995600fce19dfdbf3a5d769374d74Neil Fuller } 4093b852e3489e995600fce19dfdbf3a5d769374d74Neil Fuller outputBuilder.append(c); 4103b852e3489e995600fce19dfdbf3a5d769374d74Neil Fuller } 4113b852e3489e995600fce19dfdbf3a5d769374d74Neil Fuller break; 4123b852e3489e995600fce19dfdbf3a5d769374d74Neil Fuller default: 4133b852e3489e995600fce19dfdbf3a5d769374d74Neil Fuller outputBuilder.append(str); 4143b852e3489e995600fce19dfdbf3a5d769374d74Neil Fuller } 4153b852e3489e995600fce19dfdbf3a5d769374d74Neil Fuller } 4163b852e3489e995600fce19dfdbf3a5d769374d74Neil Fuller 4173b852e3489e995600fce19dfdbf3a5d769374d74Neil Fuller private void outputYear(int value, boolean outputTop, boolean outputBottom, int modifier) { 4183b852e3489e995600fce19dfdbf3a5d769374d74Neil Fuller int lead; 4193b852e3489e995600fce19dfdbf3a5d769374d74Neil Fuller int trail; 4203b852e3489e995600fce19dfdbf3a5d769374d74Neil Fuller 4213b852e3489e995600fce19dfdbf3a5d769374d74Neil Fuller final int DIVISOR = 100; 4223b852e3489e995600fce19dfdbf3a5d769374d74Neil Fuller trail = value % DIVISOR; 4233b852e3489e995600fce19dfdbf3a5d769374d74Neil Fuller lead = value / DIVISOR + trail / DIVISOR; 4243b852e3489e995600fce19dfdbf3a5d769374d74Neil Fuller trail %= DIVISOR; 4253b852e3489e995600fce19dfdbf3a5d769374d74Neil Fuller if (trail < 0 && lead > 0) { 4263b852e3489e995600fce19dfdbf3a5d769374d74Neil Fuller trail += DIVISOR; 4273b852e3489e995600fce19dfdbf3a5d769374d74Neil Fuller --lead; 4283b852e3489e995600fce19dfdbf3a5d769374d74Neil Fuller } else if (lead < 0 && trail > 0) { 4293b852e3489e995600fce19dfdbf3a5d769374d74Neil Fuller trail -= DIVISOR; 4303b852e3489e995600fce19dfdbf3a5d769374d74Neil Fuller ++lead; 4313b852e3489e995600fce19dfdbf3a5d769374d74Neil Fuller } 4323b852e3489e995600fce19dfdbf3a5d769374d74Neil Fuller if (outputTop) { 4333b852e3489e995600fce19dfdbf3a5d769374d74Neil Fuller if (lead == 0 && trail < 0) { 43416566656cd2f81f62c8693e64de68062f2680161Neil Fuller outputBuilder.append("-0"); 4353b852e3489e995600fce19dfdbf3a5d769374d74Neil Fuller } else { 43616566656cd2f81f62c8693e64de68062f2680161Neil Fuller numberFormatter.format(getFormat(modifier, "%02d", "%2d", "%d", "%02d"), lead); 4373b852e3489e995600fce19dfdbf3a5d769374d74Neil Fuller } 4383b852e3489e995600fce19dfdbf3a5d769374d74Neil Fuller } 4393b852e3489e995600fce19dfdbf3a5d769374d74Neil Fuller if (outputBottom) { 4403b852e3489e995600fce19dfdbf3a5d769374d74Neil Fuller int n = ((trail < 0) ? -trail : trail); 44116566656cd2f81f62c8693e64de68062f2680161Neil Fuller numberFormatter.format(getFormat(modifier, "%02d", "%2d", "%d", "%02d"), n); 4423b852e3489e995600fce19dfdbf3a5d769374d74Neil Fuller } 4433b852e3489e995600fce19dfdbf3a5d769374d74Neil Fuller } 4443b852e3489e995600fce19dfdbf3a5d769374d74Neil Fuller 4453b852e3489e995600fce19dfdbf3a5d769374d74Neil Fuller private static String getFormat(int modifier, String normal, String underscore, String dash, 4463b852e3489e995600fce19dfdbf3a5d769374d74Neil Fuller String zero) { 4473b852e3489e995600fce19dfdbf3a5d769374d74Neil Fuller switch (modifier) { 4483b852e3489e995600fce19dfdbf3a5d769374d74Neil Fuller case '_': 4493b852e3489e995600fce19dfdbf3a5d769374d74Neil Fuller return underscore; 4503b852e3489e995600fce19dfdbf3a5d769374d74Neil Fuller case '-': 4513b852e3489e995600fce19dfdbf3a5d769374d74Neil Fuller return dash; 4523b852e3489e995600fce19dfdbf3a5d769374d74Neil Fuller case '0': 4533b852e3489e995600fce19dfdbf3a5d769374d74Neil Fuller return zero; 4543b852e3489e995600fce19dfdbf3a5d769374d74Neil Fuller } 4553b852e3489e995600fce19dfdbf3a5d769374d74Neil Fuller return normal; 4563b852e3489e995600fce19dfdbf3a5d769374d74Neil Fuller } 4573b852e3489e995600fce19dfdbf3a5d769374d74Neil Fuller 4583b852e3489e995600fce19dfdbf3a5d769374d74Neil Fuller private static boolean isLeap(int year) { 4593b852e3489e995600fce19dfdbf3a5d769374d74Neil Fuller return (((year) % 4) == 0 && (((year) % 100) != 0 || ((year) % 400) == 0)); 4603b852e3489e995600fce19dfdbf3a5d769374d74Neil Fuller } 4613b852e3489e995600fce19dfdbf3a5d769374d74Neil Fuller 4623b852e3489e995600fce19dfdbf3a5d769374d74Neil Fuller /** 46316566656cd2f81f62c8693e64de68062f2680161Neil Fuller * A broken implementation of {@link Character#isUpperCase(char)} that assumes ASCII codes in 46416566656cd2f81f62c8693e64de68062f2680161Neil Fuller * order to be compatible with the old native implementation. 4653b852e3489e995600fce19dfdbf3a5d769374d74Neil Fuller */ 4663b852e3489e995600fce19dfdbf3a5d769374d74Neil Fuller private static boolean brokenIsUpper(char toCheck) { 4673b852e3489e995600fce19dfdbf3a5d769374d74Neil Fuller return toCheck >= 'A' && toCheck <= 'Z'; 4683b852e3489e995600fce19dfdbf3a5d769374d74Neil Fuller } 4693b852e3489e995600fce19dfdbf3a5d769374d74Neil Fuller 4703b852e3489e995600fce19dfdbf3a5d769374d74Neil Fuller /** 47116566656cd2f81f62c8693e64de68062f2680161Neil Fuller * A broken implementation of {@link Character#isLowerCase(char)} that assumes ASCII codes in 47216566656cd2f81f62c8693e64de68062f2680161Neil Fuller * order to be compatible with the old native implementation. 4733b852e3489e995600fce19dfdbf3a5d769374d74Neil Fuller */ 4743b852e3489e995600fce19dfdbf3a5d769374d74Neil Fuller private static boolean brokenIsLower(char toCheck) { 4753b852e3489e995600fce19dfdbf3a5d769374d74Neil Fuller return toCheck >= 'a' && toCheck <= 'z'; 4763b852e3489e995600fce19dfdbf3a5d769374d74Neil Fuller } 4773b852e3489e995600fce19dfdbf3a5d769374d74Neil Fuller 4783b852e3489e995600fce19dfdbf3a5d769374d74Neil Fuller /** 47916566656cd2f81f62c8693e64de68062f2680161Neil Fuller * A broken implementation of {@link Character#toLowerCase(char)} that assumes ASCII codes in 48016566656cd2f81f62c8693e64de68062f2680161Neil Fuller * order to be compatible with the old native implementation. 4813b852e3489e995600fce19dfdbf3a5d769374d74Neil Fuller */ 4823b852e3489e995600fce19dfdbf3a5d769374d74Neil Fuller private static char brokenToLower(char input) { 4833b852e3489e995600fce19dfdbf3a5d769374d74Neil Fuller if (input >= 'A' && input <= 'Z') { 4843b852e3489e995600fce19dfdbf3a5d769374d74Neil Fuller return (char) (input - 'A' + 'a'); 4853b852e3489e995600fce19dfdbf3a5d769374d74Neil Fuller } 4863b852e3489e995600fce19dfdbf3a5d769374d74Neil Fuller return input; 4873b852e3489e995600fce19dfdbf3a5d769374d74Neil Fuller } 4883b852e3489e995600fce19dfdbf3a5d769374d74Neil Fuller 4893b852e3489e995600fce19dfdbf3a5d769374d74Neil Fuller /** 49016566656cd2f81f62c8693e64de68062f2680161Neil Fuller * A broken implementation of {@link Character#toUpperCase(char)} that assumes ASCII codes in 49116566656cd2f81f62c8693e64de68062f2680161Neil Fuller * order to be compatible with the old native implementation. 4923b852e3489e995600fce19dfdbf3a5d769374d74Neil Fuller */ 4933b852e3489e995600fce19dfdbf3a5d769374d74Neil Fuller private static char brokenToUpper(char input) { 4943b852e3489e995600fce19dfdbf3a5d769374d74Neil Fuller if (input >= 'a' && input <= 'z') { 4953b852e3489e995600fce19dfdbf3a5d769374d74Neil Fuller return (char) (input - 'a' + 'A'); 4963b852e3489e995600fce19dfdbf3a5d769374d74Neil Fuller } 4973b852e3489e995600fce19dfdbf3a5d769374d74Neil Fuller return input; 4983b852e3489e995600fce19dfdbf3a5d769374d74Neil Fuller } 4993b852e3489e995600fce19dfdbf3a5d769374d74Neil Fuller 5003b852e3489e995600fce19dfdbf3a5d769374d74Neil Fuller} 501