12ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller/* GENERATED SOURCE. DO NOT MODIFY. */ 2f86f25d102340da66b9c7cb6b2d5ecdc0de43ecfFredrik Roubert// © 2016 and later: Unicode, Inc. and others. 3f86f25d102340da66b9c7cb6b2d5ecdc0de43ecfFredrik Roubert// License & terms of use: http://www.unicode.org/copyright.html#License 42ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller/* 51c8a530973739aafa823d758240d2cd5dad96fe3Fredrik Roubert* Copyright (C) 2008-2016, International Business Machines 62ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller* Corporation and others. All Rights Reserved. 72ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller*/ 82ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller 92ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fullerpackage android.icu.text; 102ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller 112ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fullerimport java.io.IOException; 122ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fullerimport java.io.ObjectInputStream; 132ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fullerimport java.text.FieldPosition; 142ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fullerimport java.text.ParsePosition; 152ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fullerimport java.util.Collections; 162ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fullerimport java.util.HashMap; 172ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fullerimport java.util.Locale; 182ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fullerimport java.util.Map; 192ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller 202ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fullerimport android.icu.impl.ICUCache; 21f86f25d102340da66b9c7cb6b2d5ecdc0de43ecfFredrik Roubertimport android.icu.impl.ICUData; 22f86f25d102340da66b9c7cb6b2d5ecdc0de43ecfFredrik Roubertimport android.icu.impl.ICUResourceBundle; 232ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fullerimport android.icu.impl.SimpleCache; 241c8a530973739aafa823d758240d2cd5dad96fe3Fredrik Roubertimport android.icu.impl.SimpleFormatterImpl; 252ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fullerimport android.icu.text.DateIntervalInfo.PatternInfo; 262ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fullerimport android.icu.util.Calendar; 272ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fullerimport android.icu.util.DateInterval; 282ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fullerimport android.icu.util.Output; 292ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fullerimport android.icu.util.TimeZone; 302ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fullerimport android.icu.util.ULocale; 312ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fullerimport android.icu.util.ULocale.Category; 32f86f25d102340da66b9c7cb6b2d5ecdc0de43ecfFredrik Roubertimport android.icu.util.UResourceBundle; 332ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller 342ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller 352ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller/** 362ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * DateIntervalFormat is a class for formatting and parsing date 372ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * intervals in a language-independent manner. 382ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * Only formatting is supported. Parsing is not supported. 392ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * 402ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * <P> 412ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * Date interval means from one date to another date, 422ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * for example, from "Jan 11, 2008" to "Jan 18, 2008". 432ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * We introduced class DateInterval to represent it. 442ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * DateInterval is a pair of UDate, which is 452ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * the standard milliseconds since 24:00 GMT, Jan 1, 1970. 462ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * 472ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * <P> 482ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * DateIntervalFormat formats a DateInterval into 492ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * text as compactly as possible. 502ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * For example, the date interval format from "Jan 11, 2008" to "Jan 18,. 2008" 512ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * is "Jan 11-18, 2008" for English. 522ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * And it parses text into DateInterval, 532ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * although initially, parsing is not supported. 542ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * 552ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * <P> 562ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * There is no structural information in date time patterns. 572ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * For any punctuations and string literals inside a date time pattern, 582ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * we do not know whether it is just a separator, or a prefix, or a suffix. 592ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * Without such information, so, it is difficult to generate a sub-pattern 602ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * (or super-pattern) by algorithm. 612ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * So, formatting a DateInterval is pattern-driven. It is very 622ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * similar to formatting in SimpleDateFormat. 632ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * We introduce class DateIntervalInfo to save date interval 642ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * patterns, similar to date time pattern in SimpleDateFormat. 652ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * 662ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * <P> 672ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * Logically, the interval patterns are mappings 682ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * from (skeleton, the_largest_different_calendar_field) 692ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * to (date_interval_pattern). 702ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * 712ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * <P> 722ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * A skeleton 732ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * <ol> 742ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * <li> 752ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * only keeps the field pattern letter and ignores all other parts 762ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * in a pattern, such as space, punctuations, and string literals. 772ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * <li> 782ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * hides the order of fields. 792ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * <li> 802ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * might hide a field's pattern letter length. 812ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * 822ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * For those non-digit calendar fields, the pattern letter length is 832ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * important, such as MMM, MMMM, and MMMMM; EEE and EEEE, 842ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * and the field's pattern letter length is honored. 852ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * 862ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * For the digit calendar fields, such as M or MM, d or dd, yy or yyyy, 872ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * the field pattern length is ignored and the best match, which is defined 882ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * in date time patterns, will be returned without honor the field pattern 892ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * letter length in skeleton. 902ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * </ol> 912ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * 922ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * <P> 932ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * The calendar fields we support for interval formatting are: 942ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * year, month, date, day-of-week, am-pm, hour, hour-of-day, minute, and 952ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * second (though we do not currently have specific intervalFormat data for 962ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * skeletons with seconds). 972ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * Those calendar fields can be defined in the following order: 9808ae9f2909b2ec37f755dac4372553437e9d7cf6Paul Duffin * year > month > date > hour (in day) > minute > second 992ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * 1002ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * The largest different calendar fields between 2 calendars is the 1012ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * first different calendar field in above order. 1022ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * 1032ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * For example: the largest different calendar fields between "Jan 10, 2007" 1042ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * and "Feb 20, 2008" is year. 1052ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * 1062ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * <P> 1072ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * For other calendar fields, the compact interval formatting is not 1082ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * supported. And the interval format will be fall back to fall-back 1092ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * patterns, which is mostly "{date0} - {date1}". 1102ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * 1112ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * <P> 1122ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * There is a set of pre-defined static skeleton strings in DateFormat, 1132ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * There are pre-defined interval patterns for those pre-defined skeletons 1142ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * in locales' resource files. 1152ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * For example, for a skeleton YEAR_ABBR_MONTH_DAY, which is "yMMMd", 1162ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * in en_US, if the largest different calendar field between date1 and date2 1172ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * is "year", the date interval pattern is "MMM d, yyyy - MMM d, yyyy", 1182ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * such as "Jan 10, 2007 - Jan 10, 2008". 1192ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * If the largest different calendar field between date1 and date2 is "month", 1202ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * the date interval pattern is "MMM d - MMM d, yyyy", 1212ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * such as "Jan 10 - Feb 10, 2007". 1222ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * If the largest different calendar field between date1 and date2 is "day", 1232ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * the date interval pattern is ""MMM d-d, yyyy", such as "Jan 10-20, 2007". 1242ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * 1252ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * For date skeleton, the interval patterns when year, or month, or date is 1262ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * different are defined in resource files. 1272ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * For time skeleton, the interval patterns when am/pm, or hour, or minute is 1282ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * different are defined in resource files. 1292ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * 1302ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * <P> 1312ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * If a skeleton is not found in a locale's DateIntervalInfo, which means 1322ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * the interval patterns for the skeleton is not defined in resource file, 1332ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * the interval pattern will falls back to the interval "fallback" pattern 1342ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * defined in resource file. 1352ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * If the interval "fallback" pattern is not defined, the default fall-back 1362ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * is "{date0} - {data1}". 1372ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * 1382ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * <P> 1392ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * For the combination of date and time, 1402ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * The rule to genearte interval patterns are: 1412ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * <ol> 1422ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * <li> 1432ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * when the year, month, or day differs, falls back to fall-back 1442ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * interval pattern, which mostly is the concatenate the two original 1452ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * expressions with a separator between, 1462ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * For example, interval pattern from "Jan 10, 2007 10:10 am" 1472ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * to "Jan 11, 2007 10:10am" is 1482ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * "Jan 10, 2007 10:10 am - Jan 11, 2007 10:10am" 1492ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * <li> 1502ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * otherwise, present the date followed by the range expression 1512ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * for the time. 1522ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * For example, interval pattern from "Jan 10, 2007 10:10 am" 1532ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * to "Jan 10, 2007 11:10am" is "Jan 10, 2007 10:10 am - 11:10am" 1542ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * </ol> 1552ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * 1562ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * 1572ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * <P> 1582ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * If two dates are the same, the interval pattern is the single date pattern. 1592ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * For example, interval pattern from "Jan 10, 2007" to "Jan 10, 2007" is 1602ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * "Jan 10, 2007". 1612ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * 1622ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * Or if the presenting fields between 2 dates have the exact same values, 1632ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * the interval pattern is the single date pattern. 1642ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * For example, if user only requests year and month, 1652ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * the interval pattern from "Jan 10, 2007" to "Jan 20, 2007" is "Jan 2007". 1662ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * 1672ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * <P> 1682ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * DateIntervalFormat needs the following information for correct 1692ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * formatting: time zone, calendar type, pattern, date format symbols, 1702ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * and date interval patterns. 1712ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * It can be instantiated in several ways: 1722ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * <ol> 1732ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * <li> 1742ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * create an instance using default or given locale plus given skeleton. 1752ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * Users are encouraged to created date interval formatter this way and 1762ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * to use the pre-defined skeleton macros, such as 1772ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * YEAR_NUM_MONTH, which consists the calendar fields and 1782ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * the format style. 1792ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * </li> 1802ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * <li> 1812ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * create an instance using default or given locale plus given skeleton 1822ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * plus a given DateIntervalInfo. 1832ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * This factory method is for powerful users who want to provide their own 1842ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * interval patterns. 1852ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * Locale provides the timezone, calendar, and format symbols information. 1862ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * Local plus skeleton provides full pattern information. 1872ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * DateIntervalInfo provides the date interval patterns. 1882ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * </li> 1892ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * </ol> 1902ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * 1912ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * <P> 1922ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * For the calendar field pattern letter, such as G, y, M, d, a, h, H, m, s etc. 1932ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * DateIntervalFormat uses the same syntax as that of 1942ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * DateTime format. 1952ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * 1962ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * <P> 1972ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * Code Sample: general usage 1982ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * <pre> 1992ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * 2002ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * // the date interval object which the DateIntervalFormat formats on 2012ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * // and parses into 2022ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * DateInterval dtInterval = new DateInterval(1000*3600*24L, 1000*3600*24*2L); 2032ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * DateIntervalFormat dtIntervalFmt = DateIntervalFormat.getInstance( 2042ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * YEAR_MONTH_DAY, Locale("en", "GB", "")); 2052ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * StringBuffer str = new StringBuffer(""); 2062ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * FieldPosition pos = new FieldPosition(0); 2072ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * // formatting 2082ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * dtIntervalFmt.format(dtInterval, dateIntervalString, pos); 2092ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * 2102ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * </pre> 2112ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * 2122ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * <P> 2132ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * Code Sample: for powerful users who wants to use their own interval pattern 2142ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * <pre> 2152ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * 2161fba789ac68efdd9120a7373f49daef42833e674Neil Fuller * import android.icu.text.DateIntervalInfo; 2171fba789ac68efdd9120a7373f49daef42833e674Neil Fuller * import android.icu.text.DateIntervalFormat; 2182ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * .................... 2192ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * 2202ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * // Get DateIntervalFormat instance using default locale 2212ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * DateIntervalFormat dtitvfmt = DateIntervalFormat.getInstance(YEAR_MONTH_DAY); 2222ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * 2232ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * // Create an empty DateIntervalInfo object, which does not have any interval patterns inside. 2242ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * dtitvinf = new DateIntervalInfo(); 2252ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * 2262ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * // a series of set interval patterns. 2272ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * // Only ERA, YEAR, MONTH, DATE, DAY_OF_MONTH, DAY_OF_WEEK, AM_PM, HOUR, HOUR_OF_DAY, 2282ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * MINUTE and SECOND are supported. 2292ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * dtitvinf.setIntervalPattern("yMMMd", Calendar.YEAR, "'y ~ y'"); 2302ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * dtitvinf.setIntervalPattern("yMMMd", Calendar.MONTH, "yyyy 'diff' MMM d - MMM d"); 2312ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * dtitvinf.setIntervalPattern("yMMMd", Calendar.DATE, "yyyy MMM d ~ d"); 2322ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * dtitvinf.setIntervalPattern("yMMMd", Calendar.HOUR_OF_DAY, "yyyy MMM d HH:mm ~ HH:mm"); 2332ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * 2342ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * // Set fallback interval pattern. Fallback pattern is used when interval pattern is not found. 2352ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * // If the fall-back pattern is not set, falls back to {date0} - {date1} if interval pattern is not found. 2362ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * dtitvinf.setFallbackIntervalPattern("{0} - {1}"); 2372ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * 2382ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * // Set above DateIntervalInfo object as the interval patterns of date interval formatter 2392ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * dtitvfmt.setDateIntervalInfo(dtitvinf); 2402ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * 2412ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * // Prepare to format 2422ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * pos = new FieldPosition(0); 2432ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * str = new StringBuffer(""); 2442ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * 2452ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * // The 2 calendars should be equivalent, otherwise, IllegalArgumentException will be thrown by format() 2462ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * Calendar fromCalendar = (Calendar) dtfmt.getCalendar().clone(); 2472ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * Calendar toCalendar = (Calendar) dtfmt.getCalendar().clone(); 2482ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * fromCalendar.setTimeInMillis(....); 2492ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * toCalendar.setTimeInMillis(...); 2502ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * 2512ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * //Formatting given 2 calendars 2522ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * dtitvfmt.format(fromCalendar, toCalendar, str, pos); 2532ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * 2542ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * 2552ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * </pre> 2561c8a530973739aafa823d758240d2cd5dad96fe3Fredrik Roubert * <h3>Synchronization</h3> 2571c8a530973739aafa823d758240d2cd5dad96fe3Fredrik Roubert * 2581c8a530973739aafa823d758240d2cd5dad96fe3Fredrik Roubert * The format methods of DateIntervalFormat may be used concurrently from multiple threads. 2591c8a530973739aafa823d758240d2cd5dad96fe3Fredrik Roubert * Functions that alter the state of a DateIntervalFormat object (setters) 2601c8a530973739aafa823d758240d2cd5dad96fe3Fredrik Roubert * may not be used concurrently with any other functions. 2612ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller */ 2622ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller 2632ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fullerpublic class DateIntervalFormat extends UFormat { 2642ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller 2652ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller private static final long serialVersionUID = 1; 2662ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller 2672ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller /** 2682ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * Used to save the information for a skeleton's best match skeleton. 2692ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * It is package accessible since it is used in DateIntervalInfo too. 2702ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller */ 2712ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller static final class BestMatchInfo { 2722ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller // the best match skeleton 2732ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller final String bestMatchSkeleton; 2742ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller // 0 means the best matched skeleton is the same as input skeleton 2752ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller // 1 means the fields are the same, but field width are different 2762ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller // 2 means the only difference between fields are v/z, 2772ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller // -1 means there are other fields difference 2782ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller final int bestMatchDistanceInfo; 2792ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller BestMatchInfo(String bestSkeleton, int difference) { 2802ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller bestMatchSkeleton = bestSkeleton; 2812ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller bestMatchDistanceInfo = difference; 2822ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } 2832ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } 2842ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller 2852ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller 2862ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller /* 2872ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * Used to save the information on a skeleton and its best match. 2882ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller */ 2892ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller private static final class SkeletonAndItsBestMatch { 2902ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller final String skeleton; 2912ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller final String bestMatchSkeleton; 2922ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller SkeletonAndItsBestMatch(String skeleton, String bestMatch) { 2932ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller this.skeleton = skeleton; 2942ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller bestMatchSkeleton = bestMatch; 2952ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } 2962ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } 2972ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller 2982ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller 2992ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller // Cache for the locale interval pattern 3002ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller private static ICUCache<String, Map<String, PatternInfo>> LOCAL_PATTERN_CACHE = 3012ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller new SimpleCache<String, Map<String, PatternInfo>>(); 3022ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller 3032ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller /* 3042ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * The interval patterns for this locale. 3052ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller */ 3062ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller private DateIntervalInfo fInfo; 3072ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller 3082ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller /* 3091c8a530973739aafa823d758240d2cd5dad96fe3Fredrik Roubert * The DateFormat object used to format single pattern. 3101c8a530973739aafa823d758240d2cd5dad96fe3Fredrik Roubert * Because fDateFormat is modified during format operations, all 3111c8a530973739aafa823d758240d2cd5dad96fe3Fredrik Roubert * access to it from logically const, thread safe functions must be synchronized. 3122ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller */ 3132ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller private SimpleDateFormat fDateFormat; 3142ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller 3152ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller /* 3162ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * The 2 calendars with the from and to date. 3172ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * could re-use the calendar in fDateFormat, 3182ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * but keeping 2 calendars make it clear and clean. 3191c8a530973739aafa823d758240d2cd5dad96fe3Fredrik Roubert * Because these Calendars are modified during format operations, all 3201c8a530973739aafa823d758240d2cd5dad96fe3Fredrik Roubert * access to them from logically const, thread safe functions must be synchronized. 3212ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller */ 3222ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller private Calendar fFromCalendar; 3232ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller private Calendar fToCalendar; 3242ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller 3252ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller /* 3262ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * Following are transient interval information 3272ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * relevant (locale) to this formatter. 3282ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller */ 3292ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller private String fSkeleton = null; 3302ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller 3312ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller /* 3322ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * Needed for efficient deserialization. If set, it means we can use the 3332ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * cache to initialize fIntervalPatterns. 3342ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller */ 3352ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller private boolean isDateIntervalInfoDefault; 3362ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller 3372ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller /** 3382ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * Interval patterns for this instance's locale. 3392ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller */ 3402ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller private transient Map<String, PatternInfo> fIntervalPatterns = null; 3412ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller 3422ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller /* 3432ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * Patterns for fallback formatting. 3442ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller */ 3452ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller private String fDatePattern = null; 3462ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller private String fTimePattern = null; 3472ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller private String fDateTimeFormat = null; 3482ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller 3492ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller 3502ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller /* 3512ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * default constructor; private because we don't want anyone to use 3522ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller */ 3532ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller @SuppressWarnings("unused") 3542ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller private DateIntervalFormat() { 3552ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } 3562ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller 3572ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller /** 3582ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * Construct a DateIntervalFormat from DateFormat, 3592ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * a DateIntervalInfo, and skeleton. 3602ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * DateFormat provides the timezone, calendar, 3612ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * full pattern, and date format symbols information. 3622ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * It should be a SimpleDateFormat object which 3632ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * has a pattern in it. 3642ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * the DateIntervalInfo provides the interval patterns. 3652ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * 3662ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * @param skeleton the skeleton of the date formatter 3672ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * @param dtItvInfo the DateIntervalInfo object to be adopted. 3682ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * @param simpleDateFormat will be used for formatting 3692ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * 3702ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * @deprecated This API is ICU internal only. 37193cf604e9dd0525f15bc0a7450b2a35f3884c298Neil Fuller * @hide original deprecated declaration 372836e6b40a94ec3fb7545a76cb072960442b7eee9Neil Fuller * @hide draft / provisional / internal are hidden on Android 3732ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller */ 3742ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller @Deprecated 3752ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller public DateIntervalFormat(String skeleton, DateIntervalInfo dtItvInfo, 3762ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller SimpleDateFormat simpleDateFormat) 3772ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller { 3782ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller fDateFormat = simpleDateFormat; 3792ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller // freeze date interval info 3802ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller dtItvInfo.freeze(); 3812ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller fSkeleton = skeleton; 3822ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller fInfo = dtItvInfo; 3832ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller isDateIntervalInfoDefault = false; 3842ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller fFromCalendar = (Calendar) fDateFormat.getCalendar().clone(); 3852ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller fToCalendar = (Calendar) fDateFormat.getCalendar().clone(); 3862ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller initializePattern(null); 3872ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } 3882ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller 3892ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller private DateIntervalFormat(String skeleton, ULocale locale, 3902ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller SimpleDateFormat simpleDateFormat) 3912ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller { 3922ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller fDateFormat = simpleDateFormat; 3932ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller fSkeleton = skeleton; 3942ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller fInfo = new DateIntervalInfo(locale).freeze(); 3952ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller isDateIntervalInfoDefault = true; 3962ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller fFromCalendar = (Calendar) fDateFormat.getCalendar().clone(); 3972ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller fToCalendar = (Calendar) fDateFormat.getCalendar().clone(); 3982ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller initializePattern(LOCAL_PATTERN_CACHE); 3992ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller} 4002ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller 4012ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller 4022ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller /** 4032ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * Construct a DateIntervalFormat from skeleton and the default <code>FORMAT</code> locale. 4042ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * 4052ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * This is a convenient override of 4062ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * getInstance(String skeleton, ULocale locale) 4072ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * with the value of locale as default <code>FORMAT</code> locale. 4082ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * 4092ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * @param skeleton the skeleton on which interval format based. 4102ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * @return a date time interval formatter. 4112ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * @see Category#FORMAT 4122ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller */ 4132ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller public static final DateIntervalFormat 4142ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller getInstance(String skeleton) 4152ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller 4162ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller { 4172ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller return getInstance(skeleton, ULocale.getDefault(Category.FORMAT)); 4182ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } 4192ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller 4202ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller 4212ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller /** 4222ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * Construct a DateIntervalFormat from skeleton and a given locale. 4232ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * 4242ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * This is a convenient override of 4252ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * getInstance(String skeleton, ULocale locale) 4262ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * 427cc49f813b0d7bf6664102b30b5513fd21c362e0dNeil Fuller * <p>Example code:{@sample external/icu/android_icu4j/src/samples/java/android/icu/samples/text/dateintervalformat/DateIntervalFormatSample.java dtitvfmtPreDefinedExample} 4282ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * @param skeleton the skeleton on which interval format based. 4292ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * @param locale the given locale 4302ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * @return a date time interval formatter. 4312ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller */ 4322ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller public static final DateIntervalFormat 4332ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller getInstance(String skeleton, Locale locale) 4342ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller { 4352ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller return getInstance(skeleton, ULocale.forLocale(locale)); 4362ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } 4372ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller 4382ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller 4392ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller /** 4402ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * Construct a DateIntervalFormat from skeleton and a given locale. 4412ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * <P> 4422ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * In this factory method, 4432ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * the date interval pattern information is load from resource files. 4442ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * Users are encouraged to created date interval formatter this way and 4452ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * to use the pre-defined skeleton macros. 4462ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * 4472ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * <P> 4482ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * There are pre-defined skeletons in DateFormat, 4492ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * such as MONTH_DAY, YEAR_MONTH_WEEKDAY_DAY etc. 4502ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * 4512ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * Those skeletons have pre-defined interval patterns in resource files. 4522ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * Users are encouraged to use them. 4532ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * For example: 4542ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * DateIntervalFormat.getInstance(DateFormat.MONTH_DAY, false, loc); 4552ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * 4562ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * The given Locale provides the interval patterns. 4572ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * For example, for en_GB, if skeleton is YEAR_ABBR_MONTH_WEEKDAY_DAY, 4582ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * which is "yMMMEEEd", 4592ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * the interval patterns defined in resource file to above skeleton are: 4602ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * "EEE, d MMM, yyyy - EEE, d MMM, yyyy" for year differs, 4612ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * "EEE, d MMM - EEE, d MMM, yyyy" for month differs, 4622ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * "EEE, d - EEE, d MMM, yyyy" for day differs, 4632ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * @param skeleton the skeleton on which interval format based. 4642ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * @param locale the given locale 4652ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * @return a date time interval formatter. 4662ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller */ 4672ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller public static final DateIntervalFormat 4682ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller getInstance(String skeleton, ULocale locale) 4692ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller { 4702ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller DateTimePatternGenerator generator = DateTimePatternGenerator.getInstance(locale); 4712ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller return new DateIntervalFormat(skeleton, locale, new SimpleDateFormat(generator.getBestPattern(skeleton), locale)); 4722ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } 4732ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller 4742ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller 4752ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller 4762ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller /** 4772ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * Construct a DateIntervalFormat from skeleton 4782ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * DateIntervalInfo, and the default <code>FORMAT</code> locale. 4792ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * 4802ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * This is a convenient override of 4812ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * getInstance(String skeleton, ULocale locale, DateIntervalInfo dtitvinf) 4822ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * with the locale value as default <code>FORMAT</code> locale. 4832ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * 4842ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * @param skeleton the skeleton on which interval format based. 4852ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * @param dtitvinf the DateIntervalInfo object to be adopted. 4862ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * @return a date time interval formatter. 4872ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * @see Category#FORMAT 4882ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller */ 4892ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller public static final DateIntervalFormat getInstance(String skeleton, 4902ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller DateIntervalInfo dtitvinf) 4912ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller { 4922ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller return getInstance(skeleton, ULocale.getDefault(Category.FORMAT), dtitvinf); 4932ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } 4942ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller 4952ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller 4962ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller 4972ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller /** 4982ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * Construct a DateIntervalFormat from skeleton 4992ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * a DateIntervalInfo, and the given locale. 5002ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * 5012ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * This is a convenient override of 5022ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * getInstance(String skeleton, ULocale locale, DateIntervalInfo dtitvinf) 5032ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * 504cc49f813b0d7bf6664102b30b5513fd21c362e0dNeil Fuller * <p>Example code:{@sample external/icu/android_icu4j/src/samples/java/android/icu/samples/text/dateintervalformat/DateIntervalFormatSample.java dtitvfmtCustomizedExample} 5052ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * @param skeleton the skeleton on which interval format based. 5062ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * @param locale the given locale 5072ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * @param dtitvinf the DateIntervalInfo object to be adopted. 5082ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * @return a date time interval formatter. 5092ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller */ 5102ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller public static final DateIntervalFormat getInstance(String skeleton, 5112ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller Locale locale, 5122ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller DateIntervalInfo dtitvinf) 5132ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller { 5142ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller return getInstance(skeleton, ULocale.forLocale(locale), dtitvinf); 5152ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } 5162ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller 5172ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller 5182ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller 5192ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller /** 5202ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * Construct a DateIntervalFormat from skeleton 5212ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * a DateIntervalInfo, and the given locale. 5222ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * 5232ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * <P> 5242ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * In this factory method, user provides its own date interval pattern 5252ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * information, instead of using those pre-defined data in resource file. 5262ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * This factory method is for powerful users who want to provide their own 5272ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * interval patterns. 5282ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * 5292ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * <P> 5302ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * There are pre-defined skeleton in DateFormat, 5312ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * such as MONTH_DAY, YEAR_MONTH_WEEKDAY_DAY etc. 5322ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * 5332ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * Those skeletons have pre-defined interval patterns in resource files. 5342ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * Users are encouraged to use them. 5352ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * For example: 5362ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * DateIntervalFormat.getInstance(DateFormat.MONTH_DAY, false, loc,itvinf); 5372ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * 5382ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * the DateIntervalInfo provides the interval patterns. 5392ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * 5402ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * User are encouraged to set default interval pattern in DateIntervalInfo 5412ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * as well, if they want to set other interval patterns ( instead of 5422ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * reading the interval patterns from resource files). 5432ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * When the corresponding interval pattern for a largest calendar different 5442ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * field is not found ( if user not set it ), interval format fallback to 5452ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * the default interval pattern. 5462ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * If user does not provide default interval pattern, it fallback to 5472ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * "{date0} - {date1}" 5482ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * 5492ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * @param skeleton the skeleton on which interval format based. 5502ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * @param locale the given locale 5512ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * @param dtitvinf the DateIntervalInfo object to be adopted. 5522ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * @return a date time interval formatter. 5532ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller */ 5542ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller public static final DateIntervalFormat getInstance(String skeleton, 5552ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller ULocale locale, 5562ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller DateIntervalInfo dtitvinf) 5572ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller { 5582ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller // clone. If it is frozen, clone returns itself, otherwise, clone 5592ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller // returns a copy. 5602ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller dtitvinf = (DateIntervalInfo)dtitvinf.clone(); 5612ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller DateTimePatternGenerator generator = DateTimePatternGenerator.getInstance(locale); 5622ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller return new DateIntervalFormat(skeleton, dtitvinf, new SimpleDateFormat(generator.getBestPattern(skeleton), locale)); 5632ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } 5642ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller 5652ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller 5662ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller /** 5672ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * Clone this Format object polymorphically. 5682ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * @return A copy of the object. 5692ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller */ 5701c8a530973739aafa823d758240d2cd5dad96fe3Fredrik Roubert public synchronized Object clone() 5712ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller { 5722ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller DateIntervalFormat other = (DateIntervalFormat) super.clone(); 5732ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller other.fDateFormat = (SimpleDateFormat) fDateFormat.clone(); 5742ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller other.fInfo = (DateIntervalInfo) fInfo.clone(); 5752ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller other.fFromCalendar = (Calendar) fFromCalendar.clone(); 5762ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller other.fToCalendar = (Calendar) fToCalendar.clone(); 5772ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller other.fDatePattern = fDatePattern; 5782ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller other.fTimePattern = fTimePattern; 5792ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller other.fDateTimeFormat = fDateTimeFormat; 5802ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller return other; 5812ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } 5822ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller 5832ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller 5842ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller /** 5852ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * Format an object to produce a string. This method handles Formattable 5862ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * objects with a DateInterval type. 5872ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * If a the Formattable object type is not a DateInterval, 5882ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * IllegalArgumentException is thrown. 5892ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * 5902ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * @param obj The object to format. 5912ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * Must be a DateInterval. 5922ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * @param appendTo Output parameter to receive result. 5932ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * Result is appended to existing contents. 5942ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * @param fieldPosition On input: an alignment field, if desired. 5952ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * On output: the offsets of the alignment field. 5962ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * There may be multiple instances of a given field type 5972ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * in an interval format; in this case the fieldPosition 5982ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * offsets refer to the first instance. 5992ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * @return Reference to 'appendTo' parameter. 6002ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * @throws IllegalArgumentException if the formatted object is not 6012ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * DateInterval object 6022ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller */ 6032ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller public final StringBuffer 6042ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller format(Object obj, StringBuffer appendTo, FieldPosition fieldPosition) 6052ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller { 6062ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller if ( obj instanceof DateInterval ) { 6072ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller return format( (DateInterval)obj, appendTo, fieldPosition); 6082ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } 6092ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller else { 6102ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller throw new IllegalArgumentException("Cannot format given Object (" + obj.getClass().getName() + ") as a DateInterval"); 6112ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } 6122ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } 6132ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller 6142ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller /** 6152ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * Format a DateInterval to produce a string. 6162ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * 6172ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * @param dtInterval DateInterval to be formatted. 6182ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * @param appendTo Output parameter to receive result. 6192ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * Result is appended to existing contents. 6202ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * @param fieldPosition On input: an alignment field, if desired. 6212ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * On output: the offsets of the alignment field. 6222ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * There may be multiple instances of a given field type 6232ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * in an interval format; in this case the fieldPosition 6242ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * offsets refer to the first instance. 6252ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * @return Reference to 'appendTo' parameter. 6262ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller */ 6271c8a530973739aafa823d758240d2cd5dad96fe3Fredrik Roubert public final synchronized StringBuffer format(DateInterval dtInterval, 6282ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller StringBuffer appendTo, 6292ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller FieldPosition fieldPosition) 6302ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller { 6312ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller fFromCalendar.setTimeInMillis(dtInterval.getFromDate()); 6322ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller fToCalendar.setTimeInMillis(dtInterval.getToDate()); 6332ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller return format(fFromCalendar, fToCalendar, appendTo, fieldPosition); 6342ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } 6352ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller 6362ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller /** 6372ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * @deprecated This API is ICU internal only. 63893cf604e9dd0525f15bc0a7450b2a35f3884c298Neil Fuller * @hide original deprecated declaration 639836e6b40a94ec3fb7545a76cb072960442b7eee9Neil Fuller * @hide draft / provisional / internal are hidden on Android 6402ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller */ 6412ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller @Deprecated 6422ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller public String getPatterns(Calendar fromCalendar, 6432ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller Calendar toCalendar, 6442ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller Output<String> part2) { 6452ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller // First, find the largest different calendar field. 6462ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller int field; 6472ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller if ( fromCalendar.get(Calendar.ERA) != toCalendar.get(Calendar.ERA) ) { 6482ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller field = Calendar.ERA; 6492ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } else if ( fromCalendar.get(Calendar.YEAR) != 6502ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller toCalendar.get(Calendar.YEAR) ) { 6512ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller field = Calendar.YEAR; 6522ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } else if ( fromCalendar.get(Calendar.MONTH) != 6532ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller toCalendar.get(Calendar.MONTH) ) { 6542ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller field = Calendar.MONTH; 6552ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } else if ( fromCalendar.get(Calendar.DATE) != 6562ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller toCalendar.get(Calendar.DATE) ) { 6572ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller field = Calendar.DATE; 6582ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } else if ( fromCalendar.get(Calendar.AM_PM) != 6592ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller toCalendar.get(Calendar.AM_PM) ) { 6602ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller field = Calendar.AM_PM; 6612ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } else if ( fromCalendar.get(Calendar.HOUR) != 6622ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller toCalendar.get(Calendar.HOUR) ) { 6632ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller field = Calendar.HOUR; 6642ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } else if ( fromCalendar.get(Calendar.MINUTE) != 6652ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller toCalendar.get(Calendar.MINUTE) ) { 6662ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller field = Calendar.MINUTE; 6672ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } else if ( fromCalendar.get(Calendar.SECOND) != 6682ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller toCalendar.get(Calendar.SECOND) ) { 6692ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller field = Calendar.SECOND; 6702ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } else { 6712ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller return null; 6722ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } 6732ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller PatternInfo intervalPattern = fIntervalPatterns.get( 6742ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller DateIntervalInfo.CALENDAR_FIELD_TO_PATTERN_LETTER[field]); 6752ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller part2.value = intervalPattern.getSecondPart(); 6762ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller return intervalPattern.getFirstPart(); 6772ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } 6782ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller /** 6792ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * Format 2 Calendars to produce a string. 6802ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * 6812ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * @param fromCalendar calendar set to the from date in date interval 6822ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * to be formatted into date interval string 6832ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * @param toCalendar calendar set to the to date in date interval 6842ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * to be formatted into date interval string 6852ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * @param appendTo Output parameter to receive result. 6862ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * Result is appended to existing contents. 6872ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * @param pos On input: an alignment field, if desired. 6882ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * On output: the offsets of the alignment field. 6892ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * There may be multiple instances of a given field type 6902ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * in an interval format; in this case the fieldPosition 6912ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * offsets refer to the first instance. 6922ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * @return Reference to 'appendTo' parameter. 6932ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * @throws IllegalArgumentException if the two calendars are not equivalent. 6942ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller */ 6951c8a530973739aafa823d758240d2cd5dad96fe3Fredrik Roubert public final synchronized StringBuffer format(Calendar fromCalendar, 6962ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller Calendar toCalendar, 6972ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller StringBuffer appendTo, 6982ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller FieldPosition pos) 6992ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller { 7002ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller // not support different calendar types and time zones 7012ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller if ( !fromCalendar.isEquivalentTo(toCalendar) ) { 7022ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller throw new IllegalArgumentException("can not format on two different calendars"); 7032ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } 7042ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller 7052ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller // First, find the largest different calendar field. 7062ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller int field = -1; //init with an invalid value. 7072ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller 7082ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller if ( fromCalendar.get(Calendar.ERA) != toCalendar.get(Calendar.ERA) ) { 7092ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller field = Calendar.ERA; 7102ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } else if ( fromCalendar.get(Calendar.YEAR) != 7112ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller toCalendar.get(Calendar.YEAR) ) { 7122ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller field = Calendar.YEAR; 7132ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } else if ( fromCalendar.get(Calendar.MONTH) != 7142ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller toCalendar.get(Calendar.MONTH) ) { 7152ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller field = Calendar.MONTH; 7162ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } else if ( fromCalendar.get(Calendar.DATE) != 7172ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller toCalendar.get(Calendar.DATE) ) { 7182ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller field = Calendar.DATE; 7192ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } else if ( fromCalendar.get(Calendar.AM_PM) != 7202ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller toCalendar.get(Calendar.AM_PM) ) { 7212ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller field = Calendar.AM_PM; 7222ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } else if ( fromCalendar.get(Calendar.HOUR) != 7232ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller toCalendar.get(Calendar.HOUR) ) { 7242ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller field = Calendar.HOUR; 7252ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } else if ( fromCalendar.get(Calendar.MINUTE) != 7262ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller toCalendar.get(Calendar.MINUTE) ) { 7272ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller field = Calendar.MINUTE; 7282ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } else if ( fromCalendar.get(Calendar.SECOND) != 7292ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller toCalendar.get(Calendar.SECOND) ) { 7302ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller field = Calendar.SECOND; 7312ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } else { 7322ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller /* ignore the millisecond etc. small fields' difference. 7332ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * use single date when all the above are the same. 7342ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller */ 7352ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller return fDateFormat.format(fromCalendar, appendTo, pos); 7362ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } 7372ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller boolean fromToOnSameDay = (field==Calendar.AM_PM || field==Calendar.HOUR || field==Calendar.MINUTE || field==Calendar.SECOND); 7382ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller 7392ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller // get interval pattern 7402ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller PatternInfo intervalPattern = fIntervalPatterns.get( 7412ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller DateIntervalInfo.CALENDAR_FIELD_TO_PATTERN_LETTER[field]); 7422ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller 7432ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller if ( intervalPattern == null ) { 7442ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller if ( fDateFormat.isFieldUnitIgnored(field) ) { 7452ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller /* the largest different calendar field is small than 7462ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * the smallest calendar field in pattern, 7472ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * return single date format. 7482ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller */ 7492ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller return fDateFormat.format(fromCalendar, appendTo, pos); 7502ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } 7512ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller 7522ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller return fallbackFormat(fromCalendar, toCalendar, fromToOnSameDay, appendTo, pos); 7532ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } 7542ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller 7552ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller // If the first part in interval pattern is empty, 7562ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller // the 2nd part of it saves the full-pattern used in fall-back. 7572ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller // For a 'real' interval pattern, the first part will never be empty. 7582ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller if ( intervalPattern.getFirstPart() == null ) { 7592ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller // fall back 7602ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller return fallbackFormat(fromCalendar, toCalendar, fromToOnSameDay, appendTo, pos, 7612ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller intervalPattern.getSecondPart()); 7622ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } 7632ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller Calendar firstCal; 7642ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller Calendar secondCal; 7652ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller if ( intervalPattern.firstDateInPtnIsLaterDate() ) { 7662ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller firstCal = toCalendar; 7672ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller secondCal = fromCalendar; 7682ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } else { 7692ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller firstCal = fromCalendar; 7702ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller secondCal = toCalendar; 7712ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } 7722ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller // break the interval pattern into 2 parts 7732ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller // first part should not be empty, 7742ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller String originalPattern = fDateFormat.toPattern(); 7752ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller fDateFormat.applyPattern(intervalPattern.getFirstPart()); 7762ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller fDateFormat.format(firstCal, appendTo, pos); 7772ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller if ( intervalPattern.getSecondPart() != null ) { 7782ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller fDateFormat.applyPattern(intervalPattern.getSecondPart()); 7792ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller FieldPosition otherPos = new FieldPosition(pos.getField()); 7802ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller fDateFormat.format(secondCal, appendTo, otherPos); 7812ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller if (pos.getEndIndex() == 0 && otherPos.getEndIndex() > 0) { 782f86f25d102340da66b9c7cb6b2d5ecdc0de43ecfFredrik Roubert pos.setBeginIndex(otherPos.getBeginIndex()); 783f86f25d102340da66b9c7cb6b2d5ecdc0de43ecfFredrik Roubert pos.setEndIndex(otherPos.getEndIndex()); 7842ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } 7852ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } 7862ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller fDateFormat.applyPattern(originalPattern); 7872ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller return appendTo; 7882ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } 7892ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller 7902ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller private void adjustPosition(String combiningPattern, // has {0} and {1} in it 7912ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller String pat0, FieldPosition pos0, // pattern and pos corresponding to {0} 7922ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller String pat1, FieldPosition pos1, // pattern and pos corresponding to {1} 7932ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller FieldPosition posResult) { 7942ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller int index0 = combiningPattern.indexOf("{0}"); 7952ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller int index1 = combiningPattern.indexOf("{1}"); 7962ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller if (index0 < 0 || index1 < 0) { 7972ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller return; 7982ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } 7992ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller int placeholderLen = 3; // length of "{0}" or "{1}" 8002ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller if (index0 < index1) { 8012ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller if (pos0.getEndIndex() > 0) { 8022ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller posResult.setBeginIndex(pos0.getBeginIndex() + index0); 8032ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller posResult.setEndIndex(pos0.getEndIndex() + index0); 8042ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } else if (pos1.getEndIndex() > 0) { 8052ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller // here index1 >= 3 8062ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller index1 += pat0.length() - placeholderLen; // adjust for pat0 replacing {0} 8072ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller posResult.setBeginIndex(pos1.getBeginIndex() + index1); 8082ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller posResult.setEndIndex(pos1.getEndIndex() + index1); 8092ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } 8102ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } else { 8112ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller if (pos1.getEndIndex() > 0) { 8122ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller posResult.setBeginIndex(pos1.getBeginIndex() + index1); 8132ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller posResult.setEndIndex(pos1.getEndIndex() + index1); 8142ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } else if (pos0.getEndIndex() > 0) { 8152ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller // here index0 >= 3 8162ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller index0 += pat1.length() - placeholderLen; // adjust for pat1 replacing {1} 8172ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller posResult.setBeginIndex(pos0.getBeginIndex() + index0); 8182ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller posResult.setEndIndex(pos0.getEndIndex() + index0); 8192ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } 8202ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } 8212ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } 8222ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller 8232ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller /* 8242ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * Format 2 Calendars to using fall-back interval pattern 8252ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * 8262ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * The full pattern used in this fall-back format is the 8272ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * full pattern of the date formatter. 8282ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * 8292ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * @param fromCalendar calendar set to the from date in date interval 8302ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * to be formatted into date interval string 8312ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * @param toCalendar calendar set to the to date in date interval 8322ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * to be formatted into date interval string 8332ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * @param appendTo Output parameter to receive result. 8342ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * Result is appended to existing contents. 8352ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * @param pos On input: an alignment field, if desired. 8362ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * On output: the offsets of the alignment field. 8372ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * @return Reference to 'appendTo' parameter. 8382ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller */ 8392ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller private final StringBuffer fallbackFormat(Calendar fromCalendar, 8402ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller Calendar toCalendar, 8412ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller boolean fromToOnSameDay, 8422ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller StringBuffer appendTo, 8432ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller FieldPosition pos) { 8442ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller String fullPattern = null; // for saving the pattern in fDateFormat 8452ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller boolean formatDatePlusTimeRange = (fromToOnSameDay && fDatePattern != null && fTimePattern != null); 8462ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller // the fall back 8472ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller if (formatDatePlusTimeRange) { 8482ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller fullPattern = fDateFormat.toPattern(); // save current pattern, restore later 8492ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller fDateFormat.applyPattern(fTimePattern); 8502ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } 8512ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller FieldPosition otherPos = new FieldPosition(pos.getField()); 8522ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller StringBuffer earlierDate = new StringBuffer(64); 8532ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller earlierDate = fDateFormat.format(fromCalendar, earlierDate, pos); 8542ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller StringBuffer laterDate = new StringBuffer(64); 8552ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller laterDate = fDateFormat.format(toCalendar, laterDate, otherPos); 8562ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller String fallbackPattern = fInfo.getFallbackIntervalPattern(); 8572ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller adjustPosition(fallbackPattern, earlierDate.toString(), pos, laterDate.toString(), otherPos, pos); 8581c8a530973739aafa823d758240d2cd5dad96fe3Fredrik Roubert String fallbackRange = SimpleFormatterImpl.formatRawPattern( 8591c8a530973739aafa823d758240d2cd5dad96fe3Fredrik Roubert fallbackPattern, 2, 2, earlierDate, laterDate); 8602ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller if (formatDatePlusTimeRange) { 8612ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller // fallbackRange has just the time range, need to format the date part and combine that 8622ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller fDateFormat.applyPattern(fDatePattern); 8632ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller StringBuffer datePortion = new StringBuffer(64); 8642ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller otherPos.setBeginIndex(0); 8652ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller otherPos.setEndIndex(0); 8662ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller datePortion = fDateFormat.format(fromCalendar, datePortion, otherPos); 8672ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller adjustPosition(fDateTimeFormat, fallbackRange, pos, datePortion.toString(), otherPos, pos); 8681c8a530973739aafa823d758240d2cd5dad96fe3Fredrik Roubert fallbackRange = SimpleFormatterImpl.formatRawPattern( 8691c8a530973739aafa823d758240d2cd5dad96fe3Fredrik Roubert fDateTimeFormat, 2, 2, fallbackRange, datePortion); 8702ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } 8712ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller appendTo.append(fallbackRange); 8722ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller if (formatDatePlusTimeRange) { 8732ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller // restore full pattern 8742ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller fDateFormat.applyPattern(fullPattern); 8752ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } 8762ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller return appendTo; 8772ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } 8782ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller 8792ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller 8802ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller /* 8812ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * Format 2 Calendars to using fall-back interval pattern 8822ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * 8832ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * This fall-back pattern is generated on a given full pattern, 8842ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * not the full pattern of the date formatter. 8852ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * 8862ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * @param fromCalendar calendar set to the from date in date interval 8872ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * to be formatted into date interval string 8882ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * @param toCalendar calendar set to the to date in date interval 8892ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * to be formatted into date interval string 8902ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * @param appendTo Output parameter to receive result. 8912ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * Result is appended to existing contents. 8922ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * @param pos On input: an alignment field, if desired. 8932ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * On output: the offsets of the alignment field. 8942ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * @param fullPattern the full pattern need to apply to date formatter 8952ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * @return Reference to 'appendTo' parameter. 8962ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller */ 8972ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller private final StringBuffer fallbackFormat(Calendar fromCalendar, 8982ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller Calendar toCalendar, 8992ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller boolean fromToOnSameDay, 9002ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller StringBuffer appendTo, 9012ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller FieldPosition pos, 9022ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller String fullPattern) { 9032ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller String originalPattern = fDateFormat.toPattern(); 9042ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller fDateFormat.applyPattern(fullPattern); 9052ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller fallbackFormat(fromCalendar, toCalendar, fromToOnSameDay, appendTo, pos); 9062ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller fDateFormat.applyPattern(originalPattern); 9072ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller return appendTo; 9082ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } 9092ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller 9102ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller 9112ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller /** 9122ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * Date interval parsing is not supported. 9132ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * <P> 9142ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * This method should handle parsing of 9152ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * date time interval strings into Formattable objects with 9162ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * DateInterval type, which is a pair of UDate. 9172ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * <P> 9182ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * Before calling, set parse_pos.index to the offset you want to start 9192ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * parsing at in the source. After calling, parse_pos.index is the end of 9202ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * the text you parsed. If error occurs, index is unchanged. 9212ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * <P> 9222ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * When parsing, leading whitespace is discarded (with a successful parse), 9232ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * while trailing whitespace is left as is. 9242ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * <P> 9252ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * See Format.parseObject() for more. 9262ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * 9272ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * @param source The string to be parsed into an object. 9282ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * @param parse_pos The position to start parsing at. Since no parsing 9292ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * is supported, upon return this param is unchanged. 9302ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * @return A newly created Formattable* object, or NULL 9312ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * on failure. 9322ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * @deprecated This API is ICU internal only. 93393cf604e9dd0525f15bc0a7450b2a35f3884c298Neil Fuller * @hide original deprecated declaration 934836e6b40a94ec3fb7545a76cb072960442b7eee9Neil Fuller * @hide draft / provisional / internal are hidden on Android 9352ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller */ 9362ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller @Deprecated 9372ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller public Object parseObject(String source, ParsePosition parse_pos) 9382ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller { 9392ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller throw new UnsupportedOperationException("parsing is not supported"); 9402ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } 9412ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller 9422ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller 9432ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller /** 9442ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * Gets the date time interval patterns. 9452ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * @return a copy of the date time interval patterns associated with 9462ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * this date interval formatter. 9472ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller */ 9482ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller public DateIntervalInfo getDateIntervalInfo() 9492ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller { 9502ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller return (DateIntervalInfo)fInfo.clone(); 9512ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } 9522ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller 9532ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller 9542ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller /** 9552ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * Set the date time interval patterns. 9562ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * @param newItvPattern the given interval patterns to copy. 9572ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller */ 9582ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller public void setDateIntervalInfo(DateIntervalInfo newItvPattern) 9592ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller { 9602ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller // clone it. If it is frozen, the clone returns itself. 9612ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller // Otherwise, clone returns a copy 9622ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller fInfo = (DateIntervalInfo)newItvPattern.clone(); 9632ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller this.isDateIntervalInfoDefault = false; 9642ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller fInfo.freeze(); // freeze it 9652ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller if ( fDateFormat != null ) { 9662ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller initializePattern(null); 9672ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } 9682ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } 9692ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller 9702ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller /** 9712ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * Get the TimeZone 9722ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * @return A copy of the TimeZone associated with this date interval formatter. 9732ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller */ 9742ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller public TimeZone getTimeZone() 9752ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller { 9762ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller if ( fDateFormat != null ) { 9772ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller // Here we clone, like other getters here, but unlike 9782ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller // DateFormat.getTimeZone() and Calendar.getTimeZone() 9792ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller // which return the TimeZone from the Calendar's zone variable 9802ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller return (TimeZone)(fDateFormat.getTimeZone().clone()); 9812ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } 9822ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller // If fDateFormat is null (unexpected), return default timezone. 9832ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller return TimeZone.getDefault(); 9842ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } 9852ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller 9862ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller 9872ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller /** 9882ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * Set the TimeZone for the calendar used by this DateIntervalFormat object. 9892ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * @param zone The new TimeZone, will be cloned for use by this DateIntervalFormat. 9902ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller */ 9912ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller public void setTimeZone(TimeZone zone) 9922ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller { 9932ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller // zone is cloned once for all three usages below: 9942ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller TimeZone zoneToSet = (TimeZone)zone.clone(); 9952ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller if (fDateFormat != null) { 9962ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller fDateFormat.setTimeZone(zoneToSet); 9972ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } 9982ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller // fDateFormat has the master calendar for the DateIntervalFormat; 9992ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller // fFromCalendar and fToCalendar are internal work clones of that calendar. 10002ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller if (fFromCalendar != null) { 10012ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller fFromCalendar.setTimeZone(zoneToSet); 10022ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } 10032ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller if (fToCalendar != null) { 10042ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller fToCalendar.setTimeZone(zoneToSet); 10052ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } 10062ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } 10072ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller 10082ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller /** 10092ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * Gets the date formatter 10102ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * @return a copy of the date formatter associated with 10112ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * this date interval formatter. 10122ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller */ 10131c8a530973739aafa823d758240d2cd5dad96fe3Fredrik Roubert public synchronized DateFormat getDateFormat() 10142ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller { 10152ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller return (DateFormat)fDateFormat.clone(); 10162ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } 10172ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller 10182ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller 10192ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller /* 10202ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * Below are for generating interval patterns locale to the formatter 10212ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller */ 10222ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller 10232ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller /* 10242ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * Initialize interval patterns locale to this formatter. 10252ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller */ 10262ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller private void initializePattern(ICUCache<String, Map<String, PatternInfo>> cache) { 10272ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller String fullPattern = fDateFormat.toPattern(); 10282ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller ULocale locale = fDateFormat.getLocale(); 10292ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller String key = null; 10302ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller Map<String, PatternInfo> patterns = null; 10312ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller if (cache != null) { 10322ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller if ( fSkeleton != null ) { 10332ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller key = locale.toString() + "+" + fullPattern + "+" + fSkeleton; 10342ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } else { 10352ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller key = locale.toString() + "+" + fullPattern; 10362ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } 10372ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller patterns = cache.get(key); 10382ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } 10392ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller if (patterns == null) { 10402ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller Map<String, PatternInfo> intervalPatterns = initializeIntervalPattern(fullPattern, locale); 10412ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller patterns = Collections.unmodifiableMap(intervalPatterns); 10422ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller if (cache != null) { 10432ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller cache.put(key, patterns); 10442ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } 10452ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } 10462ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller fIntervalPatterns = patterns; 10472ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } 10482ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller 10492ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller 10502ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller 10512ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller /* 10522ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * Initialize interval patterns locale to this formatter 10532ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * 10542ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * This code is a bit complicated since 10552ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * 1. the interval patterns saved in resource bundle files are interval 10562ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * patterns based on date or time only. 10572ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * It does not have interval patterns based on both date and time. 10582ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * Interval patterns on both date and time are algorithm generated. 10592ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * 10602ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * For example, it has interval patterns on skeleton "dMy" and "hm", 10612ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * but it does not have interval patterns on skeleton "dMyhm". 10622ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * 10632ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * The rule to generate interval patterns for both date and time skeleton are 10642ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * 1) when the year, month, or day differs, concatenate the two original 10652ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * expressions with a separator between, 10662ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * For example, interval pattern from "Jan 10, 2007 10:10 am" 10672ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * to "Jan 11, 2007 10:10am" is 10682ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * "Jan 10, 2007 10:10 am - Jan 11, 2007 10:10am" 10692ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * 10702ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * 2) otherwise, present the date followed by the range expression 10712ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * for the time. 10722ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * For example, interval pattern from "Jan 10, 2007 10:10 am" 10732ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * to "Jan 10, 2007 11:10am" is 10742ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * "Jan 10, 2007 10:10 am - 11:10am" 10752ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * 10762ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * 2. even a pattern does not request a certain calendar field, 10772ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * the interval pattern needs to include such field if such fields are 10782ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * different between 2 dates. 10792ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * For example, a pattern/skeleton is "hm", but the interval pattern 10802ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * includes year, month, and date when year, month, and date differs. 10812ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * 10822ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * 10832ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * @param fullPattern formatter's full pattern 10842ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * @param locale the given locale. 10852ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * @return interval patterns' hash map 10862ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller */ 10872ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller private Map<String, PatternInfo> initializeIntervalPattern(String fullPattern, ULocale locale) { 10882ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller DateTimePatternGenerator dtpng = DateTimePatternGenerator.getInstance(locale); 10892ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller if ( fSkeleton == null ) { 10902ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller // fSkeleton is already set by getDateIntervalInstance() 10912ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller // or by getInstance(String skeleton, .... ) 10922ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller fSkeleton = dtpng.getSkeleton(fullPattern); 10932ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } 10942ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller String skeleton = fSkeleton; 10952ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller 10962ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller HashMap<String, PatternInfo> intervalPatterns = new HashMap<String, PatternInfo>(); 10972ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller 10982ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller /* Check whether the skeleton is a combination of date and time. 10992ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * For the complication reason 1 explained above. 11002ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller */ 11012ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller StringBuilder date = new StringBuilder(skeleton.length()); 11022ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller StringBuilder normalizedDate = new StringBuilder(skeleton.length()); 11032ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller StringBuilder time = new StringBuilder(skeleton.length()); 11042ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller StringBuilder normalizedTime = new StringBuilder(skeleton.length()); 11052ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller 11062ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller /* the difference between time skeleton and normalizedTimeSkeleton are: 11072ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * 1. (Formerly, normalized time skeleton folded 'H' to 'h'; no longer true) 11082ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * 2. 'a' is omitted in normalized time skeleton. 11092ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * 3. there is only one appearance for 'h', 'm','v', 'z' in normalized 11102ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * time skeleton 11112ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * 11122ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * The difference between date skeleton and normalizedDateSkeleton are: 11132ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * 1. both 'y' and 'd' appear only once in normalizeDateSkeleton 11142ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * 2. 'E' and 'EE' are normalized into 'EEE' 11152ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * 3. 'MM' is normalized into 'M' 11162ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller */ 11172ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller getDateTimeSkeleton(skeleton, date, normalizedDate, 11182ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller time, normalizedTime); 11192ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller 11202ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller String dateSkeleton = date.toString(); 11212ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller String timeSkeleton = time.toString(); 11222ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller String normalizedDateSkeleton = normalizedDate.toString(); 11232ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller String normalizedTimeSkeleton = normalizedTime.toString(); 11242ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller 11252ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller // move this up here since we need it for fallbacks 11262ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller if (time.length() != 0 && date.length() != 0) { 1127f86f25d102340da66b9c7cb6b2d5ecdc0de43ecfFredrik Roubert // Need the Date/Time pattern for concatenating the date with 11282ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller // the time interval. 11292ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller // The date/time pattern ( such as {0} {1} ) is saved in 11302ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller // calendar, that is why need to get the CalendarData here. 1131f86f25d102340da66b9c7cb6b2d5ecdc0de43ecfFredrik Roubert fDateTimeFormat = getConcatenationPattern(locale); 11322ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } 11332ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller 11342ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller boolean found = genSeparateDateTimePtn(normalizedDateSkeleton, 11352ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller normalizedTimeSkeleton, 11362ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller intervalPatterns, dtpng); 11372ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller 11382ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller // for skeletons with seconds, found is false and we enter this block 11392ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller if ( found == false ) { 11402ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller // use fallback 11412ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller // TODO: if user asks "m", but "d" differ 11422ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller //StringBuffer skeleton = new StringBuffer(skeleton); 11432ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller if ( time.length() != 0 ) { 11442ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller //genFallbackForNotFound(Calendar.MINUTE, skeleton); 11452ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller //genFallbackForNotFound(Calendar.HOUR, skeleton); 11462ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller //genFallbackForNotFound(Calendar.AM_PM, skeleton); 11472ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller if ( date.length() == 0 ) { 11482ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller // prefix with yMd 11492ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller timeSkeleton = DateFormat.YEAR_NUM_MONTH_DAY + timeSkeleton; 11502ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller String pattern =dtpng.getBestPattern(timeSkeleton); 11512ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller // for fall back interval patterns, 11522ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller // the first part of the pattern is empty, 11532ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller // the second part of the pattern is the full-pattern 11542ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller // should be used in fall-back. 11552ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller PatternInfo ptn = new PatternInfo(null, pattern, 11562ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller fInfo.getDefaultOrder()); 11572ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller intervalPatterns.put(DateIntervalInfo. 11582ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller CALENDAR_FIELD_TO_PATTERN_LETTER[Calendar.DATE], ptn); 11592ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller // share interval pattern 11602ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller intervalPatterns.put(DateIntervalInfo. 11612ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller CALENDAR_FIELD_TO_PATTERN_LETTER[Calendar.MONTH], ptn); 11622ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller // share interval pattern 11632ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller intervalPatterns.put(DateIntervalInfo. 11642ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller CALENDAR_FIELD_TO_PATTERN_LETTER[Calendar.YEAR], ptn); 11652ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } else { 11662ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller //genFallbackForNotFound(Calendar.DATE, skeleton); 11672ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller //genFallbackForNotFound(Calendar.MONTH, skeleton); 11682ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller //genFallbackForNotFound(Calendar.YEAR, skeleton); 11692ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } 11702ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } else { 11712ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller //genFallbackForNotFound(Calendar.DATE, skeleton); 11722ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller //genFallbackForNotFound(Calendar.MONTH, skeleton); 11732ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller //genFallbackForNotFound(Calendar.YEAR, skeleton); 11742ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } 11752ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller return intervalPatterns; 11762ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } // end of skeleton not found 11772ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller // interval patterns for skeleton are found in resource 11782ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller if ( time.length() == 0 ) { 11792ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller // done 11802ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } else if ( date.length() == 0 ) { 11812ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller // need to set up patterns for y/M/d differ 11822ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller /* result from following looks confusing. 11832ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * for example: 10 10:10 - 11 10:10, it is not 11842ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * clear that the first 10 is the 10th day 11852ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller time.insert(0, 'd'); 11862ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller genFallbackPattern(Calendar.DATE, time); 11872ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller time.insert(0, 'M'); 11882ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller genFallbackPattern(Calendar.MONTH, time); 11892ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller time.insert(0, 'y'); 11902ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller genFallbackPattern(Calendar.YEAR, time); 11912ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller */ 11922ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller // prefix with yMd 11932ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller timeSkeleton = DateFormat.YEAR_NUM_MONTH_DAY + timeSkeleton; 11942ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller String pattern =dtpng.getBestPattern(timeSkeleton); 11952ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller // for fall back interval patterns, 11962ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller // the first part of the pattern is empty, 11972ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller // the second part of the pattern is the full-pattern 11982ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller // should be used in fall-back. 11992ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller PatternInfo ptn = new PatternInfo( 12002ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller null, pattern, fInfo.getDefaultOrder()); 12012ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller intervalPatterns.put(DateIntervalInfo. 12022ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller CALENDAR_FIELD_TO_PATTERN_LETTER[Calendar.DATE], ptn); 12032ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller intervalPatterns.put(DateIntervalInfo. 12042ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller CALENDAR_FIELD_TO_PATTERN_LETTER[Calendar.MONTH], ptn); 12052ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller intervalPatterns.put(DateIntervalInfo. 12062ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller CALENDAR_FIELD_TO_PATTERN_LETTER[Calendar.YEAR], ptn); 12072ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } else { 12082ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller /* if both present, 12092ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * 1) when the year, month, or day differs, 12102ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * concatenate the two original expressions with a separator between, 12112ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * 2) otherwise, present the date followed by the 12122ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * range expression for the time. 12132ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller */ 12142ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller /* 12152ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * 1) when the year, month, or day differs, 12162ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * concatenate the two original expressions with a separator between, 12172ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller */ 12182ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller // if field exists, use fall back 12192ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller if ( !fieldExistsInSkeleton(Calendar.DATE, dateSkeleton) ) { 12202ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller // prefix skeleton with 'd' 12212ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller skeleton = DateIntervalInfo. 12222ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller CALENDAR_FIELD_TO_PATTERN_LETTER[Calendar.DATE] + skeleton; 12232ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller genFallbackPattern(Calendar.DATE, skeleton, intervalPatterns, dtpng); 12242ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } 12252ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller if ( !fieldExistsInSkeleton(Calendar.MONTH, dateSkeleton) ) { 12262ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller // then prefix skeleton with 'M' 12272ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller skeleton = DateIntervalInfo. 12282ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller CALENDAR_FIELD_TO_PATTERN_LETTER[Calendar.MONTH] + skeleton; 12292ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller genFallbackPattern(Calendar.MONTH, skeleton, intervalPatterns, dtpng); 12302ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } 12312ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller if ( !fieldExistsInSkeleton(Calendar.YEAR, dateSkeleton) ) { 12322ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller // then prefix skeleton with 'y' 12332ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller skeleton = DateIntervalInfo. 12342ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller CALENDAR_FIELD_TO_PATTERN_LETTER[Calendar.YEAR] + skeleton; 12352ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller genFallbackPattern(Calendar.YEAR, skeleton, intervalPatterns, dtpng); 12362ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } 12372ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller 12382ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller /* 12392ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * 2) otherwise, present the date followed by the 12402ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * range expression for the time. 12412ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller */ 12422ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller if (fDateTimeFormat == null) { 12432ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller fDateTimeFormat = "{1} {0}"; 12442ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } 12452ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller String datePattern =dtpng.getBestPattern(dateSkeleton); 12462ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller concatSingleDate2TimeInterval(fDateTimeFormat, datePattern, Calendar.AM_PM, intervalPatterns); 12472ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller concatSingleDate2TimeInterval(fDateTimeFormat, datePattern, Calendar.HOUR, intervalPatterns); 12482ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller concatSingleDate2TimeInterval(fDateTimeFormat, datePattern, Calendar.MINUTE, intervalPatterns); 12492ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } 12502ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller 12512ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller return intervalPatterns; 12522ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } 12532ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller 1254f86f25d102340da66b9c7cb6b2d5ecdc0de43ecfFredrik Roubert /** 1255f86f25d102340da66b9c7cb6b2d5ecdc0de43ecfFredrik Roubert * Retrieves the concatenation DateTime pattern from the resource bundle. 1256f86f25d102340da66b9c7cb6b2d5ecdc0de43ecfFredrik Roubert * @param locale Locale to retrieve. 1257f86f25d102340da66b9c7cb6b2d5ecdc0de43ecfFredrik Roubert * @return Concatenation DateTime pattern. 1258f86f25d102340da66b9c7cb6b2d5ecdc0de43ecfFredrik Roubert */ 1259f86f25d102340da66b9c7cb6b2d5ecdc0de43ecfFredrik Roubert private String getConcatenationPattern(ULocale locale) { 1260f86f25d102340da66b9c7cb6b2d5ecdc0de43ecfFredrik Roubert ICUResourceBundle rb = (ICUResourceBundle) UResourceBundle.getBundleInstance(ICUData.ICU_BASE_NAME, locale); 1261f86f25d102340da66b9c7cb6b2d5ecdc0de43ecfFredrik Roubert ICUResourceBundle dtPatternsRb = rb.getWithFallback("calendar/gregorian/DateTimePatterns"); 1262f86f25d102340da66b9c7cb6b2d5ecdc0de43ecfFredrik Roubert ICUResourceBundle concatenationPatternRb = (ICUResourceBundle) dtPatternsRb.get(8); 1263f86f25d102340da66b9c7cb6b2d5ecdc0de43ecfFredrik Roubert if (concatenationPatternRb.getType() == UResourceBundle.STRING) { 1264f86f25d102340da66b9c7cb6b2d5ecdc0de43ecfFredrik Roubert return concatenationPatternRb.getString(); 1265f86f25d102340da66b9c7cb6b2d5ecdc0de43ecfFredrik Roubert } else { 1266f86f25d102340da66b9c7cb6b2d5ecdc0de43ecfFredrik Roubert return concatenationPatternRb.getString(0); 1267f86f25d102340da66b9c7cb6b2d5ecdc0de43ecfFredrik Roubert } 1268f86f25d102340da66b9c7cb6b2d5ecdc0de43ecfFredrik Roubert } 12692ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller 12702ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller /* 12712ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * Generate fall back interval pattern given a calendar field, 12722ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * a skeleton, and a date time pattern generator 12732ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * @param field the largest different calendar field 12742ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * @param skeleton a skeleton 12752ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * @param dtpng date time pattern generator 12762ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * @param intervalPatterns interval patterns 12772ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller */ 12782ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller private void genFallbackPattern(int field, String skeleton, 12792ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller Map<String, PatternInfo> intervalPatterns, 12802ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller DateTimePatternGenerator dtpng) { 12812ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller String pattern = dtpng.getBestPattern(skeleton); 12822ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller // for fall back interval patterns, 12832ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller // the first part of the pattern is empty, 12842ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller // the second part of the pattern is the full-pattern 12852ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller // should be used in fall-back. 12862ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller PatternInfo ptn = new PatternInfo( 12872ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller null, pattern, fInfo.getDefaultOrder()); 12882ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller intervalPatterns.put( 12892ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller DateIntervalInfo.CALENDAR_FIELD_TO_PATTERN_LETTER[field], ptn); 12902ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } 12912ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller 12922ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller 12932ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller 12942ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller /* 12952ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller private void genFallbackForNotFound(String field, StringBuffer skeleton) { 12962ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller if ( SimpleDateFormat.isFieldUnitIgnored(skeleton.toString(), field) ) { 12972ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller // single date 12982ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller DateIntervalInfo.PatternInfo ptnInfo = 12992ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller new DateIntervalInfo.PatternInfo(null, fDateFormat.toPattern(), 13002ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller fInfo.getDefaultOrder()); 13012ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller fIntervalPatterns.put(field, ptnInfo); 13022ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller return; 13032ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } else if ( skeleton.indexOf(field) == -1 ) { 13042ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller skeleton.insert(0,field); 13052ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller genFallbackPattern(field, skeleton, dtpng); 13062ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } 13072ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } 13082ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller */ 13092ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller 13102ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller /* 13112ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * get separated date and time skeleton from a combined skeleton. 13122ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * 13132ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * The difference between date skeleton and normalizedDateSkeleton are: 13142ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * 1. both 'y' and 'd' are appeared only once in normalizeDateSkeleton 13152ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * 2. 'E' and 'EE' are normalized into 'EEE' 13162ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * 3. 'MM' is normalized into 'M' 13172ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * 13182ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller ** the difference between time skeleton and normalizedTimeSkeleton are: 13192ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * 1. both 'H' and 'h' are normalized as 'h' in normalized time skeleton, 13202ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * 2. 'a' is omitted in normalized time skeleton. 13212ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * 3. there is only one appearance for 'h', 'm','v', 'z' in normalized time 13222ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * skeleton 13232ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * 13242ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * 13252ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * @param skeleton given combined skeleton. 13262ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * @param date Output parameter for date only skeleton. 13272ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * @param normalizedDate Output parameter for normalized date only 13282ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * 13292ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * @param time Output parameter for time only skeleton. 13302ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * @param normalizedTime Output parameter for normalized time only 13312ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * skeleton. 13322ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller */ 13332ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller private static void getDateTimeSkeleton(String skeleton, 13342ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller StringBuilder dateSkeleton, 13352ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller StringBuilder normalizedDateSkeleton, 13362ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller StringBuilder timeSkeleton, 13372ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller StringBuilder normalizedTimeSkeleton) 13382ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller { 13392ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller // dateSkeleton follows the sequence of y*M*E*d* 13402ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller // timeSkeleton follows the sequence of hm*[v|z]? 13412ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller int i; 13422ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller int ECount = 0; 13432ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller int dCount = 0; 13442ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller int MCount = 0; 13452ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller int yCount = 0; 13462ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller int hCount = 0; 13472ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller int HCount = 0; 13482ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller int mCount = 0; 13492ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller int vCount = 0; 13502ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller int zCount = 0; 13512ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller 13522ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller for (i = 0; i < skeleton.length(); ++i) { 13532ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller char ch = skeleton.charAt(i); 13542ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller switch ( ch ) { 13552ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller case 'E': 13562ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller dateSkeleton.append(ch); 13572ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller ++ECount; 13582ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller break; 13592ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller case 'd': 13602ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller dateSkeleton.append(ch); 13612ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller ++dCount; 13622ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller break; 13632ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller case 'M': 13642ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller dateSkeleton.append(ch); 13652ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller ++MCount; 13662ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller break; 13672ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller case 'y': 13682ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller dateSkeleton.append(ch); 13692ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller ++yCount; 13702ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller break; 13712ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller case 'G': 13722ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller case 'Y': 13732ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller case 'u': 13742ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller case 'Q': 13752ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller case 'q': 13762ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller case 'L': 13772ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller case 'l': 13782ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller case 'W': 13792ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller case 'w': 13802ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller case 'D': 13812ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller case 'F': 13822ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller case 'g': 13832ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller case 'e': 13842ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller case 'c': 13852ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller case 'U': 13862ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller case 'r': 13872ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller normalizedDateSkeleton.append(ch); 13882ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller dateSkeleton.append(ch); 13892ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller break; 13902ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller case 'a': 13912ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller // 'a' is implicitly handled 13922ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller timeSkeleton.append(ch); 13932ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller break; 13942ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller case 'h': 13952ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller timeSkeleton.append(ch); 13962ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller ++hCount; 13972ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller break; 13982ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller case 'H': 13992ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller timeSkeleton.append(ch); 14002ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller ++HCount; 14012ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller break; 14022ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller case 'm': 14032ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller timeSkeleton.append(ch); 14042ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller ++mCount; 14052ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller break; 14062ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller case 'z': 14072ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller ++zCount; 14082ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller timeSkeleton.append(ch); 14092ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller break; 14102ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller case 'v': 14112ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller ++vCount; 14122ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller timeSkeleton.append(ch); 14132ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller break; 14142ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller case 'V': 14152ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller case 'Z': 14162ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller case 'k': 14172ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller case 'K': 14182ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller case 'j': 14192ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller case 's': 14202ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller case 'S': 14212ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller case 'A': 14222ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller timeSkeleton.append(ch); 14232ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller normalizedTimeSkeleton.append(ch); 14242ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller break; 14252ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } 14262ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } 14272ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller 14282ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller /* generate normalized form for date*/ 14292ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller if ( yCount != 0 ) { 14302ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller for (i = 0; i < yCount; i++) { 14312ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller normalizedDateSkeleton.append('y'); 14322ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } 14332ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } 14342ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller if ( MCount != 0 ) { 14352ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller if ( MCount < 3 ) { 14362ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller normalizedDateSkeleton.append('M'); 14372ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } else { 14382ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller for ( i = 0; i < MCount && i < 5; ++i ) { 14392ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller normalizedDateSkeleton.append('M'); 14402ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } 14412ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } 14422ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } 14432ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller if ( ECount != 0 ) { 14442ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller if ( ECount <= 3 ) { 14452ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller normalizedDateSkeleton.append('E'); 14462ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } else { 14472ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller for ( i = 0; i < ECount && i < 5; ++i ) { 14482ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller normalizedDateSkeleton.append('E'); 14492ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } 14502ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } 14512ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } 14522ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller if ( dCount != 0 ) { 14532ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller normalizedDateSkeleton.append('d'); 14542ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } 14552ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller 14562ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller /* generate normalized form for time */ 14572ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller if ( HCount != 0 ) { 14582ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller normalizedTimeSkeleton.append('H'); 14592ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } 14602ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller else if ( hCount != 0 ) { 14612ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller normalizedTimeSkeleton.append('h'); 14622ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } 14632ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller if ( mCount != 0 ) { 14642ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller normalizedTimeSkeleton.append('m'); 14652ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } 14662ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller if ( zCount != 0 ) { 14672ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller normalizedTimeSkeleton.append('z'); 14682ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } 14692ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller if ( vCount != 0 ) { 14702ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller normalizedTimeSkeleton.append('v'); 14712ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } 14722ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } 14732ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller 14742ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller 14752ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller 14762ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller /* 14772ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * Generate date or time interval pattern from resource. 14782ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * 14792ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * It needs to handle the following: 14802ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * 1. need to adjust field width. 14812ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * For example, the interval patterns saved in DateIntervalInfo 14822ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * includes "dMMMy", but not "dMMMMy". 14832ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * Need to get interval patterns for dMMMMy from dMMMy. 14842ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * Another example, the interval patterns saved in DateIntervalInfo 14852ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * includes "hmv", but not "hmz". 14862ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * Need to get interval patterns for "hmz' from 'hmv' 14872ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * 14882ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * 2. there might be no pattern for 'y' differ for skeleton "Md", 14892ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * in order to get interval patterns for 'y' differ, 14902ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * need to look for it from skeleton 'yMd' 14912ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * 14922ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * @param dateSkeleton normalized date skeleton 14932ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * @param timeSkeleton normalized time skeleton 14942ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * @param intervalPatterns interval patterns 14952ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * @return whether there is interval patterns for the skeleton. 14962ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * true if there is, false otherwise 14972ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller */ 14982ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller private boolean genSeparateDateTimePtn(String dateSkeleton, 14992ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller String timeSkeleton, 15002ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller Map<String, PatternInfo> intervalPatterns, 15012ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller DateTimePatternGenerator dtpng) 15022ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller { 15032ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller String skeleton; 15042ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller // if both date and time skeleton present, 15052ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller // the final interval pattern might include time interval patterns 15062ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller // ( when, am_pm, hour, minute, second differ ), 15072ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller // but not date interval patterns ( when year, month, day differ ). 15082ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller // For year/month/day differ, it falls back to fall-back pattern. 15092ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller if ( timeSkeleton.length() != 0 ) { 15102ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller skeleton = timeSkeleton; 15112ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } else { 15122ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller skeleton = dateSkeleton; 15132ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } 15142ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller 15152ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller /* interval patterns for skeleton "dMMMy" (but not "dMMMMy") 15162ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * are defined in resource, 15172ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * interval patterns for skeleton "dMMMMy" are calculated by 15182ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * 1. get the best match skeleton for "dMMMMy", which is "dMMMy" 15192ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * 2. get the interval patterns for "dMMMy", 15202ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * 3. extend "MMM" to "MMMM" in above interval patterns for "dMMMMy" 15212ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * getBestSkeleton() is step 1. 15222ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller */ 15232ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller // best skeleton, and the difference information 15242ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller BestMatchInfo retValue = fInfo.getBestSkeleton(skeleton); 15252ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller String bestSkeleton = retValue.bestMatchSkeleton; 15262ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller int differenceInfo = retValue.bestMatchDistanceInfo; 15272ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller 15282ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller // Set patterns for fallback use, need to do this 15292ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller // before returning if differenceInfo == -1 15302ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller if (dateSkeleton.length() != 0 ) { 15312ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller fDatePattern = dtpng.getBestPattern(dateSkeleton); 15322ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } 15332ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller if (timeSkeleton.length() != 0 ) { 15342ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller fTimePattern = dtpng.getBestPattern(timeSkeleton); 15352ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } 15362ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller 15372ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller // difference: 15382ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller // 0 means the best matched skeleton is the same as input skeleton 15392ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller // 1 means the fields are the same, but field width are different 15402ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller // 2 means the only difference between fields are v/z, 15412ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller // -1 means there are other fields difference 15422ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller // (this will happen, for instance, if the supplied skeleton has seconds, 15432ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller // but no skeletons in the intervalFormats data do) 15442ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller if ( differenceInfo == -1 ) { 15452ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller // skeleton has different fields, not only v/z difference 15462ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller return false; 15472ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } 15482ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller 15492ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller if ( timeSkeleton.length() == 0 ) { 15502ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller // only has date skeleton 15512ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller genIntervalPattern(Calendar.DATE, skeleton, bestSkeleton, differenceInfo, intervalPatterns); 15522ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller SkeletonAndItsBestMatch skeletons = genIntervalPattern( 15532ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller Calendar.MONTH, skeleton, 15542ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller bestSkeleton, differenceInfo, 15552ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller intervalPatterns); 15562ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller if ( skeletons != null ) { 15572ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller bestSkeleton = skeletons.skeleton; 15582ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller skeleton = skeletons.bestMatchSkeleton; 15592ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } 15602ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller genIntervalPattern(Calendar.YEAR, skeleton, bestSkeleton, differenceInfo, intervalPatterns); 15612ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } else { 15622ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller genIntervalPattern(Calendar.MINUTE, skeleton, bestSkeleton, differenceInfo, intervalPatterns); 15632ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller genIntervalPattern(Calendar.HOUR, skeleton, bestSkeleton, differenceInfo, intervalPatterns); 15642ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller genIntervalPattern(Calendar.AM_PM, skeleton, bestSkeleton, differenceInfo, intervalPatterns); 15652ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } 15662ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller return true; 15672ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller 15682ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } 15692ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller 15702ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller 15712ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller 15722ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller /* 15732ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * Generate interval pattern from existing resource 15742ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * 15752ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * It not only save the interval patterns, 15762ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * but also return the skeleton and its best match skeleton. 15772ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * 15782ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * @param field largest different calendar field 15792ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * @param skeleton skeleton 15802ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * @param bestSkeleton the best match skeleton which has interval pattern 15812ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * defined in resource 15822ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * @param differenceInfo the difference between skeleton and best skeleton 15832ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * 0 means the best matched skeleton is the same as input skeleton 15842ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * 1 means the fields are the same, but field width are different 15852ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * 2 means the only difference between fields are v/z, 15862ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * -1 means there are other fields difference 15872ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * 15882ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * @param intervalPatterns interval patterns 15892ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * 15902ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * @return an extended skeleton or extended best skeleton if applicable. 15912ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * null otherwise. 15922ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller */ 15932ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller private SkeletonAndItsBestMatch genIntervalPattern( 15942ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller int field, String skeleton, String bestSkeleton, 15952ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller int differenceInfo, Map<String, PatternInfo> intervalPatterns) { 15962ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller SkeletonAndItsBestMatch retValue = null; 15972ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller PatternInfo pattern = fInfo.getIntervalPattern( 15982ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller bestSkeleton, field); 15992ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller if ( pattern == null ) { 16002ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller // single date 16012ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller if ( SimpleDateFormat.isFieldUnitIgnored(bestSkeleton, field) ) { 16022ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller PatternInfo ptnInfo = 16032ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller new PatternInfo(fDateFormat.toPattern(), 16042ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller null, 16052ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller fInfo.getDefaultOrder()); 16062ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller intervalPatterns.put(DateIntervalInfo. 16072ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller CALENDAR_FIELD_TO_PATTERN_LETTER[field], ptnInfo); 16082ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller return null; 16092ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } 16102ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller 16112ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller // for 24 hour system, interval patterns in resource file 16122ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller // might not include pattern when am_pm differ, 16132ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller // which should be the same as hour differ. 16142ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller // add it here for simplicity 16152ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller if ( field == Calendar.AM_PM ) { 16162ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller pattern = fInfo.getIntervalPattern(bestSkeleton, 16172ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller Calendar.HOUR); 16182ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller if ( pattern != null ) { 16192ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller // share 16202ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller intervalPatterns.put(DateIntervalInfo. 16212ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller CALENDAR_FIELD_TO_PATTERN_LETTER[field], 16222ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller pattern); 16232ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } 16242ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller return null; 16252ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } 16262ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller // else, looking for pattern when 'y' differ for 'dMMMM' skeleton, 16272ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller // first, get best match pattern "MMMd", 16282ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller // since there is no pattern for 'y' differs for skeleton 'MMMd', 16292ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller // need to look for it from skeleton 'yMMMd', 16302ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller // if found, adjust field width in interval pattern from 16312ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller // "MMM" to "MMMM". 16322ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller String fieldLetter = 16332ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller DateIntervalInfo.CALENDAR_FIELD_TO_PATTERN_LETTER[field]; 16342ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller bestSkeleton = fieldLetter + bestSkeleton; 16352ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller skeleton = fieldLetter + skeleton; 16362ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller // for example, looking for patterns when 'y' differ for 16372ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller // skeleton "MMMM". 16382ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller pattern = fInfo.getIntervalPattern(bestSkeleton, field); 16392ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller if ( pattern == null && differenceInfo == 0 ) { 16402ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller // if there is no skeleton "yMMMM" defined, 16412ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller // look for the best match skeleton, for example: "yMMM" 16422ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller BestMatchInfo tmpRetValue = fInfo.getBestSkeleton(skeleton); 16432ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller String tmpBestSkeleton = tmpRetValue.bestMatchSkeleton; 16442ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller differenceInfo = tmpRetValue.bestMatchDistanceInfo; 16452ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller if ( tmpBestSkeleton.length() != 0 && differenceInfo != -1 ) { 16462ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller pattern = fInfo.getIntervalPattern(tmpBestSkeleton, field); 16472ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller bestSkeleton = tmpBestSkeleton; 16482ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } 16492ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } 16502ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller if ( pattern != null ) { 16512ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller retValue = new SkeletonAndItsBestMatch(skeleton, bestSkeleton); 16522ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } 16532ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } 16542ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller if ( pattern != null ) { 16552ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller if ( differenceInfo != 0 ) { 16562ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller String part1 = adjustFieldWidth(skeleton, bestSkeleton, 16572ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller pattern.getFirstPart(), differenceInfo); 16582ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller String part2 = adjustFieldWidth(skeleton, bestSkeleton, 16592ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller pattern.getSecondPart(), differenceInfo); 16602ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller pattern = new PatternInfo(part1, part2, 16612ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller pattern.firstDateInPtnIsLaterDate()); 16622ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } else { 16632ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller // pattern is immutable, no need to clone; 16642ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller // pattern = (PatternInfo)pattern.clone(); 16652ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } 16662ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller intervalPatterns.put( 16672ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller DateIntervalInfo.CALENDAR_FIELD_TO_PATTERN_LETTER[field], pattern); 16682ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } 16692ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller return retValue; 16702ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } 16712ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller 16722ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller /* 16732ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * Adjust field width in best match interval pattern to match 16742ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * the field width in input skeleton. 16752ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * 16762ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * TODO (xji) make a general solution 16772ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * The adjusting rule can be: 16782ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * 1. always adjust 16792ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * 2. never adjust 16802ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * 3. default adjust, which means adjust according to the following rules 16812ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * 3.1 always adjust string, such as MMM and MMMM 16822ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * 3.2 never adjust between string and numeric, such as MM and MMM 16832ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * 3.3 always adjust year 16842ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * 3.4 do not adjust 'd', 'h', or 'm' if h presents 16852ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * 3.5 do not adjust 'M' if it is numeric(?) 16862ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * 16872ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * Since date interval format is well-formed format, 16882ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * date and time skeletons are normalized previously, 16892ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * till this stage, the adjust here is only "adjust strings, such as MMM 16902ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * and MMMM, EEE and EEEE. 16912ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * 16922ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * @param inputSkeleton the input skeleton 16932ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * @param bestMatchSkeleton the best match skeleton 16942ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * @param bestMatchIntervalpattern the best match interval pattern 16952ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * @param differenceInfo the difference between 2 skeletons 16962ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * 1 means only field width differs 16972ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * 2 means v/z exchange 16982ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * @return the adjusted interval pattern 16992ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller */ 17002ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller private static String adjustFieldWidth(String inputSkeleton, 17012ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller String bestMatchSkeleton, 17022ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller String bestMatchIntervalPattern, 17032ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller int differenceInfo ) { 17042ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller 17052ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller if ( bestMatchIntervalPattern == null ) { 17062ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller return null; // the 2nd part could be null 17072ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } 17082ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller int[] inputSkeletonFieldWidth = new int[58]; 17092ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller int[] bestMatchSkeletonFieldWidth = new int[58]; 17102ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller 17112ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller /* initialize as following 17122ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller { 17132ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller // A B C D E F G H I J K L M N O 17142ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 17152ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller // P Q R S T U V W X Y Z 17162ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 17172ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller // a b c d e f g h i j k l m n o 17182ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 17192ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller // p q r s t u v w x y z 17202ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 17212ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller }; 17222ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller */ 17232ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller 17242ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller 17252ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller DateIntervalInfo.parseSkeleton(inputSkeleton, inputSkeletonFieldWidth); 17262ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller DateIntervalInfo.parseSkeleton(bestMatchSkeleton, bestMatchSkeletonFieldWidth); 17272ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller if ( differenceInfo == 2 ) { 17282ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller bestMatchIntervalPattern = bestMatchIntervalPattern.replace('v', 'z'); 17292ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } 17302ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller 17312ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller StringBuilder adjustedPtn = new StringBuilder(bestMatchIntervalPattern); 17322ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller 17332ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller boolean inQuote = false; 17342ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller char prevCh = 0; 17352ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller int count = 0; 17362ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller 17372ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller int PATTERN_CHAR_BASE = 0x41; 17382ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller 17392ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller // loop through the pattern string character by character 17402ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller int adjustedPtnLength = adjustedPtn.length(); 17412ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller for (int i = 0; i < adjustedPtnLength; ++i) { 17422ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller char ch = adjustedPtn.charAt(i); 17432ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller if (ch != prevCh && count > 0) { 17442ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller // check the repeativeness of pattern letter 17452ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller char skeletonChar = prevCh; 17462ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller if ( skeletonChar == 'L' ) { 17472ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller // for skeleton "M+", the pattern is "...L..." 17482ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller skeletonChar = 'M'; 17492ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } 17502ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller int fieldCount = bestMatchSkeletonFieldWidth[skeletonChar - PATTERN_CHAR_BASE]; 17512ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller int inputFieldCount = inputSkeletonFieldWidth[skeletonChar - PATTERN_CHAR_BASE]; 17522ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller if ( fieldCount == count && inputFieldCount > fieldCount ) { 17532ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller count = inputFieldCount - fieldCount; 17542ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller for ( int j = 0; j < count; ++j ) { 17552ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller adjustedPtn.insert(i, prevCh); 17562ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } 17572ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller i += count; 17582ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller adjustedPtnLength += count; 17592ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } 17602ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller count = 0; 17612ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } 17622ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller if (ch == '\'') { 17632ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller // Consecutive single quotes are a single quote literal, 17642ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller // either outside of quotes or between quotes 17652ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller if ((i+1) < adjustedPtn.length() && adjustedPtn.charAt(i+1) == '\'') { 17662ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller ++i; 17672ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } else { 17682ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller inQuote = ! inQuote; 17692ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } 17702ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } 17712ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller else if ( ! inQuote && ((ch >= 0x0061 /*'a'*/ && ch <= 0x007A /*'z'*/) 17722ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller || (ch >= 0x0041 /*'A'*/ && ch <= 0x005A /*'Z'*/))) { 17732ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller // ch is a date-time pattern character 17742ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller prevCh = ch; 17752ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller ++count; 17762ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } 17772ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } 17782ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller if ( count > 0 ) { 17792ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller // last item 17802ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller // check the repeativeness of pattern letter 17812ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller char skeletonChar = prevCh; 17822ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller if ( skeletonChar == 'L' ) { 17832ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller // for skeleton "M+", the pattern is "...L..." 17842ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller skeletonChar = 'M'; 17852ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } 17862ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller int fieldCount = bestMatchSkeletonFieldWidth[skeletonChar - PATTERN_CHAR_BASE]; 17872ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller int inputFieldCount = inputSkeletonFieldWidth[skeletonChar - PATTERN_CHAR_BASE]; 17882ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller if ( fieldCount == count && inputFieldCount > fieldCount ) { 17892ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller count = inputFieldCount - fieldCount; 17902ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller for ( int j = 0; j < count; ++j ) { 17912ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller adjustedPtn.append(prevCh); 17922ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } 17932ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } 17942ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } 17952ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller return adjustedPtn.toString(); 17962ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } 17972ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller 17982ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller 17992ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller /* 18002ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * Concat a single date pattern with a time interval pattern, 18012ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * set it into the intervalPatterns, while field is time field. 18022ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * This is used to handle time interval patterns on skeleton with 18032ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * both time and date. Present the date followed by 18042ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * the range expression for the time. 18052ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * @param dtfmt date and time format 18062ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * @param datePattern date pattern 18072ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * @param field time calendar field: AM_PM, HOUR, MINUTE 18082ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * @param intervalPatterns interval patterns 18092ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller */ 18102ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller private void concatSingleDate2TimeInterval(String dtfmt, 18112ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller String datePattern, 18122ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller int field, 18132ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller Map<String, PatternInfo> intervalPatterns) 18142ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller { 18152ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller 18162ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller PatternInfo timeItvPtnInfo = 18172ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller intervalPatterns.get(DateIntervalInfo.CALENDAR_FIELD_TO_PATTERN_LETTER[field]); 18182ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller if ( timeItvPtnInfo != null ) { 18192ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller String timeIntervalPattern = timeItvPtnInfo.getFirstPart() + 18202ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller timeItvPtnInfo.getSecondPart(); 18211c8a530973739aafa823d758240d2cd5dad96fe3Fredrik Roubert String pattern = SimpleFormatterImpl.formatRawPattern( 18221c8a530973739aafa823d758240d2cd5dad96fe3Fredrik Roubert dtfmt, 2, 2, timeIntervalPattern, datePattern); 18232ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller timeItvPtnInfo = DateIntervalInfo.genPatternInfo(pattern, 18242ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller timeItvPtnInfo.firstDateInPtnIsLaterDate()); 18252ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller intervalPatterns.put( 18262ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller DateIntervalInfo.CALENDAR_FIELD_TO_PATTERN_LETTER[field], timeItvPtnInfo); 18272ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } 18282ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller // else: fall back 18292ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller // it should not happen if the interval format defined is valid 18302ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } 18312ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller 18322ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller 18332ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller /* 18342ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * check whether a calendar field present in a skeleton. 18352ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * @param field calendar field need to check 18362ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * @param skeleton given skeleton on which to check the calendar field 18372ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * @return true if field present in a skeleton. 18382ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller */ 18392ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller private static boolean fieldExistsInSkeleton(int field, String skeleton) 18402ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller { 18412ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller String fieldChar = DateIntervalInfo.CALENDAR_FIELD_TO_PATTERN_LETTER[field]; 18422ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller return ( (skeleton.indexOf(fieldChar) == -1) ? false : true ) ; 18432ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } 18442ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller 18452ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller 18462ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller /* 18472ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * readObject. 18482ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller */ 18492ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller private void readObject(ObjectInputStream stream) 18502ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller throws IOException, ClassNotFoundException { 18512ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller stream.defaultReadObject(); 18522ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller initializePattern(isDateIntervalInfoDefault ? LOCAL_PATTERN_CACHE : null); 18532ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } 18542ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller 18552ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller /** 18562ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * Get the internal patterns for the skeleton 18572ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * @deprecated This API is ICU internal only. 185893cf604e9dd0525f15bc0a7450b2a35f3884c298Neil Fuller * @hide original deprecated declaration 1859836e6b40a94ec3fb7545a76cb072960442b7eee9Neil Fuller * @hide draft / provisional / internal are hidden on Android 18602ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller */ 18612ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller @Deprecated 18622ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller public Map<String, PatternInfo> getRawPatterns() { 18632ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller // this is unmodifiable, so ok to return directly 18642ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller return fIntervalPatterns; 18652ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } 18662ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller} 1867