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/* 52ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller ******************************************************************************* 61c8a530973739aafa823d758240d2cd5dad96fe3Fredrik Roubert * Copyright (C) 1996-2016, International Business Machines Corporation and 72ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * others. All Rights Reserved. 82ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller ******************************************************************************* 92ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller */ 102ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller 112ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fullerpackage android.icu.text; 122ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller 132ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fullerimport java.io.IOException; 142ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fullerimport java.io.ObjectInputStream; 152ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fullerimport java.io.ObjectOutputStream; 162ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fullerimport java.text.AttributedCharacterIterator; 172ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fullerimport java.text.AttributedString; 182ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fullerimport java.text.FieldPosition; 192ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fullerimport java.text.Format; 202ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fullerimport java.text.ParsePosition; 212ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fullerimport java.util.ArrayList; 222ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fullerimport java.util.Date; 232ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fullerimport java.util.HashMap; 242ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fullerimport java.util.List; 252ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fullerimport java.util.Locale; 262ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fullerimport java.util.MissingResourceException; 272ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fullerimport java.util.UUID; 282ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller 292ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fullerimport android.icu.impl.DateNumberFormat; 301c8a530973739aafa823d758240d2cd5dad96fe3Fredrik Roubertimport android.icu.impl.DayPeriodRules; 312ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fullerimport android.icu.impl.ICUCache; 32f86f25d102340da66b9c7cb6b2d5ecdc0de43ecfFredrik Roubertimport android.icu.impl.ICUData; 33f86f25d102340da66b9c7cb6b2d5ecdc0de43ecfFredrik Roubertimport android.icu.impl.ICUResourceBundle; 342ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fullerimport android.icu.impl.PatternProps; 352ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fullerimport android.icu.impl.SimpleCache; 361c8a530973739aafa823d758240d2cd5dad96fe3Fredrik Roubertimport android.icu.impl.SimpleFormatterImpl; 372ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fullerimport android.icu.lang.UCharacter; 382ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fullerimport android.icu.text.TimeZoneFormat.Style; 392ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fullerimport android.icu.text.TimeZoneFormat.TimeType; 402ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fullerimport android.icu.util.BasicTimeZone; 412ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fullerimport android.icu.util.Calendar; 422ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fullerimport android.icu.util.HebrewCalendar; 432ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fullerimport android.icu.util.Output; 442ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fullerimport android.icu.util.TimeZone; 452ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fullerimport android.icu.util.TimeZoneTransition; 462ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fullerimport android.icu.util.ULocale; 472ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fullerimport android.icu.util.ULocale.Category; 48f86f25d102340da66b9c7cb6b2d5ecdc0de43ecfFredrik Roubertimport android.icu.util.UResourceBundle; 49f86f25d102340da66b9c7cb6b2d5ecdc0de43ecfFredrik Roubert 502ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller 512ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller 522ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller/** 531537b2f39245c07b00aa78c3600f7aebcb172490Neil Fuller * <strong>[icu enhancement]</strong> ICU's replacement for {@link java.text.SimpleDateFormat}. Methods, fields, and other functionality specific to ICU are labeled '<strong>[icu]</strong>'. 542ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * 552ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * <p><code>SimpleDateFormat</code> is a concrete class for formatting and 562ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * parsing dates in a locale-sensitive manner. It allows for formatting 5708ae9f2909b2ec37f755dac4372553437e9d7cf6Paul Duffin * (date -> text), parsing (text -> date), and normalization. 582ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * 592ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * <p> 602ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * <code>SimpleDateFormat</code> allows you to start by choosing 612ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * any user-defined patterns for date-time formatting. However, you 622ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * are encouraged to create a date-time formatter with either 632ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * <code>getTimeInstance</code>, <code>getDateInstance</code>, or 642ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * <code>getDateTimeInstance</code> in <code>DateFormat</code>. Each 652ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * of these class methods can return a date/time formatter initialized 662ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * with a default format pattern. You may modify the format pattern 672ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * using the <code>applyPattern</code> methods as desired. 682ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * For more information on using these methods, see 692ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * {@link DateFormat}. 702ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * 712ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * <p><strong>Date and Time Patterns:</strong></p> 722ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * 732ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * <p>Date and time formats are specified by <em>date and time pattern</em> strings. 742ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * Within date and time pattern strings, all unquoted ASCII letters [A-Za-z] are reserved 752ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * as pattern letters representing calendar fields. <code>SimpleDateFormat</code> supports 762ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * the date and time formatting algorithm and pattern letters defined by <a href="http://www.unicode.org/reports/tr35/">UTS#35 772ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * Unicode Locale Data Markup Language (LDML)</a>. The following pattern letters are 782ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * currently available (note that the actual values depend on CLDR and may change from the 792ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * examples shown here):</p> 802ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * <blockquote> 812ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * <table border="1"> 822ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * <tr> 832ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * <th>Field</th> 842ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * <th style="text-align: center">Sym.</th> 852ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * <th style="text-align: center">No.</th> 862ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * <th>Example</th> 872ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * <th>Description</th> 882ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * </tr> 892ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * <tr> 902ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * <th rowspan="3">era</th> 912ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * <td style="text-align: center" rowspan="3">G</td> 922ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * <td style="text-align: center">1..3</td> 932ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * <td>AD</td> 941c8a530973739aafa823d758240d2cd5dad96fe3Fredrik Roubert * <td rowspan="3">Era - Replaced with the Era string for the current date. One to three letters for the 952ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * abbreviated form, four letters for the long (wide) form, five for the narrow form.</td> 962ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * </tr> 972ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * <tr> 982ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * <td style="text-align: center">4</td> 992ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * <td>Anno Domini</td> 1002ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * </tr> 1012ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * <tr> 1022ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * <td style="text-align: center">5</td> 1032ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * <td>A</td> 1042ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * </tr> 1052ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * <tr> 1062ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * <th rowspan="6">year</th> 1072ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * <td style="text-align: center">y</td> 1082ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * <td style="text-align: center">1..n</td> 1092ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * <td>1996</td> 1102ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * <td>Year. Normally the length specifies the padding, but for two letters it also specifies the maximum 11108ae9f2909b2ec37f755dac4372553437e9d7cf6Paul Duffin * length. Example:<div style="text-align: center"> 1122ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * <center> 1132ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * <table border="1" cellpadding="2" cellspacing="0"> 1142ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * <tr> 1152ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * <th>Year</th> 1162ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * <th style="text-align: right">y</th> 1172ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * <th style="text-align: right">yy</th> 1182ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * <th style="text-align: right">yyy</th> 1192ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * <th style="text-align: right">yyyy</th> 1202ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * <th style="text-align: right">yyyyy</th> 1212ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * </tr> 1222ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * <tr> 1232ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * <td>AD 1</td> 1242ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * <td style="text-align: right">1</td> 1252ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * <td style="text-align: right">01</td> 1262ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * <td style="text-align: right">001</td> 1272ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * <td style="text-align: right">0001</td> 1282ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * <td style="text-align: right">00001</td> 1292ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * </tr> 1302ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * <tr> 1312ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * <td>AD 12</td> 1322ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * <td style="text-align: right">12</td> 1332ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * <td style="text-align: right">12</td> 1342ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * <td style="text-align: right">012</td> 1352ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * <td style="text-align: right">0012</td> 1362ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * <td style="text-align: right">00012</td> 1372ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * </tr> 1382ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * <tr> 1392ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * <td>AD 123</td> 1402ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * <td style="text-align: right">123</td> 1412ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * <td style="text-align: right">23</td> 1422ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * <td style="text-align: right">123</td> 1432ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * <td style="text-align: right">0123</td> 1442ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * <td style="text-align: right">00123</td> 1452ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * </tr> 1462ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * <tr> 1472ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * <td>AD 1234</td> 1482ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * <td style="text-align: right">1234</td> 1492ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * <td style="text-align: right">34</td> 1502ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * <td style="text-align: right">1234</td> 1512ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * <td style="text-align: right">1234</td> 1522ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * <td style="text-align: right">01234</td> 1532ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * </tr> 1542ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * <tr> 1552ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * <td>AD 12345</td> 1562ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * <td style="text-align: right">12345</td> 1572ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * <td style="text-align: right">45</td> 1582ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * <td style="text-align: right">12345</td> 1592ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * <td style="text-align: right">12345</td> 1602ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * <td style="text-align: right">12345</td> 1612ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * </tr> 1622ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * </table> 1632ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * </center></div> 1642ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * </td> 1652ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * </tr> 1662ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * <tr> 1672ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * <td style="text-align: center">Y</td> 1682ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * <td style="text-align: center">1..n</td> 1692ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * <td>1997</td> 1702ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * <td>Year (in "Week of Year" based calendars). Normally the length specifies the padding, 1712ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * but for two letters it also specifies the maximum length. This year designation is used in ISO 1722ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * year-week calendar as defined by ISO 8601, but can be used in non-Gregorian based calendar systems 1732ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * where week date processing is desired. May not always be the same value as calendar year.</td> 1742ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * </tr> 1752ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * <tr> 1762ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * <td style="text-align: center">u</td> 1772ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * <td style="text-align: center">1..n</td> 1782ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * <td>4601</td> 1792ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * <td>Extended year. This is a single number designating the year of this calendar system, encompassing 1802ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * all supra-year fields. For example, for the Julian calendar system, year numbers are positive, with an 1812ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * era of BCE or CE. An extended year value for the Julian calendar system assigns positive values to CE 1822ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * years and negative values to BCE years, with 1 BCE being year 0.</td> 1832ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * </tr> 1842ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * <tr> 1852ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * <td style="text-align: center" rowspan="3">U</td> 1862ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * <td style="text-align: center">1..3</td> 1872ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * <td>甲子</td> 1882ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * <td rowspan="3">Cyclic year name. Calendars such as the Chinese lunar calendar (and related calendars) 1892ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * and the Hindu calendars use 60-year cycles of year names. Use one through three letters for the abbreviated 1902ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * name, four for the full (wide) name, or five for the narrow name (currently the data only provides abbreviated names, 1912ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * which will be used for all requested name widths). If the calendar does not provide cyclic year name data, 1922ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * or if the year value to be formatted is out of the range of years for which cyclic name data is provided, 1932ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * then numeric formatting is used (behaves like 'y').</td> 1942ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * </tr> 1952ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * <tr> 1962ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * <td style="text-align: center">4</td> 1972ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * <td>(currently also 甲子)</td> 1982ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * </tr> 1992ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * <tr> 2002ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * <td style="text-align: center">5</td> 2012ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * <td>(currently also 甲子)</td> 2022ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * </tr> 2032ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * <tr> 2042ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * <th rowspan="6">quarter</th> 2052ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * <td rowspan="3" style="text-align: center">Q</td> 2062ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * <td style="text-align: center">1..2</td> 2072ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * <td>02</td> 2081c8a530973739aafa823d758240d2cd5dad96fe3Fredrik Roubert * <td rowspan="3">Quarter - Use one or two for the numerical quarter, three for the abbreviation, or four 2092ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * for the full (wide) name (five for the narrow name is not yet supported).</td> 2102ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * </tr> 2112ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * <tr> 2122ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * <td style="text-align: center">3</td> 2132ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * <td>Q2</td> 2142ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * </tr> 2152ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * <tr> 2162ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * <td style="text-align: center">4</td> 2172ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * <td>2nd quarter</td> 2182ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * </tr> 2192ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * <tr> 2202ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * <td rowspan="3" style="text-align: center">q</td> 2212ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * <td style="text-align: center">1..2</td> 2222ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * <td>02</td> 2231c8a530973739aafa823d758240d2cd5dad96fe3Fredrik Roubert * <td rowspan="3"><b>Stand-Alone</b> Quarter - Use one or two for the numerical quarter, three for the abbreviation, 2242ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * or four for the full name (five for the narrow name is not yet supported).</td> 2252ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * </tr> 2262ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * <tr> 2272ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * <td style="text-align: center">3</td> 2282ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * <td>Q2</td> 2292ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * </tr> 2302ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * <tr> 2312ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * <td style="text-align: center">4</td> 2322ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * <td>2nd quarter</td> 2332ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * </tr> 2342ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * <tr> 2352ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * <th rowspan="8">month</th> 2362ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * <td rowspan="4" style="text-align: center">M</td> 2372ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * <td style="text-align: center">1..2</td> 2382ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * <td>09</td> 2392ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * <td rowspan="4">Month - Use one or two for the numerical month, three for the abbreviation, four for 2402ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * the full (wide) name, or five for the narrow name. With two ("MM"), the month number is zero-padded 2412ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * if necessary (e.g. "08").</td> 2422ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * </tr> 2432ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * <tr> 2442ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * <td style="text-align: center">3</td> 2452ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * <td>Sep</td> 2462ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * </tr> 2472ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * <tr> 2482ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * <td style="text-align: center">4</td> 2492ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * <td>September</td> 2502ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * </tr> 2512ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * <tr> 2522ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * <td style="text-align: center">5</td> 2532ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * <td>S</td> 2542ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * </tr> 2552ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * <tr> 2562ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * <td rowspan="4" style="text-align: center">L</td> 2572ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * <td style="text-align: center">1..2</td> 2582ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * <td>09</td> 2591c8a530973739aafa823d758240d2cd5dad96fe3Fredrik Roubert * <td rowspan="4"><b>Stand-Alone</b> Month - Use one or two for the numerical month, three for the abbreviation, 2602ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * four for the full (wide) name, or 5 for the narrow name. With two ("LL"), the month number is zero-padded if 2612ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * necessary (e.g. "08").</td> 2622ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * </tr> 2632ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * <tr> 2642ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * <td style="text-align: center">3</td> 2652ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * <td>Sep</td> 2662ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * </tr> 2672ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * <tr> 2682ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * <td style="text-align: center">4</td> 2692ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * <td>September</td> 2702ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * </tr> 2712ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * <tr> 2722ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * <td style="text-align: center">5</td> 2732ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * <td>S</td> 2742ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * </tr> 2752ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * <tr> 2762ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * <th rowspan="2">week</th> 2772ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * <td style="text-align: center">w</td> 2782ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * <td style="text-align: center">1..2</td> 2792ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * <td>27</td> 2802ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * <td>Week of Year. Use "w" to show the minimum number of digits, or "ww" to always show two digits 2812ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * (zero-padding if necessary, e.g. "08").</td> 2822ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * </tr> 2832ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * <tr> 2842ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * <td style="text-align: center">W</td> 2852ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * <td style="text-align: center">1</td> 2862ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * <td>3</td> 2872ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * <td>Week of Month</td> 2882ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * </tr> 2892ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * <tr> 2902ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * <th rowspan="4">day</th> 2912ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * <td style="text-align: center">d</td> 2922ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * <td style="text-align: center">1..2</td> 2932ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * <td>1</td> 2942ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * <td>Date - Day of the month. Use "d" to show the minimum number of digits, or "dd" to always show 2952ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * two digits (zero-padding if necessary, e.g. "08").</td> 2962ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * </tr> 2972ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * <tr> 2982ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * <td style="text-align: center">D</td> 2992ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * <td style="text-align: center">1..3</td> 3002ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * <td>345</td> 3012ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * <td>Day of year</td> 3022ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * </tr> 3032ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * <tr> 3042ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * <td style="text-align: center">F</td> 3052ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * <td style="text-align: center">1</td> 3062ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * <td>2</td> 3072ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * <td>Day of Week in Month. The example is for the 2nd Wed in July</td> 3082ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * </tr> 3092ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * <tr> 3102ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * <td style="text-align: center">g</td> 3112ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * <td style="text-align: center">1..n</td> 3122ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * <td>2451334</td> 3132ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * <td>Modified Julian day. This is different from the conventional Julian day number in two regards. 3142ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * First, it demarcates days at local zone midnight, rather than noon GMT. Second, it is a local number; 3151c8a530973739aafa823d758240d2cd5dad96fe3Fredrik Roubert * that is, it depends on the local time zone. It can be thought of as a single number that encompasses 3162ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * all the date-related fields.</td> 3172ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * </tr> 3182ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * <tr> 3192ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * <th rowspan="14">week<br> 3202ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * day</th> 3212ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * <td rowspan="4" style="text-align: center">E</td> 3222ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * <td style="text-align: center">1..3</td> 3232ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * <td>Tue</td> 3241c8a530973739aafa823d758240d2cd5dad96fe3Fredrik Roubert * <td rowspan="4">Day of week - Use one through three letters for the short day, four for the full (wide) name, 3252ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * five for the narrow name, or six for the short name.</td> 3262ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * </tr> 3272ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * <tr> 3282ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * <td style="text-align: center">4</td> 3292ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * <td>Tuesday</td> 3302ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * </tr> 3312ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * <tr> 3322ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * <td style="text-align: center">5</td> 3332ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * <td>T</td> 3342ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * </tr> 3352ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * <tr> 3362ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * <td style="text-align: center">6</td> 3372ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * <td>Tu</td> 3382ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * </tr> 3392ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * <tr> 3402ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * <td rowspan="5" style="text-align: center">e</td> 3412ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * <td style="text-align: center">1..2</td> 3422ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * <td>2</td> 3432ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * <td rowspan="5">Local day of week. Same as E except adds a numeric value that will depend on the local 3442ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * starting day of the week, using one or two letters. For this example, Monday is the first day of the week.</td> 3452ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * </tr> 3462ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * <tr> 3472ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * <td style="text-align: center">3</td> 3482ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * <td>Tue</td> 3492ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * </tr> 3502ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * <tr> 3512ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * <td style="text-align: center">4</td> 3522ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * <td>Tuesday</td> 3532ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * </tr> 3542ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * <tr> 3552ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * <td style="text-align: center">5</td> 3562ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * <td>T</td> 3572ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * </tr> 3582ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * <tr> 3592ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * <td style="text-align: center">6</td> 3602ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * <td>Tu</td> 3612ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * </tr> 3622ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * <tr> 3632ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * <td rowspan="5" style="text-align: center">c</td> 3642ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * <td style="text-align: center">1</td> 3652ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * <td>2</td> 3662ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * <td rowspan="5"><b>Stand-Alone</b> local day of week - Use one letter for the local numeric value (same 3672ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * as 'e'), three for the short day, four for the full (wide) name, five for the narrow name, or six for 3682ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * the short name.</td> 3692ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * </tr> 3702ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * <tr> 3712ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * <td style="text-align: center">3</td> 3722ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * <td>Tue</td> 3732ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * </tr> 3742ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * <tr> 3752ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * <td style="text-align: center">4</td> 3762ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * <td>Tuesday</td> 3772ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * </tr> 3782ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * <tr> 3792ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * <td style="text-align: center">5</td> 3802ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * <td>T</td> 3812ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * </tr> 3822ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * <tr> 3832ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * <td style="text-align: center">6</td> 3842ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * <td>Tu</td> 3852ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * </tr> 3862ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * <tr> 3872ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * <th>period</th> 3882ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * <td style="text-align: center">a</td> 3892ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * <td style="text-align: center">1</td> 3902ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * <td>AM</td> 3912ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * <td>AM or PM</td> 3922ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * </tr> 3932ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * <tr> 3942ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * <th rowspan="4">hour</th> 3952ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * <td style="text-align: center">h</td> 3962ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * <td style="text-align: center">1..2</td> 3972ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * <td>11</td> 3982ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * <td>Hour [1-12]. When used in skeleton data or in a skeleton passed in an API for flexible data pattern 3992ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * generation, it should match the 12-hour-cycle format preferred by the locale (h or K); it should not match 4002ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * a 24-hour-cycle format (H or k). Use hh for zero padding.</td> 4012ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * </tr> 4022ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * <tr> 4032ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * <td style="text-align: center">H</td> 4042ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * <td style="text-align: center">1..2</td> 4052ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * <td>13</td> 4062ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * <td>Hour [0-23]. When used in skeleton data or in a skeleton passed in an API for flexible data pattern 4072ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * generation, it should match the 24-hour-cycle format preferred by the locale (H or k); it should not match a 4082ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * 12-hour-cycle format (h or K). Use HH for zero padding.</td> 4092ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * </tr> 4102ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * <tr> 4112ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * <td style="text-align: center">K</td> 4122ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * <td style="text-align: center">1..2</td> 4132ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * <td>0</td> 4142ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * <td>Hour [0-11]. When used in a skeleton, only matches K or h, see above. Use KK for zero padding.</td> 4152ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * </tr> 4162ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * <tr> 4172ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * <td style="text-align: center">k</td> 4182ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * <td style="text-align: center">1..2</td> 4192ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * <td>24</td> 4202ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * <td>Hour [1-24]. When used in a skeleton, only matches k or H, see above. Use kk for zero padding.</td> 4212ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * </tr> 4222ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * <tr> 4232ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * <th>minute</th> 4242ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * <td style="text-align: center">m</td> 4252ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * <td style="text-align: center">1..2</td> 4262ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * <td>59</td> 4272ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * <td>Minute. Use "m" to show the minimum number of digits, or "mm" to always show two digits 4282ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * (zero-padding if necessary, e.g. "08")..</td> 4292ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * </tr> 4302ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * <tr> 4312ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * <th rowspan="3">second</th> 4322ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * <td style="text-align: center">s</td> 4332ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * <td style="text-align: center">1..2</td> 4342ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * <td>12</td> 4352ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * <td>Second. Use "s" to show the minimum number of digits, or "ss" to always show two digits 4362ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * (zero-padding if necessary, e.g. "08").</td> 4372ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * </tr> 4382ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * <tr> 4392ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * <td style="text-align: center">S</td> 4402ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * <td style="text-align: center">1..n</td> 4412ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * <td>3450</td> 4422ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * <td>Fractional Second - truncates (like other time fields) to the count of letters when formatting. Appends zeros if more than 3 letters specified. Truncates at three significant digits when parsing. 4432ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * (example shows display using pattern SSSS for seconds value 12.34567)</td> 4442ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * </tr> 4452ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * <tr> 4462ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * <td style="text-align: center">A</td> 4472ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * <td style="text-align: center">1..n</td> 4482ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * <td>69540000</td> 4492ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * <td>Milliseconds in day. This field behaves <i>exactly</i> like a composite of all time-related fields, 4502ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * not including the zone fields. As such, it also reflects discontinuities of those fields on DST transition 4512ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * days. On a day of DST onset, it will jump forward. On a day of DST cessation, it will jump backward. This 4522ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * reflects the fact that is must be combined with the offset field to obtain a unique local time value.</td> 4532ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * </tr> 4542ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * <tr> 4552ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * <th rowspan="23">zone</th> 4562ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * <td rowspan="2" style="text-align: center">z</td> 4572ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * <td style="text-align: center">1..3</td> 4582ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * <td>PDT</td> 4592ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * <td>The <i>short specific non-location format</i>. 4602ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * Where that is unavailable, falls back to the <i>short localized GMT format</i> ("O").</td> 4612ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * </tr> 4622ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * <tr> 4632ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * <td style="text-align: center">4</td> 4642ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * <td>Pacific Daylight Time</td> 4652ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * <td>The <i>long specific non-location format</i>. 4662ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * Where that is unavailable, falls back to the <i>long localized GMT format</i> ("OOOO").</td> 4672ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * </tr> 4682ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * <tr> 4692ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * <td rowspan="3" style="text-align: center">Z</td> 4702ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * <td style="text-align: center">1..3</td> 4712ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * <td>-0800</td> 4722ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * <td>The <i>ISO8601 basic format</i> with hours, minutes and optional seconds fields. 4732ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * The format is equivalent to RFC 822 zone format (when optional seconds field is absent). 4742ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * This is equivalent to the "xxxx" specifier.</td> 4752ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * </tr> 4762ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * <tr> 4772ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * <td style="text-align: center">4</td> 4782ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * <td>GMT-8:00</td> 4792ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * <td>The <i>long localized GMT format</i>. 4802ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * This is equivalent to the "OOOO" specifier.</td> 4812ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * </tr> 4822ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * <tr> 4832ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * <td style="text-align: center">5</td> 4842ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * <td>-08:00<br> 4852ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * -07:52:58</td> 4862ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * <td>The <i>ISO8601 extended format</i> with hours, minutes and optional seconds fields. 4872ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * The ISO8601 UTC indicator "Z" is used when local time offset is 0. 4882ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * This is equivalent to the "XXXXX" specifier.</td> 4892ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * </tr> 4902ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * <tr> 4912ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * <td rowspan="2" style="text-align: center">O</td> 4922ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * <td style="text-align: center">1</td> 4932ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * <td>GMT-8</td> 4942ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * <td>The <i>short localized GMT format</i>.</td> 4952ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * </tr> 4962ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * <tr> 4972ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * <td style="text-align: center">4</td> 4982ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * <td>GMT-08:00</td> 4992ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * <td>The <i>long localized GMT format</i>.</td> 5002ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * </tr> 5012ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * <tr> 5022ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * <td rowspan="2" style="text-align: center">v</td> 5032ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * <td style="text-align: center">1</td> 5042ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * <td>PT</td> 5052ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * <td>The <i>short generic non-location format</i>. 5062ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * Where that is unavailable, falls back to the <i>generic location format</i> ("VVVV"), 5072ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * then the <i>short localized GMT format</i> as the final fallback.</td> 5082ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * </tr> 5092ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * <tr> 5102ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * <td style="text-align: center">4</td> 5112ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * <td>Pacific Time</td> 5122ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * <td>The <i>long generic non-location format</i>. 5132ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * Where that is unavailable, falls back to <i>generic location format</i> ("VVVV"). 5142ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * </tr> 5152ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * <tr> 5162ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * <td rowspan="4" style="text-align: center">V</td> 5172ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * <td style="text-align: center">1</td> 5182ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * <td>uslax</td> 5192ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * <td>The short time zone ID. 5202ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * Where that is unavailable, the special short time zone ID <i>unk</i> (Unknown Zone) is used.<br> 5212ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * <i><b>Note</b>: This specifier was originally used for a variant of the short specific non-location format, 5222ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * but it was deprecated in the later version of the LDML specification. In CLDR 23/ICU 51, the definition of 5232ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * the specifier was changed to designate a short time zone ID.</i></td> 5242ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * </tr> 5252ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * <tr> 5262ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * <td style="text-align: center">2</td> 5272ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * <td>America/Los_Angeles</td> 5282ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * <td>The long time zone ID.</td> 5292ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * </tr> 5302ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * <tr> 5312ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * <td style="text-align: center">3</td> 5322ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * <td>Los Angeles</td> 5332ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * <td>The exemplar city (location) for the time zone. 5342ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * Where that is unavailable, the localized exemplar city name for the special zone <i>Etc/Unknown</i> is used 5352ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * as the fallback (for example, "Unknown City"). </td> 5362ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * </tr> 5372ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * <tr> 5382ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * <td style="text-align: center">4</td> 5392ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * <td>Los Angeles Time</td> 5402ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * <td>The <i>generic location format</i>. 5412ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * Where that is unavailable, falls back to the <i>long localized GMT format</i> ("OOOO"; 5422ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * Note: Fallback is only necessary with a GMT-style Time Zone ID, like Etc/GMT-830.)<br> 5431c8a530973739aafa823d758240d2cd5dad96fe3Fredrik Roubert * This is especially useful when presenting possible timezone choices for user selection, 5442ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * since the naming is more uniform than the "v" format.</td> 5452ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * </tr> 5462ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * <tr> 5472ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * <td rowspan="5" style="text-align: center">X</td> 5482ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * <td style="text-align: center">1</td> 5492ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * <td>-08<br> 5502ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * +0530<br> 5512ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * Z</td> 5522ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * <td>The <i>ISO8601 basic format</i> with hours field and optional minutes field. 5532ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * The ISO8601 UTC indicator "Z" is used when local time offset is 0.</td> 5542ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * </tr> 5552ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * <tr> 5562ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * <td style="text-align: center">2</td> 5572ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * <td>-0800<br> 5582ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * Z</td> 5592ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * <td>The <i>ISO8601 basic format</i> with hours and minutes fields. 5602ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * The ISO8601 UTC indicator "Z" is used when local time offset is 0.</td> 5612ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * </tr> 5622ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * <tr> 5632ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * <td style="text-align: center">3</td> 5642ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * <td>-08:00<br> 5652ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * Z</td> 5662ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * <td>The <i>ISO8601 extended format</i> with hours and minutes fields. 5672ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * The ISO8601 UTC indicator "Z" is used when local time offset is 0.</td> 5682ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * </tr> 5692ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * <tr> 5702ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * <td style="text-align: center">4</td> 5712ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * <td>-0800<br> 5722ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * -075258<br> 5732ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * Z</td> 5742ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * <td>The <i>ISO8601 basic format</i> with hours, minutes and optional seconds fields. 5752ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * (Note: The seconds field is not supported by the ISO8601 specification.) 5762ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * The ISO8601 UTC indicator "Z" is used when local time offset is 0.</td> 5772ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * </tr> 5782ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * <tr> 5792ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * <td style="text-align: center">5</td> 5802ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * <td>-08:00<br> 5812ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * -07:52:58<br> 5822ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * Z</td> 5832ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * <td>The <i>ISO8601 extended format</i> with hours, minutes and optional seconds fields. 5842ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * (Note: The seconds field is not supported by the ISO8601 specification.) 5852ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * The ISO8601 UTC indicator "Z" is used when local time offset is 0.</td> 5862ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * </tr> 5872ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * <tr> 5882ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * <td rowspan="5" style="text-align: center">x</td> 5892ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * <td style="text-align: center">1</td> 5902ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * <td>-08<br> 5912ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * +0530</td> 5922ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * <td>The <i>ISO8601 basic format</i> with hours field and optional minutes field.</td> 5932ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * </tr> 5942ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * <tr> 5952ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * <td style="text-align: center">2</td> 5962ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * <td>-0800</td> 5972ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * <td>The <i>ISO8601 basic format</i> with hours and minutes fields.</td> 5982ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * </tr> 5992ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * <tr> 6002ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * <td style="text-align: center">3</td> 6012ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * <td>-08:00</td> 6022ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * <td>The <i>ISO8601 extended format</i> with hours and minutes fields.</td> 6032ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * </tr> 6042ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * <tr> 6052ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * <td style="text-align: center">4</td> 6062ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * <td>-0800<br> 6072ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * -075258</td> 6082ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * <td>The <i>ISO8601 basic format</i> with hours, minutes and optional seconds fields. 6092ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * (Note: The seconds field is not supported by the ISO8601 specification.)</td> 6102ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * </tr> 6112ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * <tr> 6122ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * <td style="text-align: center">5</td> 6132ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * <td>-08:00<br> 6142ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * -07:52:58</td> 6152ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * <td>The <i>ISO8601 extended format</i> with hours, minutes and optional seconds fields. 6162ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * (Note: The seconds field is not supported by the ISO8601 specification.)</td> 6172ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * </tr> 6182ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * </table> 6191c8a530973739aafa823d758240d2cd5dad96fe3Fredrik Roubert * 6202ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * </blockquote> 6212ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * <p> 6222ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * Any characters in the pattern that are not in the ranges of ['a'..'z'] 6232ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * and ['A'..'Z'] will be treated as quoted text. For instance, characters 6242ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * like ':', '.', ' ', '#' and '@' will appear in the resulting time text 6252ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * even they are not embraced within single quotes. 6262ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * <p> 6272ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * A pattern containing any invalid pattern letter will result in a thrown 6282ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * exception during formatting or parsing. 6292ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * 6302ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * <p> 6312ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * <strong>Examples Using the US Locale:</strong> 6322ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * <blockquote> 6332ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * <pre> 6342ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * Format Pattern Result 6352ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * -------------- ------- 63608ae9f2909b2ec37f755dac4372553437e9d7cf6Paul Duffin * "yyyy.MM.dd G 'at' HH:mm:ss vvvv" ->> 1996.07.10 AD at 15:08:56 Pacific Time 63708ae9f2909b2ec37f755dac4372553437e9d7cf6Paul Duffin * "EEE, MMM d, ''yy" ->> Wed, July 10, '96 63808ae9f2909b2ec37f755dac4372553437e9d7cf6Paul Duffin * "h:mm a" ->> 12:08 PM 63908ae9f2909b2ec37f755dac4372553437e9d7cf6Paul Duffin * "hh 'o''clock' a, zzzz" ->> 12 o'clock PM, Pacific Daylight Time 64008ae9f2909b2ec37f755dac4372553437e9d7cf6Paul Duffin * "K:mm a, vvv" ->> 0:00 PM, PT 64108ae9f2909b2ec37f755dac4372553437e9d7cf6Paul Duffin * "yyyyy.MMMMM.dd GGG hh:mm aaa" ->> 01996.July.10 AD 12:08 PM 6422ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * </pre> 6432ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * </blockquote> 6442ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * <strong>Code Sample:</strong> 6452ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * <blockquote> 6462ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * <pre> 6472ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * SimpleTimeZone pdt = new SimpleTimeZone(-8 * 60 * 60 * 1000, "PST"); 6482ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * pdt.setStartRule(Calendar.APRIL, 1, Calendar.SUNDAY, 2*60*60*1000); 6492ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * pdt.setEndRule(Calendar.OCTOBER, -1, Calendar.SUNDAY, 2*60*60*1000); 6502ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * <br> 6512ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * // Format the current time. 6522ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * SimpleDateFormat formatter 6532ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * = new SimpleDateFormat ("yyyy.MM.dd G 'at' hh:mm:ss a zzz"); 6542ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * Date currentTime_1 = new Date(); 6552ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * String dateString = formatter.format(currentTime_1); 6562ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * <br> 6572ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * // Parse the previous string back into a Date. 6582ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * ParsePosition pos = new ParsePosition(0); 6592ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * Date currentTime_2 = formatter.parse(dateString, pos); 6602ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * </pre> 6612ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * </blockquote> 6622ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * In the example, the time value <code>currentTime_2</code> obtained from 6632ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * parsing will be equal to <code>currentTime_1</code>. However, they may not be 6642ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * equal if the am/pm marker 'a' is left out from the format pattern while 6652ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * the "hour in am/pm" pattern symbol is used. This information loss can 6662ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * happen when formatting the time in PM. 6672ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * 6682ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * <p>When parsing a date string using the abbreviated year pattern ("yy"), 6692ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * SimpleDateFormat must interpret the abbreviated year 6702ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * relative to some century. It does this by adjusting dates to be 6712ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * within 80 years before and 20 years after the time the SimpleDateFormat 6722ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * instance is created. For example, using a pattern of "MM/dd/yy" and a 6732ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * SimpleDateFormat instance created on Jan 1, 1997, the string 6742ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * "01/11/12" would be interpreted as Jan 11, 2012 while the string "05/04/64" 6752ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * would be interpreted as May 4, 1964. 6762ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * During parsing, only strings consisting of exactly two digits, as defined by 6772ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * {@link android.icu.lang.UCharacter#isDigit(int)}, will be parsed into the default 6782ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * century. 6792ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * Any other numeric string, such as a one digit string, a three or more digit 6802ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * string, or a two digit string that isn't all digits (for example, "-1"), is 6812ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * interpreted literally. So "01/02/3" or "01/02/003" are parsed, using the 6822ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * same pattern, as Jan 2, 3 AD. Likewise, "01/02/-3" is parsed as Jan 2, 4 BC. 6832ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * 6842ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * <p>If the year pattern does not have exactly two 'y' characters, the year is 6852ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * interpreted literally, regardless of the number of digits. So using the 6862ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * pattern "MM/dd/yyyy", "01/11/12" parses to Jan 11, 12 A.D. 6872ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * 6882ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * <p>When numeric fields abut one another directly, with no intervening delimiter 6892ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * characters, they constitute a run of abutting numeric fields. Such runs are 6902ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * parsed specially. For example, the format "HHmmss" parses the input text 6912ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * "123456" to 12:34:56, parses the input text "12345" to 1:23:45, and fails to 6922ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * parse "1234". In other words, the leftmost field of the run is flexible, 6932ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * while the others keep a fixed width. If the parse fails anywhere in the run, 6942ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * then the leftmost field is shortened by one character, and the entire run is 6952ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * parsed again. This is repeated until either the parse succeeds or the 6962ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * leftmost field is one character in length. If the parse still fails at that 6972ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * point, the parse of the run fails. 6982ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * 6992ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * <p>For time zones that have no names, use strings GMT+hours:minutes or 7002ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * GMT-hours:minutes. 7012ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * 7022ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * <p>The calendar defines what is the first day of the week, the first week 7032ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * of the year, whether hours are zero based or not (0 vs 12 or 24), and the 7042ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * time zone. There is one common decimal format to handle all the numbers; 7052ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * the digit count is handled programmatically according to the pattern. 7062ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * 70708ae9f2909b2ec37f755dac4372553437e9d7cf6Paul Duffin * <h3>Synchronization</h3> 7082ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * 7092ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * Date formats are not synchronized. It is recommended to create separate 7102ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * format instances for each thread. If multiple threads access a format 7112ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * concurrently, it must be synchronized externally. 7122ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * 7132ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * @see android.icu.util.Calendar 7142ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * @see android.icu.util.GregorianCalendar 7152ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * @see android.icu.util.TimeZone 7162ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * @see DateFormat 7172ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * @see DateFormatSymbols 7182ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * @see DecimalFormat 7192ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * @see TimeZoneFormat 7202ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * @author Mark Davis, Chen-Lieh Huang, Alan Liu 7212ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller */ 7222ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fullerpublic class SimpleDateFormat extends DateFormat { 7232ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller 7242ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller // the official serial version ID which says cryptically 7252ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller // which version we're compatible with 7262ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller private static final long serialVersionUID = 4774881970558875024L; 7272ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller 7282ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller // the internal serial version which says which version was written 7292ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller // - 0 (default) for version up to JDK 1.1.3 7302ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller // - 1 for version from JDK 1.1.4, which includes a new field 7312ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller // - 2 we write additional int for capitalizationSetting 7322ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller static final int currentSerialVersion = 2; 7332ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller 7342ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller static boolean DelayedHebrewMonthCheck = false; 7352ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller 7362ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller /* 7372ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * From calendar field to its level. 7382ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * Used to order calendar field. 7392ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * For example, calendar fields can be defined in the following order: 7402ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * year > month > date > am-pm > hour > minute 7412ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * YEAR --> 10, MONTH -->20, DATE --> 30; 7422ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * AM_PM -->40, HOUR --> 50, MINUTE -->60 7432ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller */ 7442ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller private static final int[] CALENDAR_FIELD_TO_LEVEL = 7452ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller { 7462ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller /*GyM*/ 0, 10, 20, 7472ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller /*wW*/ 20, 30, 7482ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller /*dDEF*/ 30, 20, 30, 30, 7492ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller /*ahHm*/ 40, 50, 50, 60, 7502ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller /*sS*/ 70, 80, 7512ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller /*z?Y*/ 0, 0, 10, 7522ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller /*eug*/ 30, 10, 0, 7532ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller /*A?*/ 40, 0, 0 7542ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller }; 7552ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller 7562ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller /* 7572ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * From calendar field letter to its level. 7582ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * Used to order calendar field. 7592ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * For example, calendar fields can be defined in the following order: 7602ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * year > month > date > am-pm > hour > minute 7612ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * 'y' --> 10, 'M' -->20, 'd' --> 30; 'a' -->40, 'h' --> 50, 'm' -->60 7622ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller */ 7632ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller private static final int[] PATTERN_CHAR_TO_LEVEL = 7642ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller { 7652ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 7662ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller // 7672ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 7682ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller // ! " # $ % & ' ( ) * + , - . / 7692ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 7702ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller // 0 1 2 3 4 5 6 7 8 9 : ; < = > ? 7712ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 7722ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller // @ A B C D E F G H I J K L M N O 7732ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller -1, 40, -1, -1, 20, 30, 30, 0, 50, -1, -1, 50, 20, 20, -1, 0, 7742ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller // P Q R S T U V W X Y Z [ \ ] ^ _ 7752ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller -1, 20, -1, 80, -1, 10, 0, 30, 0, 10, 0, -1, -1, -1, -1, -1, 7762ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller // ` a b c d e f g h i j k l m n o 7772ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller -1, 40, -1, 30, 30, 30, -1, 0, 50, -1, -1, 50, -1, 60, -1, -1, 7782ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller // p q r s t u v w x y z { | } ~ 7792ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller -1, 20, 10, 70, -1, 10, 0, 20, 0, 10, 0, -1, -1, -1, -1, -1, 7802ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller }; 7812ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller 7822ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller /** 7832ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * Map calendar field letter into calendar field level. 7842ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller */ 7852ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller private static int getLevelFromChar(char ch) { 7862ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller return ch < PATTERN_CHAR_TO_LEVEL.length ? PATTERN_CHAR_TO_LEVEL[ch & 0xff] : -1; 7872ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } 7882ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller 7892ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller private static final boolean[] PATTERN_CHAR_IS_SYNTAX = 7902ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller { 7912ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller // 7922ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller false, false, false, false, false, false, false, false, 7932ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller // 7942ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller false, false, false, false, false, false, false, false, 7952ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller // 7962ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller false, false, false, false, false, false, false, false, 7972ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller // 7982ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller false, false, false, false, false, false, false, false, 7992ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller // ! " # $ % & ' 8002ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller false, false, false, false, false, false, false, false, 8012ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller // ( ) * + , - . / 8022ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller false, false, false, false, false, false, false, false, 8032ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller // 0 1 2 3 4 5 6 7 8042ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller false, false, false, false, false, false, false, false, 8052ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller // 8 9 : ; < = > ? 8062ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller false, false, false, false, false, false, false, false, 8072ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller // @ A B C D E F G 8082ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller false, true, true, true, true, true, true, true, 8092ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller // H I J K L M N O 8102ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller true, true, true, true, true, true, true, true, 8112ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller // P Q R S T U V W 8122ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller true, true, true, true, true, true, true, true, 8132ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller // X Y Z [ \ ] ^ _ 8142ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller true, true, true, false, false, false, false, false, 8152ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller // ` a b c d e f g 8162ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller false, true, true, true, true, true, true, true, 8172ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller // h i j k l m n o 8182ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller true, true, true, true, true, true, true, true, 8192ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller // p q r s t u v w 8202ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller true, true, true, true, true, true, true, true, 8212ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller // x y z { | } ~ 8222ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller true, true, true, false, false, false, false, false, 8232ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller }; 8242ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller 8252ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller /** 8262ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * Tell if a character can be used to define a field in a format string. 8272ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller */ 8282ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller private static boolean isSyntaxChar(char ch) { 8292ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller return ch < PATTERN_CHAR_IS_SYNTAX.length ? PATTERN_CHAR_IS_SYNTAX[ch & 0xff] : false; 8302ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } 8312ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller 8322ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller // When calendar uses hebr numbering (i.e. he@calendar=hebrew), 8332ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller // offset the years within the current millenium down to 1-999 8342ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller private static final int HEBREW_CAL_CUR_MILLENIUM_START_YEAR = 5000; 8352ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller private static final int HEBREW_CAL_CUR_MILLENIUM_END_YEAR = 6000; 8362ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller 8372ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller /** 8382ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * The version of the serialized data on the stream. Possible values: 8392ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * <ul> 8402ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * <li><b>0</b> or not present on stream: JDK 1.1.3. This version 8412ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * has no <code>defaultCenturyStart</code> on stream. 8422ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * <li><b>1</b> JDK 1.1.4 or later. This version adds 8432ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * <code>defaultCenturyStart</code>. 8442ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * <li><b>2</b> This version writes an additional int for 8452ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * <code>capitalizationSetting</code>. 8462ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * </ul> 8472ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * When streaming out this class, the most recent format 8482ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * and the highest allowable <code>serialVersionOnStream</code> 8492ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * is written. 8502ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * @serial 8512ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller */ 8522ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller private int serialVersionOnStream = currentSerialVersion; 8532ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller 8542ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller /** 8552ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * The pattern string of this formatter. This is always a non-localized 8562ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * pattern. May not be null. See class documentation for details. 8572ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * @serial 8582ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller */ 8592ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller private String pattern; 8602ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller 8612ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller /** 8622ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * The override string of this formatter. Used to override the 8632ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * numbering system for one or more fields. 8642ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * @serial 8652ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller */ 8662ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller private String override; 8672ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller 8682ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller /** 8692ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * The hash map used for number format overrides. 8702ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * @serial 8712ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller */ 8722ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller private HashMap<String, NumberFormat> numberFormatters; 8732ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller 8742ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller /** 8752ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * The hash map used for number format overrides. 8762ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * @serial 8772ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller */ 8782ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller private HashMap<Character, String> overrideMap; 8792ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller 8802ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller /** 8812ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * The symbols used by this formatter for week names, month names, 8822ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * etc. May not be null. 8832ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * @serial 8842ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * @see DateFormatSymbols 8852ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller */ 8862ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller private DateFormatSymbols formatData; 8872ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller 8882ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller private transient ULocale locale; 8892ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller 8902ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller /** 8912ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * We map dates with two-digit years into the century starting at 8922ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * <code>defaultCenturyStart</code>, which may be any date. May 8932ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * not be null. 8942ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * @serial 8952ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller */ 8962ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller private Date defaultCenturyStart; 8972ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller 8982ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller private transient int defaultCenturyStartYear; 8992ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller 9002ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller // defaultCenturyBase is set when an instance is created 9012ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller // and may be used for calculating defaultCenturyStart when needed. 9022ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller private transient long defaultCenturyBase; 9032ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller 9042ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller private static final int millisPerHour = 60 * 60 * 1000; 9052ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller 9062ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller // When possessing ISO format, the ERA may be ommitted is the 9072ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller // year specifier is a negative number. 9082ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller private static final int ISOSpecialEra = -32000; 9091c8a530973739aafa823d758240d2cd5dad96fe3Fredrik Roubert 9102ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller // This prefix is designed to NEVER MATCH real text, in order to 9112ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller // suppress the parsing of negative numbers. Adjust as needed (if 9122ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller // this becomes valid Unicode). 9132ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller private static final String SUPPRESS_NEGATIVE_PREFIX = "\uAB00"; 9142ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller 9152ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller /** 9162ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * If true, this object supports fast formatting using the 9172ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * subFormat variant that takes a StringBuffer. 9182ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller */ 9192ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller private transient boolean useFastFormat; 9202ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller 9212ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller /* 9222ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * The time zone sub-formatter, introduced in ICU 4.8 9232ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller */ 9242ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller private volatile TimeZoneFormat tzFormat; 9252ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller 9262ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller /** 9272ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * BreakIterator to use for capitalization 9282ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller */ 9292ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller private transient BreakIterator capitalizationBrkIter = null; 9302ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller 9311c8a530973739aafa823d758240d2cd5dad96fe3Fredrik Roubert /** 9321c8a530973739aafa823d758240d2cd5dad96fe3Fredrik Roubert * DateFormat pattern contains the minute field. 9331c8a530973739aafa823d758240d2cd5dad96fe3Fredrik Roubert */ 9341c8a530973739aafa823d758240d2cd5dad96fe3Fredrik Roubert private transient boolean hasMinute; 9351c8a530973739aafa823d758240d2cd5dad96fe3Fredrik Roubert 9361c8a530973739aafa823d758240d2cd5dad96fe3Fredrik Roubert /** 9371c8a530973739aafa823d758240d2cd5dad96fe3Fredrik Roubert * DateFormat pattern contains the second field. 9381c8a530973739aafa823d758240d2cd5dad96fe3Fredrik Roubert */ 9391c8a530973739aafa823d758240d2cd5dad96fe3Fredrik Roubert private transient boolean hasSecond; 9401c8a530973739aafa823d758240d2cd5dad96fe3Fredrik Roubert 9412ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller /* 9422ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * Capitalization setting, introduced in ICU 50 9432ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * Special serialization, see writeObject & readObject below 9442ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * 9452ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * Hoisted to DateFormat in ICU 53, get value with 9462ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * getContext(DisplayContext.Type.CAPITALIZATION) 9472ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller */ 9482ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller // private transient DisplayContext capitalizationSetting; 9492ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller 9502ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller /* 9512ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * Old defaultCapitalizationContext field 9522ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * from ICU 49.1: 9532ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller */ 9542ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller //private ContextValue defaultCapitalizationContext; 9552ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller /** 9562ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * Old ContextValue enum, preserved only to avoid 9572ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * deserialization errs from ICU 49.1. 9582ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller */ 9592ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller @SuppressWarnings("unused") 9602ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller private enum ContextValue { 9612ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller UNKNOWN, 9622ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller CAPITALIZATION_FOR_MIDDLE_OF_SENTENCE, 9632ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller CAPITALIZATION_FOR_BEGINNING_OF_SENTENCE, 9642ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller CAPITALIZATION_FOR_UI_LIST_OR_MENU, 9652ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller CAPITALIZATION_FOR_STANDALONE 9662ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } 9672ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller 9682ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller /** 9692ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * Constructs a SimpleDateFormat using the default pattern for the default <code>FORMAT</code> 9702ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * locale. <b>Note:</b> Not all locales support SimpleDateFormat; for full 9712ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * generality, use the factory methods in the DateFormat class. 9722ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * 9732ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * @see DateFormat 9742ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * @see Category#FORMAT 9752ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller */ 9762ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller public SimpleDateFormat() { 9772ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller this(getDefaultPattern(), null, null, null, null, true, null); 9782ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } 9792ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller 9802ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller /** 9812ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * Constructs a SimpleDateFormat using the given pattern in the default <code>FORMAT</code> 9822ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * locale. <b>Note:</b> Not all locales support SimpleDateFormat; for full 9832ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * generality, use the factory methods in the DateFormat class. 9842ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * @see Category#FORMAT 9852ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller */ 9862ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller public SimpleDateFormat(String pattern) 9872ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller { 9882ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller this(pattern, null, null, null, null, true, null); 9892ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } 9902ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller 9912ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller /** 9922ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * Constructs a SimpleDateFormat using the given pattern and locale. 9932ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * <b>Note:</b> Not all locales support SimpleDateFormat; for full 9942ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * generality, use the factory methods in the DateFormat class. 9952ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller */ 9962ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller public SimpleDateFormat(String pattern, Locale loc) 9972ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller { 9982ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller this(pattern, null, null, null, ULocale.forLocale(loc), true, null); 9992ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } 10002ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller 10012ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller /** 10022ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * Constructs a SimpleDateFormat using the given pattern and locale. 10032ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * <b>Note:</b> Not all locales support SimpleDateFormat; for full 10042ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * generality, use the factory methods in the DateFormat class. 10052ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller */ 10062ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller public SimpleDateFormat(String pattern, ULocale loc) 10072ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller { 10082ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller this(pattern, null, null, null, loc, true, null); 10092ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } 10102ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller 10112ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller /** 10122ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * Constructs a SimpleDateFormat using the given pattern , override and locale. 10132ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * @param pattern The pattern to be used 10142ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * @param override The override string. A numbering system override string can take one of the following forms: 10152ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * 1). If just a numbering system name is specified, it applies to all numeric fields in the date format pattern. 10162ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * 2). To specify an alternate numbering system on a field by field basis, use the field letters from the pattern 10172ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * followed by an = sign, followed by the numbering system name. For example, to specify that just the year 10182ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * be formatted using Hebrew digits, use the override "y=hebr". Multiple overrides can be specified in a single 10192ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * string by separating them with a semi-colon. For example, the override string "m=thai;y=deva" would format using 10202ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * Thai digits for the month and Devanagari digits for the year. 10212ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * @param loc The locale to be used 10222ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller */ 10232ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller public SimpleDateFormat(String pattern, String override, ULocale loc) 10242ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller { 10252ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller this(pattern, null, null, null, loc, false,override); 10262ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } 10272ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller 10282ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller /** 10292ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * Constructs a SimpleDateFormat using the given pattern and 10302ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * locale-specific symbol data. 10312ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * Warning: uses default <code>FORMAT</code> locale for digits! 10322ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller */ 10332ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller public SimpleDateFormat(String pattern, DateFormatSymbols formatData) 10342ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller { 10352ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller this(pattern, (DateFormatSymbols)formatData.clone(), null, null, null, true, null); 10362ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } 10372ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller 10382ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller /** 10392ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * @deprecated This API is ICU internal only. 104093cf604e9dd0525f15bc0a7450b2a35f3884c298Neil Fuller * @hide original deprecated declaration 1041836e6b40a94ec3fb7545a76cb072960442b7eee9Neil Fuller * @hide draft / provisional / internal are hidden on Android 10422ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller */ 10432ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller @Deprecated 10442ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller public SimpleDateFormat(String pattern, DateFormatSymbols formatData, ULocale loc) 10452ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller { 10462ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller this(pattern, (DateFormatSymbols)formatData.clone(), null, null, loc, true,null); 10472ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } 10482ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller 10492ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller /** 10502ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * Package-private constructor that allows a subclass to specify 10512ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * whether it supports fast formatting. 10522ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * 10532ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * TODO make this API public. 10542ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller */ 10552ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller SimpleDateFormat(String pattern, DateFormatSymbols formatData, Calendar calendar, ULocale locale, 10562ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller boolean useFastFormat, String override) { 10572ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller this(pattern, (DateFormatSymbols)formatData.clone(), (Calendar)calendar.clone(), null, locale, useFastFormat,override); 10582ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } 10592ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller 10602ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller /* 10612ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * The constructor called from all other SimpleDateFormat constructors 10622ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller */ 10632ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller private SimpleDateFormat(String pattern, DateFormatSymbols formatData, Calendar calendar, 10642ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller NumberFormat numberFormat, ULocale locale, boolean useFastFormat,String override) { 10652ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller this.pattern = pattern; 10662ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller this.formatData = formatData; 10672ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller this.calendar = calendar; 10682ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller this.numberFormat = numberFormat; 10692ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller this.locale = locale; // time zone formatting 10702ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller this.useFastFormat = useFastFormat; 10712ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller this.override = override; 10722ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller initialize(); 10732ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } 10742ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller 10752ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller /** 10762ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * Creates an instance of SimpleDateFormat for the given format configuration 10772ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * @param formatConfig the format configuration 10782ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * @return A SimpleDateFormat instance 10792ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * @deprecated This API is ICU internal only. 108093cf604e9dd0525f15bc0a7450b2a35f3884c298Neil Fuller * @hide original deprecated declaration 1081836e6b40a94ec3fb7545a76cb072960442b7eee9Neil Fuller * @hide draft / provisional / internal are hidden on Android 10822ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller */ 10832ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller @Deprecated 10842ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller public static SimpleDateFormat getInstance(Calendar.FormatConfiguration formatConfig) { 10852ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller 10862ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller String ostr = formatConfig.getOverrideString(); 10872ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller boolean useFast = ( ostr != null && ostr.length() > 0 ); 10882ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller 10892ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller return new SimpleDateFormat(formatConfig.getPatternString(), 10902ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller formatConfig.getDateFormatSymbols(), 10912ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller formatConfig.getCalendar(), 10922ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller null, 10932ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller formatConfig.getLocale(), 10942ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller useFast, 10952ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller formatConfig.getOverrideString()); 10962ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } 10972ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller 10982ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller /* 10992ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * Initialized fields 11002ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller */ 11012ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller private void initialize() { 11022ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller if (locale == null) { 11032ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller locale = ULocale.getDefault(Category.FORMAT); 11042ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } 11052ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller if (formatData == null) { 11062ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller formatData = new DateFormatSymbols(locale); 11072ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } 11082ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller if (calendar == null) { 11092ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller calendar = Calendar.getInstance(locale); 11102ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } 11112ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller if (numberFormat == null) { 11122ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller NumberingSystem ns = NumberingSystem.getInstance(locale); 11132ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller if (ns.isAlgorithmic()) { 11142ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller numberFormat = NumberFormat.getInstance(locale); 11152ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } else { 11162ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller String digitString = ns.getDescription(); 11172ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller String nsName = ns.getName(); 11182ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller // Use a NumberFormat optimized for date formatting 11192ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller numberFormat = new DateNumberFormat(locale, digitString, nsName); 11202ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } 11212ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } 11222ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller // Note: deferring calendar calculation until when we really need it. 11232ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller // Instead, we just record time of construction for backward compatibility. 11242ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller defaultCenturyBase = System.currentTimeMillis(); 11252ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller 11262ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller setLocale(calendar.getLocale(ULocale.VALID_LOCALE ), calendar.getLocale(ULocale.ACTUAL_LOCALE)); 11272ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller initLocalZeroPaddingNumberFormat(); 11282ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller 11292ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller if (override != null) { 11302ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller initNumberFormatters(locale); 11312ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } 11321c8a530973739aafa823d758240d2cd5dad96fe3Fredrik Roubert 11331c8a530973739aafa823d758240d2cd5dad96fe3Fredrik Roubert parsePattern(); 11342ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } 11352ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller 11362ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller /** 11372ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * Private method lazily instantiate the TimeZoneFormat field 11382ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * @param bForceUpdate when true, check if tzFormat is synchronized with 11392ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * the current numberFormat and update its digits if necessary. When false, 11402ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * this check is skipped. 11412ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller */ 11422ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller private synchronized void initializeTimeZoneFormat(boolean bForceUpdate) { 11432ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller if (bForceUpdate || tzFormat == null) { 11442ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller tzFormat = TimeZoneFormat.getInstance(locale); 11452ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller 11462ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller String digits = null; 11472ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller if (numberFormat instanceof DecimalFormat) { 11482ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller DecimalFormatSymbols decsym = ((DecimalFormat) numberFormat).getDecimalFormatSymbols(); 11492ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller digits = new String(decsym.getDigits()); 11502ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } else if (numberFormat instanceof DateNumberFormat) { 11512ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller digits = new String(((DateNumberFormat)numberFormat).getDigits()); 11522ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } 11532ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller 11542ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller if (digits != null) { 11552ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller if (!tzFormat.getGMTOffsetDigits().equals(digits)) { 11562ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller if (tzFormat.isFrozen()) { 11572ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller tzFormat = tzFormat.cloneAsThawed(); 11582ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } 11592ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller tzFormat.setGMTOffsetDigits(digits); 11602ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } 11612ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } 11622ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } 11632ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } 11642ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller 11652ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller /** 11662ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * Private method, returns non-null TimeZoneFormat. 11672ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * @return the TimeZoneFormat used by this formatter. 11682ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller */ 11692ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller private TimeZoneFormat tzFormat() { 11702ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller if (tzFormat == null) { 11712ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller initializeTimeZoneFormat(false); 11722ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } 11732ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller return tzFormat; 11742ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } 11752ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller 11762ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller // privates for the default pattern 11772ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller private static ULocale cachedDefaultLocale = null; 11782ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller private static String cachedDefaultPattern = null; 11792ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller private static final String FALLBACKPATTERN = "yy/MM/dd HH:mm"; 11802ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller 11812ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller /* 11822ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * Returns the default date and time pattern (SHORT) for the default locale. 11832ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * This method is only used by the default SimpleDateFormat constructor. 11842ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller */ 11852ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller private static synchronized String getDefaultPattern() { 11862ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller ULocale defaultLocale = ULocale.getDefault(Category.FORMAT); 11872ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller if (!defaultLocale.equals(cachedDefaultLocale)) { 11882ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller cachedDefaultLocale = defaultLocale; 11892ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller Calendar cal = Calendar.getInstance(cachedDefaultLocale); 1190f86f25d102340da66b9c7cb6b2d5ecdc0de43ecfFredrik Roubert 11912ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller try { 1192f86f25d102340da66b9c7cb6b2d5ecdc0de43ecfFredrik Roubert // Load the calendar data directly. 1193f86f25d102340da66b9c7cb6b2d5ecdc0de43ecfFredrik Roubert ICUResourceBundle rb = (ICUResourceBundle) UResourceBundle.getBundleInstance( 1194f86f25d102340da66b9c7cb6b2d5ecdc0de43ecfFredrik Roubert ICUData.ICU_BASE_NAME, cachedDefaultLocale); 1195f86f25d102340da66b9c7cb6b2d5ecdc0de43ecfFredrik Roubert String resourcePath = "calendar/" + cal.getType() + "/DateTimePatterns"; 1196f86f25d102340da66b9c7cb6b2d5ecdc0de43ecfFredrik Roubert ICUResourceBundle patternsRb= rb.findWithFallback(resourcePath); 1197f86f25d102340da66b9c7cb6b2d5ecdc0de43ecfFredrik Roubert 1198f86f25d102340da66b9c7cb6b2d5ecdc0de43ecfFredrik Roubert if (patternsRb == null) { 1199f86f25d102340da66b9c7cb6b2d5ecdc0de43ecfFredrik Roubert patternsRb = rb.findWithFallback("calendar/gregorian/DateTimePatterns"); 1200f86f25d102340da66b9c7cb6b2d5ecdc0de43ecfFredrik Roubert } 1201f86f25d102340da66b9c7cb6b2d5ecdc0de43ecfFredrik Roubert if (patternsRb == null || patternsRb.getSize() < 9) { 1202f86f25d102340da66b9c7cb6b2d5ecdc0de43ecfFredrik Roubert cachedDefaultPattern = FALLBACKPATTERN; 1203f86f25d102340da66b9c7cb6b2d5ecdc0de43ecfFredrik Roubert } else { 1204f86f25d102340da66b9c7cb6b2d5ecdc0de43ecfFredrik Roubert int defaultIndex = 8; 1205f86f25d102340da66b9c7cb6b2d5ecdc0de43ecfFredrik Roubert if (patternsRb.getSize() >= 13) { 1206f86f25d102340da66b9c7cb6b2d5ecdc0de43ecfFredrik Roubert defaultIndex += (SHORT + 1); 1207f86f25d102340da66b9c7cb6b2d5ecdc0de43ecfFredrik Roubert } 1208f86f25d102340da66b9c7cb6b2d5ecdc0de43ecfFredrik Roubert String basePattern = patternsRb.getString(defaultIndex); 1209f86f25d102340da66b9c7cb6b2d5ecdc0de43ecfFredrik Roubert 1210f86f25d102340da66b9c7cb6b2d5ecdc0de43ecfFredrik Roubert cachedDefaultPattern = SimpleFormatterImpl.formatRawPattern( 1211f86f25d102340da66b9c7cb6b2d5ecdc0de43ecfFredrik Roubert basePattern, 2, 2, 1212f86f25d102340da66b9c7cb6b2d5ecdc0de43ecfFredrik Roubert patternsRb.getString(SHORT), patternsRb.getString(SHORT + 4)); 1213f86f25d102340da66b9c7cb6b2d5ecdc0de43ecfFredrik Roubert } 12142ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } catch (MissingResourceException e) { 12152ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller cachedDefaultPattern = FALLBACKPATTERN; 12162ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } 12172ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } 12182ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller return cachedDefaultPattern; 12192ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } 12202ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller 12212ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller /* Define one-century window into which to disambiguate dates using 12222ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * two-digit years. 12232ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller */ 12242ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller private void parseAmbiguousDatesAsAfter(Date startDate) { 12252ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller defaultCenturyStart = startDate; 12262ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller calendar.setTime(startDate); 12272ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller defaultCenturyStartYear = calendar.get(Calendar.YEAR); 12282ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } 12292ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller 12302ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller /* Initialize defaultCenturyStart and defaultCenturyStartYear by base time. 12312ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * The default start time is 80 years before the creation time of this object. 12322ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller */ 12332ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller private void initializeDefaultCenturyStart(long baseTime) { 12342ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller defaultCenturyBase = baseTime; 12352ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller // clone to avoid messing up date stored in calendar object 12362ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller // when this method is called while parsing 12372ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller Calendar tmpCal = (Calendar)calendar.clone(); 12382ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller tmpCal.setTimeInMillis(baseTime); 12392ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller tmpCal.add(Calendar.YEAR, -80); 12402ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller defaultCenturyStart = tmpCal.getTime(); 12412ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller defaultCenturyStartYear = tmpCal.get(Calendar.YEAR); 12422ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } 12432ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller 12442ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller /* Gets the default century start date for this object */ 12452ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller private Date getDefaultCenturyStart() { 12462ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller if (defaultCenturyStart == null) { 12472ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller // not yet initialized 12482ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller initializeDefaultCenturyStart(defaultCenturyBase); 12492ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } 12502ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller return defaultCenturyStart; 12512ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } 12522ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller 12532ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller /* Gets the default century start year for this object */ 12542ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller private int getDefaultCenturyStartYear() { 12552ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller if (defaultCenturyStart == null) { 12562ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller // not yet initialized 12572ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller initializeDefaultCenturyStart(defaultCenturyBase); 12582ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } 12592ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller return defaultCenturyStartYear; 12602ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } 12612ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller 12622ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller /** 12632ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * Sets the 100-year period 2-digit years will be interpreted as being in 12642ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * to begin on the date the user specifies. 12652ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * @param startDate During parsing, two digit years will be placed in the range 12662ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * <code>startDate</code> to <code>startDate + 100 years</code>. 12672ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller */ 12682ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller public void set2DigitYearStart(Date startDate) { 12692ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller parseAmbiguousDatesAsAfter(startDate); 12702ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } 12712ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller 12722ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller /** 12732ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * Returns the beginning date of the 100-year period 2-digit years are interpreted 12742ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * as being within. 12752ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * @return the start of the 100-year period into which two digit years are 12762ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * parsed 12772ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller */ 12782ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller public Date get2DigitYearStart() { 12792ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller return getDefaultCenturyStart(); 12802ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } 12812ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller 12822ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller /** 12831537b2f39245c07b00aa78c3600f7aebcb172490Neil Fuller * <strong>[icu]</strong> Set a particular DisplayContext value in the formatter, 12841c8a530973739aafa823d758240d2cd5dad96fe3Fredrik Roubert * such as CAPITALIZATION_FOR_STANDALONE. Note: For getContext, see 12852ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * DateFormat. 12861c8a530973739aafa823d758240d2cd5dad96fe3Fredrik Roubert * 12871c8a530973739aafa823d758240d2cd5dad96fe3Fredrik Roubert * @param context The DisplayContext value to set. 12882ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller */ 12892ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller // Here we override the DateFormat implementation in order to lazily initialize relevant items 1290f86f25d102340da66b9c7cb6b2d5ecdc0de43ecfFredrik Roubert @Override 12912ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller public void setContext(DisplayContext context) { 12922ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller super.setContext(context); 12932ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller if (capitalizationBrkIter == null && (context==DisplayContext.CAPITALIZATION_FOR_BEGINNING_OF_SENTENCE || 12942ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller context==DisplayContext.CAPITALIZATION_FOR_UI_LIST_OR_MENU || 12952ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller context==DisplayContext.CAPITALIZATION_FOR_STANDALONE)) { 12962ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller capitalizationBrkIter = BreakIterator.getSentenceInstance(locale); 12972ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } 12982ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } 12992ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller 13002ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller /** 13012ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * Formats a date or time, which is the standard millis 13022ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * since January 1, 1970, 00:00:00 GMT. 13032ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * <p>Example: using the US locale: 130408ae9f2909b2ec37f755dac4372553437e9d7cf6Paul Duffin * "yyyy.MM.dd G 'at' HH:mm:ss zzz" ->> 1996.07.10 AD at 15:08:56 PDT 13052ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * @param cal the calendar whose date-time value is to be formatted into a date-time string 13062ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * @param toAppendTo where the new date-time text is to be appended 13072ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * @param pos the formatting position. On input: an alignment field, 13082ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * if desired. On output: the offsets of the alignment field. 13092ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * @return the formatted date-time string. 13102ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * @see DateFormat 13112ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller */ 1312f86f25d102340da66b9c7cb6b2d5ecdc0de43ecfFredrik Roubert @Override 13132ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller public StringBuffer format(Calendar cal, StringBuffer toAppendTo, 13142ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller FieldPosition pos) { 13152ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller TimeZone backupTZ = null; 13162ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller if (cal != calendar && !cal.getType().equals(calendar.getType())) { 13172ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller // Different calendar type 13182ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller // We use the time and time zone from the input calendar, but 13192ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller // do not use the input calendar for field calculation. 13202ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller calendar.setTimeInMillis(cal.getTimeInMillis()); 13212ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller backupTZ = calendar.getTimeZone(); 13222ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller calendar.setTimeZone(cal.getTimeZone()); 13232ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller cal = calendar; 13242ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } 13252ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller StringBuffer result = format(cal, getContext(DisplayContext.Type.CAPITALIZATION), toAppendTo, pos, null); 13262ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller if (backupTZ != null) { 13272ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller // Restore the original time zone 13282ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller calendar.setTimeZone(backupTZ); 13292ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } 13302ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller return result; 13312ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } 13322ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller 13332ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller // The actual method to format date. If List attributes is not null, 13342ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller // then attribute information will be recorded. 13352ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller private StringBuffer format(Calendar cal, DisplayContext capitalizationContext, 13362ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller StringBuffer toAppendTo, FieldPosition pos, List<FieldPosition> attributes) { 13372ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller // Initialize 13382ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller pos.setBeginIndex(0); 13392ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller pos.setEndIndex(0); 13402ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller 13412ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller // Careful: For best performance, minimize the number of calls 13422ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller // to StringBuffer.append() by consolidating appends when 13432ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller // possible. 13442ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller 13452ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller Object[] items = getPatternItems(); 13462ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller for (int i = 0; i < items.length; i++) { 13472ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller if (items[i] instanceof String) { 13482ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller toAppendTo.append((String)items[i]); 13492ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } else { 13502ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller PatternItem item = (PatternItem)items[i]; 13512ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller int start = 0; 13522ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller if (attributes != null) { 13532ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller // Save the current length 13542ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller start = toAppendTo.length(); 13552ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } 13562ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller if (useFastFormat) { 13572ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller subFormat(toAppendTo, item.type, item.length, toAppendTo.length(), 13582ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller i, capitalizationContext, pos, cal); 13592ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } else { 13602ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller toAppendTo.append(subFormat(item.type, item.length, toAppendTo.length(), 13612ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller i, capitalizationContext, pos, cal)); 13622ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } 13632ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller if (attributes != null) { 13642ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller // Check the sub format length 13652ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller int end = toAppendTo.length(); 13662ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller if (end - start > 0) { 13672ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller // Append the attribute to the list 13682ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller DateFormat.Field attr = patternCharToDateFormatField(item.type); 13692ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller FieldPosition fp = new FieldPosition(attr); 13702ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller fp.setBeginIndex(start); 13712ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller fp.setEndIndex(end); 13722ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller attributes.add(fp); 13732ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } 13742ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } 13752ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } 13762ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } 13772ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller return toAppendTo; 13782ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller 13792ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } 13802ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller 13812ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller // Map pattern character to index 13822ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller private static final int[] PATTERN_CHAR_TO_INDEX = 13832ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller { 13842ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 13852ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller // 13862ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 13872ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller // ! " # $ % & ' ( ) * + , - . / 13882ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 13892ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller // 0 1 2 3 4 5 6 7 8 9 : ; < = > ? 13902ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 13912ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller // @ A B C D E F G H I J K L M N O 13921c8a530973739aafa823d758240d2cd5dad96fe3Fredrik Roubert -1, 22, 36, -1, 10, 9, 11, 0, 5, -1, -1, 16, 26, 2, -1, 31, 13932ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller // P Q R S T U V W X Y Z [ \ ] ^ _ 13942ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller -1, 27, -1, 8, -1, 30, 29, 13, 32, 18, 23, -1, -1, -1, -1, -1, 13952ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller // ` a b c d e f g h i j k l m n o 13961c8a530973739aafa823d758240d2cd5dad96fe3Fredrik Roubert -1, 14, 35, 25, 3, 19, -1, 21, 15, -1, -1, 4, -1, 6, -1, -1, 13972ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller // p q r s t u v w x y z { | } ~ 13982ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller -1, 28, 34, 7, -1, 20, 24, 12, 33, 1, 17, -1, -1, -1, -1, -1, 13992ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller }; 14002ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller 14012ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller private static int getIndexFromChar(char ch) { 14022ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller return ch < PATTERN_CHAR_TO_INDEX.length ? PATTERN_CHAR_TO_INDEX[ch & 0xff] : -1; 14032ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } 14042ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller 14052ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller // Map pattern character index to Calendar field number 14062ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller private static final int[] PATTERN_INDEX_TO_CALENDAR_FIELD = 14072ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller { 14082ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller /*GyM*/ Calendar.ERA, Calendar.YEAR, Calendar.MONTH, 14092ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller /*dkH*/ Calendar.DATE, Calendar.HOUR_OF_DAY, Calendar.HOUR_OF_DAY, 14102ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller /*msS*/ Calendar.MINUTE, Calendar.SECOND, Calendar.MILLISECOND, 14112ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller /*EDF*/ Calendar.DAY_OF_WEEK, Calendar.DAY_OF_YEAR, Calendar.DAY_OF_WEEK_IN_MONTH, 14122ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller /*wWa*/ Calendar.WEEK_OF_YEAR, Calendar.WEEK_OF_MONTH, Calendar.AM_PM, 14132ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller /*hKz*/ Calendar.HOUR, Calendar.HOUR, Calendar.ZONE_OFFSET, 14142ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller /*Yeu*/ Calendar.YEAR_WOY, Calendar.DOW_LOCAL, Calendar.EXTENDED_YEAR, 14152ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller /*gAZ*/ Calendar.JULIAN_DAY, Calendar.MILLISECONDS_IN_DAY, Calendar.ZONE_OFFSET /* also DST_OFFSET */, 14162ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller /*v*/ Calendar.ZONE_OFFSET /* also DST_OFFSET */, 14172ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller /*c*/ Calendar.DOW_LOCAL, 14182ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller /*L*/ Calendar.MONTH, 14192ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller /*Qq*/ Calendar.MONTH, Calendar.MONTH, 14202ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller /*V*/ Calendar.ZONE_OFFSET /* also DST_OFFSET */, 14212ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller /*U*/ Calendar.YEAR, 14222ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller /*O*/ Calendar.ZONE_OFFSET /* also DST_OFFSET */, 14232ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller /*Xx*/ Calendar.ZONE_OFFSET /* also DST_OFFSET */, Calendar.ZONE_OFFSET /* also DST_OFFSET */, 14242ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller /*r*/ Calendar.EXTENDED_YEAR /* not an exact match */, 14251c8a530973739aafa823d758240d2cd5dad96fe3Fredrik Roubert /*bB*/ -1, -1 /* am/pm/midnight/noon and flexible day period fields; no mapping to calendar fields */ 14262ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller /*:*/ -1, /* => no useful mapping to any calendar field, can't use protected Calendar.BASE_FIELD_COUNT */ 14272ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller }; 14282ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller 14292ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller // Map pattern character index to DateFormat field number 14302ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller private static final int[] PATTERN_INDEX_TO_DATE_FORMAT_FIELD = { 14312ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller /*GyM*/ DateFormat.ERA_FIELD, DateFormat.YEAR_FIELD, DateFormat.MONTH_FIELD, 14322ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller /*dkH*/ DateFormat.DATE_FIELD, DateFormat.HOUR_OF_DAY1_FIELD, DateFormat.HOUR_OF_DAY0_FIELD, 14332ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller /*msS*/ DateFormat.MINUTE_FIELD, DateFormat.SECOND_FIELD, DateFormat.FRACTIONAL_SECOND_FIELD, 14342ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller /*EDF*/ DateFormat.DAY_OF_WEEK_FIELD, DateFormat.DAY_OF_YEAR_FIELD, DateFormat.DAY_OF_WEEK_IN_MONTH_FIELD, 14352ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller /*wWa*/ DateFormat.WEEK_OF_YEAR_FIELD, DateFormat.WEEK_OF_MONTH_FIELD, DateFormat.AM_PM_FIELD, 14362ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller /*hKz*/ DateFormat.HOUR1_FIELD, DateFormat.HOUR0_FIELD, DateFormat.TIMEZONE_FIELD, 14372ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller /*Yeu*/ DateFormat.YEAR_WOY_FIELD, DateFormat.DOW_LOCAL_FIELD, DateFormat.EXTENDED_YEAR_FIELD, 14382ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller /*gAZ*/ DateFormat.JULIAN_DAY_FIELD, DateFormat.MILLISECONDS_IN_DAY_FIELD, DateFormat.TIMEZONE_RFC_FIELD, 14392ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller /*v*/ DateFormat.TIMEZONE_GENERIC_FIELD, 14402ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller /*c*/ DateFormat.STANDALONE_DAY_FIELD, 14412ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller /*L*/ DateFormat.STANDALONE_MONTH_FIELD, 14422ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller /*Qq*/ DateFormat.QUARTER_FIELD, DateFormat.STANDALONE_QUARTER_FIELD, 14432ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller /*V*/ DateFormat.TIMEZONE_SPECIAL_FIELD, 14442ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller /*U*/ DateFormat.YEAR_NAME_FIELD, 14452ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller /*O*/ DateFormat.TIMEZONE_LOCALIZED_GMT_OFFSET_FIELD, 14462ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller /*Xx*/ DateFormat.TIMEZONE_ISO_FIELD, DateFormat.TIMEZONE_ISO_LOCAL_FIELD, 14472ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller /*r*/ DateFormat.RELATED_YEAR, 14481c8a530973739aafa823d758240d2cd5dad96fe3Fredrik Roubert /*bB*/ DateFormat.AM_PM_MIDNIGHT_NOON_FIELD, DateFormat.FLEXIBLE_DAY_PERIOD_FIELD, 14492ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller /*(no pattern character defined for this)*/ DateFormat.TIME_SEPARATOR, 14502ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller }; 14512ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller 14522ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller // Map pattern character index to DateFormat.Field 14532ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller private static final DateFormat.Field[] PATTERN_INDEX_TO_DATE_FORMAT_ATTRIBUTE = { 14542ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller /*GyM*/ DateFormat.Field.ERA, DateFormat.Field.YEAR, DateFormat.Field.MONTH, 14552ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller /*dkH*/ DateFormat.Field.DAY_OF_MONTH, DateFormat.Field.HOUR_OF_DAY1, DateFormat.Field.HOUR_OF_DAY0, 14562ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller /*msS*/ DateFormat.Field.MINUTE, DateFormat.Field.SECOND, DateFormat.Field.MILLISECOND, 14572ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller /*EDF*/ DateFormat.Field.DAY_OF_WEEK, DateFormat.Field.DAY_OF_YEAR, DateFormat.Field.DAY_OF_WEEK_IN_MONTH, 14582ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller /*wWa*/ DateFormat.Field.WEEK_OF_YEAR, DateFormat.Field.WEEK_OF_MONTH, DateFormat.Field.AM_PM, 14592ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller /*hKz*/ DateFormat.Field.HOUR1, DateFormat.Field.HOUR0, DateFormat.Field.TIME_ZONE, 14602ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller /*Yeu*/ DateFormat.Field.YEAR_WOY, DateFormat.Field.DOW_LOCAL, DateFormat.Field.EXTENDED_YEAR, 14612ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller /*gAZ*/ DateFormat.Field.JULIAN_DAY, DateFormat.Field.MILLISECONDS_IN_DAY, DateFormat.Field.TIME_ZONE, 14622ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller /*v*/ DateFormat.Field.TIME_ZONE, 14632ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller /*c*/ DateFormat.Field.DAY_OF_WEEK, 14642ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller /*L*/ DateFormat.Field.MONTH, 14652ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller /*Qq*/ DateFormat.Field.QUARTER, DateFormat.Field.QUARTER, 14662ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller /*V*/ DateFormat.Field.TIME_ZONE, 14672ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller /*U*/ DateFormat.Field.YEAR, 14682ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller /*O*/ DateFormat.Field.TIME_ZONE, 14692ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller /*Xx*/ DateFormat.Field.TIME_ZONE, DateFormat.Field.TIME_ZONE, 14702ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller /*r*/ DateFormat.Field.RELATED_YEAR, 14711c8a530973739aafa823d758240d2cd5dad96fe3Fredrik Roubert /*bB*/ DateFormat.Field.AM_PM_MIDNIGHT_NOON, DateFormat.Field.FLEXIBLE_DAY_PERIOD, 14722ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller /*(no pattern character defined for this)*/ DateFormat.Field.TIME_SEPARATOR, 14732ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller }; 14742ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller 14752ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller /** 14762ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * Returns a DateFormat.Field constant associated with the specified format pattern 14772ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * character. 14782ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * 14792ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * @param ch The pattern character 14802ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * @return DateFormat.Field associated with the pattern character 14812ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller */ 14822ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller protected DateFormat.Field patternCharToDateFormatField(char ch) { 14832ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller int patternCharIndex = getIndexFromChar(ch); 14842ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller if (patternCharIndex != -1) { 14852ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller return PATTERN_INDEX_TO_DATE_FORMAT_ATTRIBUTE[patternCharIndex]; 14862ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } 14872ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller return null; 14882ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } 14892ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller 14902ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller /** 14912ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * Formats a single field, given its pattern character. Subclasses may 14922ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * override this method in order to modify or add formatting 14932ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * capabilities. 14942ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * @param ch the pattern character 14952ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * @param count the number of times ch is repeated in the pattern 14962ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * @param beginOffset the offset of the output string at the start of 14972ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * this field; used to set pos when appropriate 14982ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * @param pos receives the position of a field, when appropriate 14992ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * @param fmtData the symbols for this formatter 15002ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller */ 15012ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller protected String subFormat(char ch, int count, int beginOffset, 15022ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller FieldPosition pos, DateFormatSymbols fmtData, 15032ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller Calendar cal) 15042ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller throws IllegalArgumentException 15052ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller { 15062ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller // Note: formatData is ignored 15072ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller return subFormat(ch, count, beginOffset, 0, DisplayContext.CAPITALIZATION_NONE, pos, cal); 15082ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } 15092ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller 15102ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller /** 15112ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * Formats a single field. This is the version called internally; it 15122ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * adds fieldNum and capitalizationContext parameters. 15132ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * 15142ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * @deprecated This API is ICU internal only. 151593cf604e9dd0525f15bc0a7450b2a35f3884c298Neil Fuller * @hide original deprecated declaration 1516836e6b40a94ec3fb7545a76cb072960442b7eee9Neil Fuller * @hide draft / provisional / internal are hidden on Android 15172ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller */ 15182ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller @Deprecated 15192ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller protected String subFormat(char ch, int count, int beginOffset, 15202ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller int fieldNum, DisplayContext capitalizationContext, 15212ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller FieldPosition pos, 15222ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller Calendar cal) 15232ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller { 15242ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller StringBuffer buf = new StringBuffer(); 15252ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller subFormat(buf, ch, count, beginOffset, fieldNum, capitalizationContext, pos, cal); 15262ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller return buf.toString(); 15272ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } 15282ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller 15292ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller /** 15302ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * Formats a single field; useFastFormat variant. Reuses a 15312ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * StringBuffer for results instead of creating a String on the 15322ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * heap for each call. 15332ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * 15342ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * NOTE We don't really need the beginOffset parameter, EXCEPT for 15352ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * the need to support the slow subFormat variant (above) which 15362ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * has to pass it in to us. 15372ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * 15382ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * @deprecated This API is ICU internal only. 153993cf604e9dd0525f15bc0a7450b2a35f3884c298Neil Fuller * @hide original deprecated declaration 15401537b2f39245c07b00aa78c3600f7aebcb172490Neil Fuller * @hide draft / provisional / internal are hidden on Android 15412ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller */ 15422ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller @Deprecated 15432ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller @SuppressWarnings("fallthrough") 15442ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller protected void subFormat(StringBuffer buf, 15452ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller char ch, int count, int beginOffset, 15462ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller int fieldNum, DisplayContext capitalizationContext, 15472ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller FieldPosition pos, 15482ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller Calendar cal) { 15492ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller 15502ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller final int maxIntCount = Integer.MAX_VALUE; 15512ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller final int bufstart = buf.length(); 15522ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller TimeZone tz = cal.getTimeZone(); 15532ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller long date = cal.getTimeInMillis(); 15542ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller String result = null; 15552ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller 15562ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller int patternCharIndex = getIndexFromChar(ch); 15572ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller if (patternCharIndex == -1) { 15582ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller if (ch == 'l') { // (SMALL LETTER L) deprecated placeholder for leap month marker, ignore 15592ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller return; 15602ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } else { 15612ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller throw new IllegalArgumentException("Illegal pattern character " + 15622ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller "'" + ch + "' in \"" + 15632ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller pattern + '"'); 15642ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } 15652ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } 15662ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller 15672ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller final int field = PATTERN_INDEX_TO_CALENDAR_FIELD[patternCharIndex]; 15682ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller int value = 0; 15692ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller // Don't get value unless it is useful 15702ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller if (field >= 0) { 15712ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller value = (patternCharIndex != DateFormat.RELATED_YEAR)? cal.get(field): cal.getRelatedYear(); 15722ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } 15732ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller 15742ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller NumberFormat currentNumberFormat = getNumberFormat(ch); 15752ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller DateFormatSymbols.CapitalizationContextUsage capContextUsageType = DateFormatSymbols.CapitalizationContextUsage.OTHER; 15762ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller 15772ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller switch (patternCharIndex) { 15782ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller case 0: // 'G' - ERA 15792ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller if ( cal.getType().equals("chinese") || cal.getType().equals("dangi") ) { 15802ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller // moved from ChineseDateFormat 15812ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller zeroPaddingNumber(currentNumberFormat, buf, value, 1, 9); 15822ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } else { 15832ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller if (count == 5) { 15842ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller safeAppend(formatData.narrowEras, value, buf); 15852ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller capContextUsageType = DateFormatSymbols.CapitalizationContextUsage.ERA_NARROW; 15862ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } else if (count == 4) { 15872ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller safeAppend(formatData.eraNames, value, buf); 15882ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller capContextUsageType = DateFormatSymbols.CapitalizationContextUsage.ERA_WIDE; 15892ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } else { 15902ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller safeAppend(formatData.eras, value, buf); 15912ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller capContextUsageType = DateFormatSymbols.CapitalizationContextUsage.ERA_ABBREV; 15922ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } 15932ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } 15942ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller break; 15952ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller case 30: // 'U' - YEAR_NAME_FIELD 15962ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller if (formatData.shortYearNames != null && value <= formatData.shortYearNames.length) { 15972ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller safeAppend(formatData.shortYearNames, value-1, buf); 15982ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller break; 15992ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } 16001c8a530973739aafa823d758240d2cd5dad96fe3Fredrik Roubert // else fall through to numeric year handling, do not break here 16012ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller case 1: // 'y' - YEAR 16022ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller case 18: // 'Y' - YEAR_WOY 16032ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller if ( override != null && (override.compareTo("hebr") == 0 || override.indexOf("y=hebr") >= 0) && 16042ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller value > HEBREW_CAL_CUR_MILLENIUM_START_YEAR && value < HEBREW_CAL_CUR_MILLENIUM_END_YEAR ) { 16052ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller value -= HEBREW_CAL_CUR_MILLENIUM_START_YEAR; 16062ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } 16072ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller /* According to the specification, if the number of pattern letters ('y') is 2, 16082ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * the year is truncated to 2 digits; otherwise it is interpreted as a number. 16092ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * But the original code process 'y', 'yy', 'yyy' in the same way. and process 16102ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * patterns with 4 or more than 4 'y' characters in the same way. 16112ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * So I change the codes to meet the specification. [Richard/GCl] 16122ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller */ 16132ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller if (count == 2) { 16142ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller zeroPaddingNumber(currentNumberFormat,buf, value, 2, 2); // clip 1996 to 96 16152ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } else { //count = 1 or count > 2 16162ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller zeroPaddingNumber(currentNumberFormat,buf, value, count, maxIntCount); 16172ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } 16182ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller break; 16192ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller case 2: // 'M' - MONTH 16202ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller case 26: // 'L' - STANDALONE MONTH 16212ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller if ( cal.getType().equals("hebrew")) { 16222ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller boolean isLeap = HebrewCalendar.isLeapYear(cal.get(Calendar.YEAR)); 16232ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller if (isLeap && value == 6 && count >= 3 ) { 16242ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller value = 13; // Show alternate form for Adar II in leap years in Hebrew calendar. 16252ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } 16262ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller if (!isLeap && value >= 6 && count < 3 ) { 16272ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller value--; // Adjust the month number down 1 in Hebrew non-leap years, i.e. Adar is 6, not 7. 16282ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } 16292ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } 16302ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller int isLeapMonth = (formatData.leapMonthPatterns != null && formatData.leapMonthPatterns.length >= DateFormatSymbols.DT_MONTH_PATTERN_COUNT)? 16312ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller cal.get(Calendar.IS_LEAP_MONTH): 0; 16322ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller // should consolidate the next section by using arrays of pointers & counts for the right symbols... 16332ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller if (count == 5) { 16342ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller if (patternCharIndex == 2) { 16352ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller safeAppendWithMonthPattern(formatData.narrowMonths, value, buf, (isLeapMonth!=0)? formatData.leapMonthPatterns[DateFormatSymbols.DT_LEAP_MONTH_PATTERN_FORMAT_NARROW]: null); 16362ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } else { 16372ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller safeAppendWithMonthPattern(formatData.standaloneNarrowMonths, value, buf, (isLeapMonth!=0)? formatData.leapMonthPatterns[DateFormatSymbols.DT_LEAP_MONTH_PATTERN_STANDALONE_NARROW]: null); 16382ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } 16392ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller capContextUsageType = DateFormatSymbols.CapitalizationContextUsage.MONTH_NARROW; 16402ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } else if (count == 4) { 16412ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller if (patternCharIndex == 2) { 16422ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller safeAppendWithMonthPattern(formatData.months, value, buf, (isLeapMonth!=0)? formatData.leapMonthPatterns[DateFormatSymbols.DT_LEAP_MONTH_PATTERN_FORMAT_WIDE]: null); 16432ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller capContextUsageType = DateFormatSymbols.CapitalizationContextUsage.MONTH_FORMAT; 16442ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } else { 16452ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller safeAppendWithMonthPattern(formatData.standaloneMonths, value, buf, (isLeapMonth!=0)? formatData.leapMonthPatterns[DateFormatSymbols.DT_LEAP_MONTH_PATTERN_STANDALONE_WIDE]: null); 16462ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller capContextUsageType = DateFormatSymbols.CapitalizationContextUsage.MONTH_STANDALONE; 16472ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } 16482ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } else if (count == 3) { 16492ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller if (patternCharIndex == 2) { 16502ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller safeAppendWithMonthPattern(formatData.shortMonths, value, buf, (isLeapMonth!=0)? formatData.leapMonthPatterns[DateFormatSymbols.DT_LEAP_MONTH_PATTERN_FORMAT_ABBREV]: null); 16512ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller capContextUsageType = DateFormatSymbols.CapitalizationContextUsage.MONTH_FORMAT; 16522ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } else { 16532ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller safeAppendWithMonthPattern(formatData.standaloneShortMonths, value, buf, (isLeapMonth!=0)? formatData.leapMonthPatterns[DateFormatSymbols.DT_LEAP_MONTH_PATTERN_STANDALONE_ABBREV]: null); 16542ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller capContextUsageType = DateFormatSymbols.CapitalizationContextUsage.MONTH_STANDALONE; 16552ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } 16562ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } else { 16572ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller StringBuffer monthNumber = new StringBuffer(); 16582ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller zeroPaddingNumber(currentNumberFormat, monthNumber, value+1, count, maxIntCount); 16592ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller String[] monthNumberStrings = new String[1]; 16602ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller monthNumberStrings[0] = monthNumber.toString(); 16612ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller safeAppendWithMonthPattern(monthNumberStrings, 0, buf, (isLeapMonth!=0)? formatData.leapMonthPatterns[DateFormatSymbols.DT_LEAP_MONTH_PATTERN_NUMERIC]: null); 16622ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } 16632ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller break; 16642ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller case 4: // 'k' - HOUR_OF_DAY (1..24) 16652ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller if (value == 0) { 16662ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller zeroPaddingNumber(currentNumberFormat,buf, 16672ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller cal.getMaximum(Calendar.HOUR_OF_DAY)+1, 16682ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller count, maxIntCount); 16692ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } else { 16702ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller zeroPaddingNumber(currentNumberFormat,buf, value, count, maxIntCount); 16712ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } 16722ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller break; 16732ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller case 8: // 'S' - FRACTIONAL_SECOND 16742ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller // Fractional seconds left-justify 16752ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller { 16762ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller numberFormat.setMinimumIntegerDigits(Math.min(3, count)); 16772ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller numberFormat.setMaximumIntegerDigits(maxIntCount); 16782ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller if (count == 1) { 16792ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller value /= 100; 16802ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } else if (count == 2) { 16812ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller value /= 10; 16822ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } 16832ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller FieldPosition p = new FieldPosition(-1); 1684f86f25d102340da66b9c7cb6b2d5ecdc0de43ecfFredrik Roubert numberFormat.format(value, buf, p); 16852ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller if (count > 3) { 16862ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller numberFormat.setMinimumIntegerDigits(count - 3); 16872ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller numberFormat.format(0L, buf, p); 16882ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } 16892ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } 16902ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller break; 16912ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller case 19: // 'e' - DOW_LOCAL (use DOW_LOCAL for numeric, DAY_OF_WEEK for format names) 16922ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller if (count < 3) { 16932ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller zeroPaddingNumber(currentNumberFormat,buf, value, count, maxIntCount); 16942ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller break; 16952ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } 16962ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller // For alpha day-of-week, we don't want DOW_LOCAL, 16972ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller // we need the standard DAY_OF_WEEK. 16982ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller value = cal.get(Calendar.DAY_OF_WEEK); 16992ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller // fall through, do not break here 17002ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller case 9: // 'E' - DAY_OF_WEEK 17012ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller if (count == 5) { 17022ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller safeAppend(formatData.narrowWeekdays, value, buf); 17032ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller capContextUsageType = DateFormatSymbols.CapitalizationContextUsage.DAY_NARROW; 17042ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } else if (count == 4) { 17052ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller safeAppend(formatData.weekdays, value, buf); 17062ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller capContextUsageType = DateFormatSymbols.CapitalizationContextUsage.DAY_FORMAT; 17072ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } else if (count == 6 && formatData.shorterWeekdays != null) { 17082ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller safeAppend(formatData.shorterWeekdays, value, buf); 17092ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller capContextUsageType = DateFormatSymbols.CapitalizationContextUsage.DAY_FORMAT; 17102ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } else {// count <= 3, use abbreviated form if exists 17112ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller safeAppend(formatData.shortWeekdays, value, buf); 17122ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller capContextUsageType = DateFormatSymbols.CapitalizationContextUsage.DAY_FORMAT; 17132ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } 17142ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller break; 17152ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller case 14: // 'a' - AM_PM 17162ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller // formatData.ampmsNarrow may be null when deserializing DateFormatSymbolsfrom old version 17172ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller if (count < 5 || formatData.ampmsNarrow == null) { 17182ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller safeAppend(formatData.ampms, value, buf); 17192ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } else { 17202ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller safeAppend(formatData.ampmsNarrow, value, buf); 17212ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } 17222ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller break; 17232ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller case 15: // 'h' - HOUR (1..12) 17242ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller if (value == 0) { 17252ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller zeroPaddingNumber(currentNumberFormat,buf, 17262ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller cal.getLeastMaximum(Calendar.HOUR)+1, 17272ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller count, maxIntCount); 17282ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } else { 17292ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller zeroPaddingNumber(currentNumberFormat,buf, value, count, maxIntCount); 17302ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } 17312ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller break; 17322ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller 17332ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller case 17: // 'z' - TIMEZONE_FIELD 17342ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller if (count < 4) { 17352ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller // "z", "zz", "zzz" 17362ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller result = tzFormat().format(Style.SPECIFIC_SHORT, tz, date); 17372ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller capContextUsageType = DateFormatSymbols.CapitalizationContextUsage.METAZONE_SHORT; 17382ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } else { 17392ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller result = tzFormat().format(Style.SPECIFIC_LONG, tz, date); 17402ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller capContextUsageType = DateFormatSymbols.CapitalizationContextUsage.METAZONE_LONG; 17412ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } 17422ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller buf.append(result); 17432ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller break; 17442ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller case 23: // 'Z' - TIMEZONE_RFC_FIELD 17452ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller if (count < 4) { 17462ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller // RFC822 format - equivalent to ISO 8601 local offset fixed width format 17472ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller result = tzFormat().format(Style.ISO_BASIC_LOCAL_FULL, tz, date); 17482ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } else if (count == 5) { 17492ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller // ISO 8601 extended format 17502ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller result = tzFormat().format(Style.ISO_EXTENDED_FULL, tz, date); 17512ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } else { 17522ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller // long form, localized GMT pattern 17532ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller result = tzFormat().format(Style.LOCALIZED_GMT, tz, date); 17542ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } 17552ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller buf.append(result); 17562ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller break; 17572ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller case 24: // 'v' - TIMEZONE_GENERIC_FIELD 17582ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller if (count == 1) { 17592ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller // "v" 17602ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller result = tzFormat().format(Style.GENERIC_SHORT, tz, date); 17612ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller capContextUsageType = DateFormatSymbols.CapitalizationContextUsage.METAZONE_SHORT; 17622ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } else if (count == 4) { 17632ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller // "vvvv" 17642ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller result = tzFormat().format(Style.GENERIC_LONG, tz, date); 17652ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller capContextUsageType = DateFormatSymbols.CapitalizationContextUsage.METAZONE_LONG; 17662ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } 17672ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller buf.append(result); 17682ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller break; 17692ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller case 29: // 'V' - TIMEZONE_SPECIAL_FIELD 17702ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller if (count == 1) { 17712ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller // "V" 17722ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller result = tzFormat().format(Style.ZONE_ID_SHORT, tz, date); 17732ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } else if (count == 2) { 17742ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller // "VV" 17752ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller result = tzFormat().format(Style.ZONE_ID, tz, date); 17762ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } else if (count == 3) { 17772ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller // "VVV" 17782ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller result = tzFormat().format(Style.EXEMPLAR_LOCATION, tz, date); 17792ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } else if (count == 4) { 17802ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller // "VVVV" 17812ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller result = tzFormat().format(Style.GENERIC_LOCATION, tz, date); 17822ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller capContextUsageType = DateFormatSymbols.CapitalizationContextUsage.ZONE_LONG; 17832ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } 17842ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller buf.append(result); 17852ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller break; 17862ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller case 31: // 'O' - TIMEZONE_LOCALIZED_GMT_OFFSET_FIELD 17872ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller if (count == 1) { 17882ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller // "O" - Short Localized GMT format 17892ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller result = tzFormat().format(Style.LOCALIZED_GMT_SHORT, tz, date); 17902ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } else if (count == 4) { 17912ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller // "OOOO" - Localized GMT format 17922ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller result = tzFormat().format(Style.LOCALIZED_GMT, tz, date); 17932ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } 17942ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller buf.append(result); 17952ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller break; 17962ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller case 32: // 'X' - TIMEZONE_ISO_FIELD 17972ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller if (count == 1) { 17982ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller // "X" - ISO Basic/Short 17992ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller result = tzFormat().format(Style.ISO_BASIC_SHORT, tz, date); 18002ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } else if (count == 2) { 18012ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller // "XX" - ISO Basic/Fixed 18022ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller result = tzFormat().format(Style.ISO_BASIC_FIXED, tz, date); 18032ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } else if (count == 3) { 18042ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller // "XXX" - ISO Extended/Fixed 18052ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller result = tzFormat().format(Style.ISO_EXTENDED_FIXED, tz, date); 18062ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } else if (count == 4) { 18072ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller // "XXXX" - ISO Basic/Optional second field 18082ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller result = tzFormat().format(Style.ISO_BASIC_FULL, tz, date); 18092ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } else if (count == 5) { 18102ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller // "XXXXX" - ISO Extended/Optional second field 18112ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller result = tzFormat().format(Style.ISO_EXTENDED_FULL, tz, date); 18122ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } 18132ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller buf.append(result); 18142ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller break; 18152ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller case 33: // 'x' - TIMEZONE_ISO_LOCAL_FIELD 18162ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller if (count == 1) { 18172ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller // "x" - ISO Local Basic/Short 18182ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller result = tzFormat().format(Style.ISO_BASIC_LOCAL_SHORT, tz, date); 18192ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } else if (count == 2) { 18202ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller // "x" - ISO Local Basic/Fixed 18212ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller result = tzFormat().format(Style.ISO_BASIC_LOCAL_FIXED, tz, date); 18222ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } else if (count == 3) { 18232ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller // "xxx" - ISO Local Extended/Fixed 18242ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller result = tzFormat().format(Style.ISO_EXTENDED_LOCAL_FIXED, tz, date); 18252ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } else if (count == 4) { 18262ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller // "xxxx" - ISO Local Basic/Optional second field 18272ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller result = tzFormat().format(Style.ISO_BASIC_LOCAL_FULL, tz, date); 18282ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } else if (count == 5) { 18292ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller // "xxxxx" - ISO Local Extended/Optional second field 18302ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller result = tzFormat().format(Style.ISO_EXTENDED_LOCAL_FULL, tz, date); 18312ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } 18322ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller buf.append(result); 18332ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller break; 18342ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller 18352ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller case 25: // 'c' - STANDALONE DAY (use DOW_LOCAL for numeric, DAY_OF_WEEK for standalone) 18362ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller if (count < 3) { 18372ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller zeroPaddingNumber(currentNumberFormat,buf, value, 1, maxIntCount); 18382ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller break; 18392ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } 18402ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller // For alpha day-of-week, we don't want DOW_LOCAL, 18412ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller // we need the standard DAY_OF_WEEK. 18422ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller value = cal.get(Calendar.DAY_OF_WEEK); 18432ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller if (count == 5) { 18442ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller safeAppend(formatData.standaloneNarrowWeekdays, value, buf); 18452ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller capContextUsageType = DateFormatSymbols.CapitalizationContextUsage.DAY_NARROW; 18462ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } else if (count == 4) { 18472ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller safeAppend(formatData.standaloneWeekdays, value, buf); 18482ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller capContextUsageType = DateFormatSymbols.CapitalizationContextUsage.DAY_STANDALONE; 18492ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } else if (count == 6 && formatData.standaloneShorterWeekdays != null) { 18502ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller safeAppend(formatData.standaloneShorterWeekdays, value, buf); 18512ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller capContextUsageType = DateFormatSymbols.CapitalizationContextUsage.DAY_STANDALONE; 18522ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } else { // count == 3 18532ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller safeAppend(formatData.standaloneShortWeekdays, value, buf); 18542ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller capContextUsageType = DateFormatSymbols.CapitalizationContextUsage.DAY_STANDALONE; 18552ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } 18562ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller break; 18572ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller case 27: // 'Q' - QUARTER 18582ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller if (count >= 4) { 18592ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller safeAppend(formatData.quarters, value/3, buf); 18602ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } else if (count == 3) { 18612ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller safeAppend(formatData.shortQuarters, value/3, buf); 18622ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } else { 18632ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller zeroPaddingNumber(currentNumberFormat,buf, (value/3)+1, count, maxIntCount); 18642ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } 18652ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller break; 18662ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller case 28: // 'q' - STANDALONE QUARTER 18672ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller if (count >= 4) { 18682ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller safeAppend(formatData.standaloneQuarters, value/3, buf); 18692ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } else if (count == 3) { 18702ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller safeAppend(formatData.standaloneShortQuarters, value/3, buf); 18712ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } else { 18722ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller zeroPaddingNumber(currentNumberFormat,buf, (value/3)+1, count, maxIntCount); 18732ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } 18742ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller break; 18751c8a530973739aafa823d758240d2cd5dad96fe3Fredrik Roubert case 35: // 'b' - am/pm/noon/midnight 18761c8a530973739aafa823d758240d2cd5dad96fe3Fredrik Roubert { 18771c8a530973739aafa823d758240d2cd5dad96fe3Fredrik Roubert // Note: "midnight" can be ambiguous as to whether it refers to beginning of day or end of day. 18781c8a530973739aafa823d758240d2cd5dad96fe3Fredrik Roubert // For ICU 57 output of "midnight" is temporarily suppressed. 18791c8a530973739aafa823d758240d2cd5dad96fe3Fredrik Roubert 18801c8a530973739aafa823d758240d2cd5dad96fe3Fredrik Roubert int hour = cal.get(Calendar.HOUR_OF_DAY); 18811c8a530973739aafa823d758240d2cd5dad96fe3Fredrik Roubert String toAppend = null; 18821c8a530973739aafa823d758240d2cd5dad96fe3Fredrik Roubert 18831c8a530973739aafa823d758240d2cd5dad96fe3Fredrik Roubert // For "midnight" and "noon": 18841c8a530973739aafa823d758240d2cd5dad96fe3Fredrik Roubert // Time, as displayed, must be exactly noon or midnight. 18851c8a530973739aafa823d758240d2cd5dad96fe3Fredrik Roubert // This means minutes and seconds, if present, must be zero. 18861c8a530973739aafa823d758240d2cd5dad96fe3Fredrik Roubert if ((/*hour == 0 ||*/ hour == 12) && 18871c8a530973739aafa823d758240d2cd5dad96fe3Fredrik Roubert (!hasMinute || cal.get(Calendar.MINUTE) == 0) && 18881c8a530973739aafa823d758240d2cd5dad96fe3Fredrik Roubert (!hasSecond || cal.get(Calendar.SECOND) == 0)) { 18891c8a530973739aafa823d758240d2cd5dad96fe3Fredrik Roubert // Stealing am/pm value to use as our array index. 18901c8a530973739aafa823d758240d2cd5dad96fe3Fredrik Roubert // It works out: am/midnight are both 0, pm/noon are both 1, 18911c8a530973739aafa823d758240d2cd5dad96fe3Fredrik Roubert // 12 am is 12 midnight, and 12 pm is 12 noon. 18921c8a530973739aafa823d758240d2cd5dad96fe3Fredrik Roubert value = cal.get(Calendar.AM_PM); 18931c8a530973739aafa823d758240d2cd5dad96fe3Fredrik Roubert 18941c8a530973739aafa823d758240d2cd5dad96fe3Fredrik Roubert if (count == 3) { 18951c8a530973739aafa823d758240d2cd5dad96fe3Fredrik Roubert toAppend = formatData.abbreviatedDayPeriods[value]; 18961c8a530973739aafa823d758240d2cd5dad96fe3Fredrik Roubert } else if (count == 4 || count > 5) { 18971c8a530973739aafa823d758240d2cd5dad96fe3Fredrik Roubert toAppend = formatData.wideDayPeriods[value]; 18981c8a530973739aafa823d758240d2cd5dad96fe3Fredrik Roubert } else { // count == 5 18991c8a530973739aafa823d758240d2cd5dad96fe3Fredrik Roubert toAppend = formatData.narrowDayPeriods[value]; 19001c8a530973739aafa823d758240d2cd5dad96fe3Fredrik Roubert } 19011c8a530973739aafa823d758240d2cd5dad96fe3Fredrik Roubert } 19021c8a530973739aafa823d758240d2cd5dad96fe3Fredrik Roubert 19031c8a530973739aafa823d758240d2cd5dad96fe3Fredrik Roubert if (toAppend == null) { 19041c8a530973739aafa823d758240d2cd5dad96fe3Fredrik Roubert // Time isn't exactly midnight or noon (as displayed) or localized string doesn't 19051c8a530973739aafa823d758240d2cd5dad96fe3Fredrik Roubert // exist for requested period. Fall back to am/pm instead. 19061c8a530973739aafa823d758240d2cd5dad96fe3Fredrik Roubert subFormat(buf, 'a', count, beginOffset, fieldNum, capitalizationContext, pos, cal); 19071c8a530973739aafa823d758240d2cd5dad96fe3Fredrik Roubert } else { 19081c8a530973739aafa823d758240d2cd5dad96fe3Fredrik Roubert buf.append(toAppend); 19091c8a530973739aafa823d758240d2cd5dad96fe3Fredrik Roubert } 19101c8a530973739aafa823d758240d2cd5dad96fe3Fredrik Roubert 19111c8a530973739aafa823d758240d2cd5dad96fe3Fredrik Roubert break; 19121c8a530973739aafa823d758240d2cd5dad96fe3Fredrik Roubert } 19131c8a530973739aafa823d758240d2cd5dad96fe3Fredrik Roubert case 36: // 'B' - flexible day period 19141c8a530973739aafa823d758240d2cd5dad96fe3Fredrik Roubert { 19151c8a530973739aafa823d758240d2cd5dad96fe3Fredrik Roubert // TODO: Maybe fetch the DayperiodRules during initialization (instead of at the first 19161c8a530973739aafa823d758240d2cd5dad96fe3Fredrik Roubert // loading of an instance) if a relevant pattern character (b or B) is used. 19171c8a530973739aafa823d758240d2cd5dad96fe3Fredrik Roubert DayPeriodRules ruleSet = DayPeriodRules.getInstance(getLocale()); 19181c8a530973739aafa823d758240d2cd5dad96fe3Fredrik Roubert if (ruleSet == null) { 19191c8a530973739aafa823d758240d2cd5dad96fe3Fredrik Roubert // Data doesn't exist for the locale we're looking for. 19201c8a530973739aafa823d758240d2cd5dad96fe3Fredrik Roubert // Fall back to am/pm. 19211c8a530973739aafa823d758240d2cd5dad96fe3Fredrik Roubert subFormat(buf, 'a', count, beginOffset, fieldNum, capitalizationContext, pos, cal); 19221c8a530973739aafa823d758240d2cd5dad96fe3Fredrik Roubert break; 19231c8a530973739aafa823d758240d2cd5dad96fe3Fredrik Roubert } 19241c8a530973739aafa823d758240d2cd5dad96fe3Fredrik Roubert 19251c8a530973739aafa823d758240d2cd5dad96fe3Fredrik Roubert // Get current display time. 19261c8a530973739aafa823d758240d2cd5dad96fe3Fredrik Roubert int hour = cal.get(Calendar.HOUR_OF_DAY); 19271c8a530973739aafa823d758240d2cd5dad96fe3Fredrik Roubert int minute = 0; 19281c8a530973739aafa823d758240d2cd5dad96fe3Fredrik Roubert int second = 0; 19291c8a530973739aafa823d758240d2cd5dad96fe3Fredrik Roubert if (hasMinute) { minute = cal.get(Calendar.MINUTE); } 19301c8a530973739aafa823d758240d2cd5dad96fe3Fredrik Roubert if (hasSecond) { second = cal.get(Calendar.SECOND); } 19311c8a530973739aafa823d758240d2cd5dad96fe3Fredrik Roubert 19321c8a530973739aafa823d758240d2cd5dad96fe3Fredrik Roubert // Determine day period. 19331c8a530973739aafa823d758240d2cd5dad96fe3Fredrik Roubert DayPeriodRules.DayPeriod periodType; 19341c8a530973739aafa823d758240d2cd5dad96fe3Fredrik Roubert if (hour == 0 && minute == 0 && second == 0 && ruleSet.hasMidnight()) { 19351c8a530973739aafa823d758240d2cd5dad96fe3Fredrik Roubert periodType = DayPeriodRules.DayPeriod.MIDNIGHT; 19361c8a530973739aafa823d758240d2cd5dad96fe3Fredrik Roubert } else if (hour == 12 && minute == 0 && second == 0 && ruleSet.hasNoon()) { 19371c8a530973739aafa823d758240d2cd5dad96fe3Fredrik Roubert periodType = DayPeriodRules.DayPeriod.NOON; 19381c8a530973739aafa823d758240d2cd5dad96fe3Fredrik Roubert } else { 19391c8a530973739aafa823d758240d2cd5dad96fe3Fredrik Roubert periodType = ruleSet.getDayPeriodForHour(hour); 19401c8a530973739aafa823d758240d2cd5dad96fe3Fredrik Roubert } 19411c8a530973739aafa823d758240d2cd5dad96fe3Fredrik Roubert 19421c8a530973739aafa823d758240d2cd5dad96fe3Fredrik Roubert // Note: "midnight" can be ambiguous as to whether it refers to beginning of day or end of day. 19431c8a530973739aafa823d758240d2cd5dad96fe3Fredrik Roubert // For ICU 57 output of "midnight" is temporarily suppressed. 19441c8a530973739aafa823d758240d2cd5dad96fe3Fredrik Roubert 19451c8a530973739aafa823d758240d2cd5dad96fe3Fredrik Roubert // Rule set exists, therefore periodType can't be null. 19461c8a530973739aafa823d758240d2cd5dad96fe3Fredrik Roubert // Get localized string. 19471c8a530973739aafa823d758240d2cd5dad96fe3Fredrik Roubert assert(periodType != null); 19481c8a530973739aafa823d758240d2cd5dad96fe3Fredrik Roubert String toAppend = null; 19491c8a530973739aafa823d758240d2cd5dad96fe3Fredrik Roubert int index; 19501c8a530973739aafa823d758240d2cd5dad96fe3Fredrik Roubert 19511c8a530973739aafa823d758240d2cd5dad96fe3Fredrik Roubert if (periodType != DayPeriodRules.DayPeriod.AM && periodType != DayPeriodRules.DayPeriod.PM && 19521c8a530973739aafa823d758240d2cd5dad96fe3Fredrik Roubert periodType != DayPeriodRules.DayPeriod.MIDNIGHT) { 19531c8a530973739aafa823d758240d2cd5dad96fe3Fredrik Roubert index = periodType.ordinal(); 19541c8a530973739aafa823d758240d2cd5dad96fe3Fredrik Roubert if (count <= 3) { 19551c8a530973739aafa823d758240d2cd5dad96fe3Fredrik Roubert toAppend = formatData.abbreviatedDayPeriods[index]; // i.e. short 19561c8a530973739aafa823d758240d2cd5dad96fe3Fredrik Roubert } else if (count == 4 || count > 5) { 19571c8a530973739aafa823d758240d2cd5dad96fe3Fredrik Roubert toAppend = formatData.wideDayPeriods[index]; 19581c8a530973739aafa823d758240d2cd5dad96fe3Fredrik Roubert } else { // count == 5 19591c8a530973739aafa823d758240d2cd5dad96fe3Fredrik Roubert toAppend = formatData.narrowDayPeriods[index]; 19601c8a530973739aafa823d758240d2cd5dad96fe3Fredrik Roubert } 19611c8a530973739aafa823d758240d2cd5dad96fe3Fredrik Roubert } 19621c8a530973739aafa823d758240d2cd5dad96fe3Fredrik Roubert 19631c8a530973739aafa823d758240d2cd5dad96fe3Fredrik Roubert 19641c8a530973739aafa823d758240d2cd5dad96fe3Fredrik Roubert // Fallback schedule: 19651c8a530973739aafa823d758240d2cd5dad96fe3Fredrik Roubert // Midnight/Noon -> General Periods -> AM/PM. 19661c8a530973739aafa823d758240d2cd5dad96fe3Fredrik Roubert 19671c8a530973739aafa823d758240d2cd5dad96fe3Fredrik Roubert // Midnight/Noon -> General Periods. 19681c8a530973739aafa823d758240d2cd5dad96fe3Fredrik Roubert if (toAppend == null && 19691c8a530973739aafa823d758240d2cd5dad96fe3Fredrik Roubert (periodType == DayPeriodRules.DayPeriod.MIDNIGHT || 19701c8a530973739aafa823d758240d2cd5dad96fe3Fredrik Roubert periodType == DayPeriodRules.DayPeriod.NOON)) { 19711c8a530973739aafa823d758240d2cd5dad96fe3Fredrik Roubert periodType = ruleSet.getDayPeriodForHour(hour); 19721c8a530973739aafa823d758240d2cd5dad96fe3Fredrik Roubert index = periodType.ordinal(); 19731c8a530973739aafa823d758240d2cd5dad96fe3Fredrik Roubert 19741c8a530973739aafa823d758240d2cd5dad96fe3Fredrik Roubert if (count <= 3) { 19751c8a530973739aafa823d758240d2cd5dad96fe3Fredrik Roubert toAppend = formatData.abbreviatedDayPeriods[index]; // i.e. short 19761c8a530973739aafa823d758240d2cd5dad96fe3Fredrik Roubert } else if (count == 4 || count > 5) { 19771c8a530973739aafa823d758240d2cd5dad96fe3Fredrik Roubert toAppend = formatData.wideDayPeriods[index]; 19781c8a530973739aafa823d758240d2cd5dad96fe3Fredrik Roubert } else { // count == 5 19791c8a530973739aafa823d758240d2cd5dad96fe3Fredrik Roubert toAppend = formatData.narrowDayPeriods[index]; 19801c8a530973739aafa823d758240d2cd5dad96fe3Fredrik Roubert } 19811c8a530973739aafa823d758240d2cd5dad96fe3Fredrik Roubert } 19821c8a530973739aafa823d758240d2cd5dad96fe3Fredrik Roubert 19831c8a530973739aafa823d758240d2cd5dad96fe3Fredrik Roubert // General Periods -> AM/PM. 19841c8a530973739aafa823d758240d2cd5dad96fe3Fredrik Roubert if (periodType == DayPeriodRules.DayPeriod.AM || 19851c8a530973739aafa823d758240d2cd5dad96fe3Fredrik Roubert periodType == DayPeriodRules.DayPeriod.PM || 19861c8a530973739aafa823d758240d2cd5dad96fe3Fredrik Roubert toAppend == null) { 19871c8a530973739aafa823d758240d2cd5dad96fe3Fredrik Roubert subFormat(buf, 'a', count, beginOffset, fieldNum, capitalizationContext, pos, cal); 19881c8a530973739aafa823d758240d2cd5dad96fe3Fredrik Roubert } 19891c8a530973739aafa823d758240d2cd5dad96fe3Fredrik Roubert else { 19901c8a530973739aafa823d758240d2cd5dad96fe3Fredrik Roubert buf.append(toAppend); 19911c8a530973739aafa823d758240d2cd5dad96fe3Fredrik Roubert } 19921c8a530973739aafa823d758240d2cd5dad96fe3Fredrik Roubert 19931c8a530973739aafa823d758240d2cd5dad96fe3Fredrik Roubert break; 19941c8a530973739aafa823d758240d2cd5dad96fe3Fredrik Roubert } 19951c8a530973739aafa823d758240d2cd5dad96fe3Fredrik Roubert case 37: // TIME SEPARATOR (no pattern character currently defined, we should 19961c8a530973739aafa823d758240d2cd5dad96fe3Fredrik Roubert // not get here but leave support in for future definition. 19972ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller buf.append(formatData.getTimeSeparatorString()); 19982ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller break; 19992ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller default: 20002ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller // case 3: // 'd' - DATE 20012ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller // case 5: // 'H' - HOUR_OF_DAY (0..23) 20022ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller // case 6: // 'm' - MINUTE 20032ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller // case 7: // 's' - SECOND 20042ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller // case 10: // 'D' - DAY_OF_YEAR 20052ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller // case 11: // 'F' - DAY_OF_WEEK_IN_MONTH 20062ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller // case 12: // 'w' - WEEK_OF_YEAR 20072ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller // case 13: // 'W' - WEEK_OF_MONTH 20082ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller // case 16: // 'K' - HOUR (0..11) 20092ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller // case 20: // 'u' - EXTENDED_YEAR 20102ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller // case 21: // 'g' - JULIAN_DAY 20112ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller // case 22: // 'A' - MILLISECONDS_IN_DAY 20122ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller 20132ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller zeroPaddingNumber(currentNumberFormat,buf, value, count, maxIntCount); 20142ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller break; 20152ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } // switch (patternCharIndex) 20162ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller 20172ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller if (fieldNum == 0 && capitalizationContext != null && UCharacter.isLowerCase(buf.codePointAt(bufstart))) { 20182ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller boolean titlecase = false; 20192ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller switch (capitalizationContext) { 20202ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller case CAPITALIZATION_FOR_BEGINNING_OF_SENTENCE: 20212ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller titlecase = true; 20222ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller break; 20232ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller case CAPITALIZATION_FOR_UI_LIST_OR_MENU: 20242ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller case CAPITALIZATION_FOR_STANDALONE: 20252ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller if (formatData.capitalization != null) { 20262ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller boolean[] transforms = formatData.capitalization.get(capContextUsageType); 20272ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller titlecase = (capitalizationContext==DisplayContext.CAPITALIZATION_FOR_UI_LIST_OR_MENU)? 20282ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller transforms[0]: transforms[1]; 20292ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } 20302ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller break; 20312ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller default: 20322ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller break; 20332ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } 20342ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller if (titlecase) { 20352ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller if (capitalizationBrkIter == null) { 20362ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller // should only happen when deserializing, etc. 20372ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller capitalizationBrkIter = BreakIterator.getSentenceInstance(locale); 20382ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } 20392ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller String firstField = buf.substring(bufstart); // bufstart or beginOffset, should be the same 20402ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller String firstFieldTitleCase = UCharacter.toTitleCase(locale, firstField, capitalizationBrkIter, 20412ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller UCharacter.TITLECASE_NO_LOWERCASE | UCharacter.TITLECASE_NO_BREAK_ADJUSTMENT); 20422ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller buf.replace(bufstart, buf.length(), firstFieldTitleCase); 20432ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } 20442ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } 20452ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller 20462ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller // Set the FieldPosition (for the first occurrence only) 20472ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller if (pos.getBeginIndex() == pos.getEndIndex()) { 20482ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller if (pos.getField() == PATTERN_INDEX_TO_DATE_FORMAT_FIELD[patternCharIndex]) { 20492ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller pos.setBeginIndex(beginOffset); 20502ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller pos.setEndIndex(beginOffset + buf.length() - bufstart); 20512ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } else if (pos.getFieldAttribute() == 20522ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller PATTERN_INDEX_TO_DATE_FORMAT_ATTRIBUTE[patternCharIndex]) { 20532ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller pos.setBeginIndex(beginOffset); 20542ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller pos.setEndIndex(beginOffset + buf.length() - bufstart); 20552ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } 20562ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } 20572ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } 20582ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller 20592ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller private static void safeAppend(String[] array, int value, StringBuffer appendTo) { 20602ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller if (array != null && value >= 0 && value < array.length) { 20612ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller appendTo.append(array[value]); 20622ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } 20632ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } 20642ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller 20652ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller private static void safeAppendWithMonthPattern(String[] array, int value, StringBuffer appendTo, String monthPattern) { 20662ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller if (array != null && value >= 0 && value < array.length) { 20672ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller if (monthPattern == null) { 20682ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller appendTo.append(array[value]); 20692ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } else { 20701c8a530973739aafa823d758240d2cd5dad96fe3Fredrik Roubert String s = SimpleFormatterImpl.formatRawPattern(monthPattern, 1, 1, array[value]); 20711c8a530973739aafa823d758240d2cd5dad96fe3Fredrik Roubert appendTo.append(s); 20722ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } 20732ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } 20742ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } 20752ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller 20762ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller /* 20772ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * PatternItem store parsed date/time field pattern information. 20782ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller */ 20792ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller private static class PatternItem { 20802ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller final char type; 20812ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller final int length; 20822ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller final boolean isNumeric; 20832ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller 20842ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller PatternItem(char type, int length) { 20852ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller this.type = type; 20862ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller this.length = length; 20872ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller isNumeric = isNumeric(type, length); 20882ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } 20892ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } 20902ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller 20912ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller private static ICUCache<String, Object[]> PARSED_PATTERN_CACHE = 20922ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller new SimpleCache<String, Object[]>(); 20932ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller private transient Object[] patternItems; 20942ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller 20952ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller /* 20962ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * Returns parsed pattern items. Each item is either String or 20972ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * PatternItem. 20982ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller */ 20992ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller private Object[] getPatternItems() { 21002ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller if (patternItems != null) { 21012ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller return patternItems; 21022ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } 21032ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller 21042ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller patternItems = PARSED_PATTERN_CACHE.get(pattern); 21052ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller if (patternItems != null) { 21062ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller return patternItems; 21072ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } 21082ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller 21092ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller boolean isPrevQuote = false; 21102ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller boolean inQuote = false; 21112ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller StringBuilder text = new StringBuilder(); 21122ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller char itemType = 0; // 0 for string literal, otherwise date/time pattern character 21132ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller int itemLength = 1; 21142ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller 21152ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller List<Object> items = new ArrayList<Object>(); 21162ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller 21172ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller for (int i = 0; i < pattern.length(); i++) { 21182ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller char ch = pattern.charAt(i); 21192ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller if (ch == '\'') { 21202ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller if (isPrevQuote) { 21212ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller text.append('\''); 21222ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller isPrevQuote = false; 21232ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } else { 21242ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller isPrevQuote = true; 21252ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller if (itemType != 0) { 21262ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller items.add(new PatternItem(itemType, itemLength)); 21272ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller itemType = 0; 21282ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } 21292ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } 21302ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller inQuote = !inQuote; 21312ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } else { 21322ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller isPrevQuote = false; 21332ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller if (inQuote) { 21342ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller text.append(ch); 21352ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } else { 21362ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller if (isSyntaxChar(ch)) { 21372ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller // a date/time pattern character 21382ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller if (ch == itemType) { 21392ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller itemLength++; 21402ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } else { 21412ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller if (itemType == 0) { 21422ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller if (text.length() > 0) { 21432ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller items.add(text.toString()); 21442ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller text.setLength(0); 21452ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } 21462ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } else { 21472ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller items.add(new PatternItem(itemType, itemLength)); 21482ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } 21492ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller itemType = ch; 21502ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller itemLength = 1; 21512ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } 21522ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } else { 21532ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller // a string literal 21542ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller if (itemType != 0) { 21552ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller items.add(new PatternItem(itemType, itemLength)); 21562ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller itemType = 0; 21572ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } 21582ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller text.append(ch); 21592ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } 21602ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } 21612ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } 21622ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } 21632ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller // handle last item 21642ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller if (itemType == 0) { 21652ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller if (text.length() > 0) { 21662ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller items.add(text.toString()); 21672ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller text.setLength(0); 21682ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } 21692ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } else { 21702ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller items.add(new PatternItem(itemType, itemLength)); 21712ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } 21722ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller 21732ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller patternItems = items.toArray(new Object[items.size()]); 21742ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller 21752ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller PARSED_PATTERN_CACHE.put(pattern, patternItems); 21762ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller 21772ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller return patternItems; 21782ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } 21792ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller 21802ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller /** 21812ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * Internal high-speed method. Reuses a StringBuffer for results 21822ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * instead of creating a String on the heap for each call. 21832ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * @deprecated This API is ICU internal only. 218493cf604e9dd0525f15bc0a7450b2a35f3884c298Neil Fuller * @hide original deprecated declaration 2185836e6b40a94ec3fb7545a76cb072960442b7eee9Neil Fuller * @hide draft / provisional / internal are hidden on Android 21862ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller */ 21872ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller @Deprecated 21882ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller protected void zeroPaddingNumber(NumberFormat nf,StringBuffer buf, int value, 21892ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller int minDigits, int maxDigits) { 21902ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller // Note: Indian calendar uses negative value for a calendar 21912ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller // field. fastZeroPaddingNumber cannot handle negative numbers. 21922ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller // BTW, it looks like a design bug in the Indian calendar... 21932ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller if (useLocalZeroPaddingNumberFormat && value >= 0) { 21942ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller fastZeroPaddingNumber(buf, value, minDigits, maxDigits); 21952ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } else { 21962ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller nf.setMinimumIntegerDigits(minDigits); 21972ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller nf.setMaximumIntegerDigits(maxDigits); 21982ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller nf.format(value, buf, new FieldPosition(-1)); 21992ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } 22002ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } 22012ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller 22022ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller /** 22032ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * Overrides superclass method and 22041c8a530973739aafa823d758240d2cd5dad96fe3Fredrik Roubert * This method also clears per field NumberFormat instances 22051c8a530973739aafa823d758240d2cd5dad96fe3Fredrik Roubert * previously set by {@link #setNumberFormat(String, NumberFormat)} 22062ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller */ 2207f86f25d102340da66b9c7cb6b2d5ecdc0de43ecfFredrik Roubert @Override 22082ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller public void setNumberFormat(NumberFormat newNumberFormat) { 22092ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller // Override this method to update local zero padding number formatter 22102ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller super.setNumberFormat(newNumberFormat); 22112ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller initLocalZeroPaddingNumberFormat(); 22122ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller initializeTimeZoneFormat(true); 22132ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller 22142ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller if (numberFormatters != null) { 22152ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller numberFormatters = null; 22162ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } 22172ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller if (overrideMap != null) { 22182ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller overrideMap = null; 22192ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } 22202ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } 22212ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller 22222ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller /* 22232ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * Initializes transient fields for fast simple numeric formatting 22242ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * code. This method should be called whenever number format is updated. 22252ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller */ 22262ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller private void initLocalZeroPaddingNumberFormat() { 22272ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller if (numberFormat instanceof DecimalFormat) { 22282ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller decDigits = ((DecimalFormat)numberFormat).getDecimalFormatSymbols().getDigits(); 22292ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller useLocalZeroPaddingNumberFormat = true; 22302ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } else if (numberFormat instanceof DateNumberFormat) { 22312ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller decDigits = ((DateNumberFormat)numberFormat).getDigits(); 22322ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller useLocalZeroPaddingNumberFormat = true; 22332ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } else { 22342ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller useLocalZeroPaddingNumberFormat = false; 22352ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } 22362ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller 22372ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller if (useLocalZeroPaddingNumberFormat) { 22382ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller decimalBuf = new char[DECIMAL_BUF_SIZE]; 22392ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } 22402ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } 22412ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller 22422ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller // If true, use local version of zero padding number format 22432ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller private transient boolean useLocalZeroPaddingNumberFormat; 22442ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller private transient char[] decDigits; // read-only - can be shared by multiple instances 22452ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller private transient char[] decimalBuf; // mutable - one per instance 22462ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller private static final int DECIMAL_BUF_SIZE = 10; // sufficient for int numbers 22472ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller 22482ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller /* 22492ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * Lightweight zero padding integer number format function. 22502ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * 22512ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * Note: This implementation is almost equivalent to format method in DateNumberFormat. 22522ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * In the method zeroPaddingNumber above should be able to use the one in DateNumberFormat, 22532ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * but, it does not help IBM J9's JIT to optimize the performance much. In simple repeative 22542ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * date format test case, having local implementation is ~10% faster than using one in 22552ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * DateNumberFormat on IBM J9 VM. On Sun Hotspot VM, I do not see such difference. 22562ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * 22572ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * -Yoshito 22582ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller */ 22592ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller private void fastZeroPaddingNumber(StringBuffer buf, int value, int minDigits, int maxDigits) { 22602ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller int limit = decimalBuf.length < maxDigits ? decimalBuf.length : maxDigits; 22612ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller int index = limit - 1; 22622ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller while (true) { 22632ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller decimalBuf[index] = decDigits[(value % 10)]; 22642ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller value /= 10; 22652ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller if (index == 0 || value == 0) { 22662ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller break; 22672ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } 22682ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller index--; 22692ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } 22702ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller int padding = minDigits - (limit - index); 22712ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller while (padding > 0 && index > 0) { 22722ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller decimalBuf[--index] = decDigits[0]; 22732ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller padding--; 22742ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } 22752ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller while (padding > 0) { 22762ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller // when pattern width is longer than decimalBuf, need extra 22772ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller // leading zeros - ticke#7595 22782ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller buf.append(decDigits[0]); 22792ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller padding--; 22802ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } 22812ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller buf.append(decimalBuf, index, limit - index); 22822ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } 22832ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller 22842ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller /** 22852ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * Formats a number with the specified minimum and maximum number of digits. 22862ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller */ 22872ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller protected String zeroPaddingNumber(long value, int minDigits, int maxDigits) 22882ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller { 22892ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller numberFormat.setMinimumIntegerDigits(minDigits); 22902ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller numberFormat.setMaximumIntegerDigits(maxDigits); 22912ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller return numberFormat.format(value); 22922ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } 22932ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller 22942ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller /** 22952ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * Format characters that indicate numeric fields always. 22962ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller */ 22972ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller private static final String NUMERIC_FORMAT_CHARS = "ADdFgHhKkmrSsuWwYy"; 22982ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller 22992ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller /** 23002ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * Format characters that indicate numeric fields when pattern lengh 23012ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * is up to 2. 23022ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller */ 23032ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller private static final String NUMERIC_FORMAT_CHARS2 = "ceLMQq"; 23042ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller 23052ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller /** 23062ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * Return true if the given format character, occuring count 23072ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * times, represents a numeric field. 23082ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller */ 23092ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller private static final boolean isNumeric(char formatChar, int count) { 23102ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller return NUMERIC_FORMAT_CHARS.indexOf(formatChar) >= 0 23112ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller || (count <= 2 && NUMERIC_FORMAT_CHARS2.indexOf(formatChar) >= 0); 23122ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } 23132ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller 23142ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller /** 23152ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * Overrides DateFormat 23162ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * @see DateFormat 23172ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller */ 2318f86f25d102340da66b9c7cb6b2d5ecdc0de43ecfFredrik Roubert @Override 23192ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller public void parse(String text, Calendar cal, ParsePosition parsePos) 23202ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller { 23212ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller TimeZone backupTZ = null; 23222ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller Calendar resultCal = null; 23232ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller if (cal != calendar && !cal.getType().equals(calendar.getType())) { 23242ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller // Different calendar type 23252ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller // We use the time/zone from the input calendar, but 23262ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller // do not use the input calendar for field calculation. 23272ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller calendar.setTimeInMillis(cal.getTimeInMillis()); 23282ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller backupTZ = calendar.getTimeZone(); 23292ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller calendar.setTimeZone(cal.getTimeZone()); 23302ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller resultCal = cal; 23312ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller cal = calendar; 23322ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } 23332ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller 23342ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller int pos = parsePos.getIndex(); 23352ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller if(pos < 0) { 23362ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller parsePos.setErrorIndex(0); 23372ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller return; 23382ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } 23392ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller int start = pos; 23402ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller 23411c8a530973739aafa823d758240d2cd5dad96fe3Fredrik Roubert // Hold the day period until everything else is parsed, because we need 23421c8a530973739aafa823d758240d2cd5dad96fe3Fredrik Roubert // the hour to interpret time correctly. 23431c8a530973739aafa823d758240d2cd5dad96fe3Fredrik Roubert // Using an one-element array for output parameter. 23441c8a530973739aafa823d758240d2cd5dad96fe3Fredrik Roubert Output<DayPeriodRules.DayPeriod> dayPeriod = new Output<DayPeriodRules.DayPeriod>(null); 23451c8a530973739aafa823d758240d2cd5dad96fe3Fredrik Roubert 23462ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller Output<TimeType> tzTimeType = new Output<TimeType>(TimeType.UNKNOWN); 23472ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller boolean[] ambiguousYear = { false }; 23482ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller 23492ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller // item index for the first numeric field within a contiguous numeric run 23502ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller int numericFieldStart = -1; 23512ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller // item length for the first numeric field within a contiguous numeric run 23522ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller int numericFieldLength = 0; 23532ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller // start index of numeric text run in the input text 23542ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller int numericStartPos = 0; 23551c8a530973739aafa823d758240d2cd5dad96fe3Fredrik Roubert 23562ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller MessageFormat numericLeapMonthFormatter = null; 23572ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller if (formatData.leapMonthPatterns != null && formatData.leapMonthPatterns.length >= DateFormatSymbols.DT_MONTH_PATTERN_COUNT) { 23582ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller numericLeapMonthFormatter = new MessageFormat(formatData.leapMonthPatterns[DateFormatSymbols.DT_LEAP_MONTH_PATTERN_NUMERIC], locale); 23592ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } 23602ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller 23612ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller Object[] items = getPatternItems(); 23622ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller int i = 0; 23632ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller while (i < items.length) { 23642ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller if (items[i] instanceof PatternItem) { 23652ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller // Handle pattern field 23662ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller PatternItem field = (PatternItem)items[i]; 23672ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller if (field.isNumeric) { 23682ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller // Handle fields within a run of abutting numeric fields. Take 23692ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller // the pattern "HHmmss" as an example. We will try to parse 23702ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller // 2/2/2 characters of the input text, then if that fails, 23712ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller // 1/2/2. We only adjust the width of the leftmost field; the 23722ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller // others remain fixed. This allows "123456" => 12:34:56, but 23732ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller // "12345" => 1:23:45. Likewise, for the pattern "yyyyMMdd" we 23742ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller // try 4/2/2, 3/2/2, 2/2/2, and finally 1/2/2. 23752ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller if (numericFieldStart == -1) { 23762ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller // check if this field is followed by abutting another numeric field 23771c8a530973739aafa823d758240d2cd5dad96fe3Fredrik Roubert if ((i + 1) < items.length 23781c8a530973739aafa823d758240d2cd5dad96fe3Fredrik Roubert && (items[i + 1] instanceof PatternItem) 23792ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller && ((PatternItem)items[i + 1]).isNumeric) { 23802ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller // record the first numeric field within a numeric text run 23812ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller numericFieldStart = i; 23822ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller numericFieldLength = field.length; 23832ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller numericStartPos = pos; 23842ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } 23852ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } 23862ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } 23872ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller if (numericFieldStart != -1) { 23882ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller // Handle a numeric field within abutting numeric fields 23892ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller int len = field.length; 23902ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller if (numericFieldStart == i) { 23912ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller len = numericFieldLength; 23922ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } 23932ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller 23942ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller // Parse a numeric field 23952ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller pos = subParse(text, pos, field.type, len, 23962ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller true, false, ambiguousYear, cal, numericLeapMonthFormatter, tzTimeType); 23972ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller 23982ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller if (pos < 0) { 23992ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller // If the parse fails anywhere in the numeric run, back up to the 24002ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller // start of the run and use shorter pattern length for the first 24012ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller // numeric field. 24022ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller --numericFieldLength; 24032ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller if (numericFieldLength == 0) { 24042ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller // can not make shorter any more 24052ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller parsePos.setIndex(start); 24062ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller parsePos.setErrorIndex(pos); 24072ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller if (backupTZ != null) { 24082ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller calendar.setTimeZone(backupTZ); 24092ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } 24102ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller return; 24112ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } 24122ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller i = numericFieldStart; 24132ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller pos = numericStartPos; 24142ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller continue; 24152ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } 24162ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller 24172ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } else if (field.type != 'l') { // (SMALL LETTER L) obsolete pattern char just gets ignored 24182ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller // Handle a non-numeric field or a non-abutting numeric field 24192ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller numericFieldStart = -1; 24202ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller 24212ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller int s = pos; 24222ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller pos = subParse(text, pos, field.type, field.length, 24231c8a530973739aafa823d758240d2cd5dad96fe3Fredrik Roubert false, true, ambiguousYear, cal, numericLeapMonthFormatter, tzTimeType, dayPeriod); 24241c8a530973739aafa823d758240d2cd5dad96fe3Fredrik Roubert 24252ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller if (pos < 0) { 24262ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller if (pos == ISOSpecialEra) { 24272ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller // era not present, in special cases allow this to continue 24282ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller pos = s; 24292ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller 24301c8a530973739aafa823d758240d2cd5dad96fe3Fredrik Roubert if (i+1 < items.length) { 24311c8a530973739aafa823d758240d2cd5dad96fe3Fredrik Roubert 24322ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller String patl = null; 24332ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller // if it will cause a class cast exception to String, we can't use it 24342ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller try { 24352ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller patl = (String)items[i+1]; 24362ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } catch(ClassCastException cce) { 24372ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller parsePos.setIndex(start); 24382ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller parsePos.setErrorIndex(s); 24392ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller if (backupTZ != null) { 24402ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller calendar.setTimeZone(backupTZ); 24412ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } 24422ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller return; 24431c8a530973739aafa823d758240d2cd5dad96fe3Fredrik Roubert } 24441c8a530973739aafa823d758240d2cd5dad96fe3Fredrik Roubert 24452ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller // get next item in pattern 24462ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller if(patl == null) 24472ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller patl = (String)items[i+1]; 24482ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller int plen = patl.length(); 24492ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller int idx=0; 24501c8a530973739aafa823d758240d2cd5dad96fe3Fredrik Roubert 24511c8a530973739aafa823d758240d2cd5dad96fe3Fredrik Roubert // White space characters found in pattern. 24522ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller // Skip contiguous white spaces. 24532ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller while (idx < plen) { 24542ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller 24552ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller char pch = patl.charAt(idx); 24562ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller if (PatternProps.isWhiteSpace(pch)) 24572ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller idx++; 24582ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller else 24592ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller break; 24602ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } 24611c8a530973739aafa823d758240d2cd5dad96fe3Fredrik Roubert 24622ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller // if next item in pattern is all whitespace, skip it 24632ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller if (idx == plen) { 24642ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller i++; 24652ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } 24662ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller 24672ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } 24682ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } else { 24692ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller parsePos.setIndex(start); 24702ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller parsePos.setErrorIndex(s); 24712ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller if (backupTZ != null) { 24722ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller calendar.setTimeZone(backupTZ); 24732ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } 24742ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller return; 24751c8a530973739aafa823d758240d2cd5dad96fe3Fredrik Roubert } 24762ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } 24772ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller 24782ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } 24792ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } else { 24802ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller // Handle literal pattern text literal 24812ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller numericFieldStart = -1; 24822ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller boolean[] complete = new boolean[1]; 24832ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller pos = matchLiteral(text, pos, items, i, complete); 24842ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller if (!complete[0]) { 24852ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller // Set the position of mismatch 24862ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller parsePos.setIndex(start); 24872ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller parsePos.setErrorIndex(pos); 24882ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller if (backupTZ != null) { 24892ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller calendar.setTimeZone(backupTZ); 24902ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } 24912ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller return; 24922ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } 24932ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } 24942ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller ++i; 24952ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } 24961c8a530973739aafa823d758240d2cd5dad96fe3Fredrik Roubert 24972ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller // Special hack for trailing "." after non-numeric field. 24982ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller if (pos < text.length()) { 24992ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller char extra = text.charAt(pos); 25002ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller if (extra == '.' && getBooleanAttribute(DateFormat.BooleanAttribute.PARSE_ALLOW_WHITESPACE) && items.length != 0) { 25012ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller // only do if the last field is not numeric 25022ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller Object lastItem = items[items.length - 1]; 25032ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller if (lastItem instanceof PatternItem && !((PatternItem)lastItem).isNumeric) { 25042ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller pos++; // skip the extra "." 25052ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } 25062ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } 25072ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } 25082ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller 25091c8a530973739aafa823d758240d2cd5dad96fe3Fredrik Roubert // If dayPeriod is set, use it in conjunction with hour-of-day to determine am/pm. 25101c8a530973739aafa823d758240d2cd5dad96fe3Fredrik Roubert if (dayPeriod.value != null) { 25111c8a530973739aafa823d758240d2cd5dad96fe3Fredrik Roubert DayPeriodRules ruleSet = DayPeriodRules.getInstance(getLocale()); 25121c8a530973739aafa823d758240d2cd5dad96fe3Fredrik Roubert 25131c8a530973739aafa823d758240d2cd5dad96fe3Fredrik Roubert if (!cal.isSet(Calendar.HOUR) && !cal.isSet(Calendar.HOUR_OF_DAY)) { 25141c8a530973739aafa823d758240d2cd5dad96fe3Fredrik Roubert // If hour is not set, set time to the midpoint of current day period, overwriting 25151c8a530973739aafa823d758240d2cd5dad96fe3Fredrik Roubert // minutes if it's set. 25161c8a530973739aafa823d758240d2cd5dad96fe3Fredrik Roubert double midPoint = ruleSet.getMidPointForDayPeriod(dayPeriod.value); 25171c8a530973739aafa823d758240d2cd5dad96fe3Fredrik Roubert 25181c8a530973739aafa823d758240d2cd5dad96fe3Fredrik Roubert // Truncate midPoint toward zero to get the hour. 25191c8a530973739aafa823d758240d2cd5dad96fe3Fredrik Roubert // Any leftover means it was a half-hour. 25201c8a530973739aafa823d758240d2cd5dad96fe3Fredrik Roubert int midPointHour = (int) midPoint; 25211c8a530973739aafa823d758240d2cd5dad96fe3Fredrik Roubert int midPointMinute = (midPoint - midPointHour) > 0 ? 30 : 0; 25221c8a530973739aafa823d758240d2cd5dad96fe3Fredrik Roubert 25231c8a530973739aafa823d758240d2cd5dad96fe3Fredrik Roubert // No need to set am/pm because hour-of-day is set last therefore takes precedence. 25241c8a530973739aafa823d758240d2cd5dad96fe3Fredrik Roubert cal.set(Calendar.HOUR_OF_DAY, midPointHour); 25251c8a530973739aafa823d758240d2cd5dad96fe3Fredrik Roubert cal.set(Calendar.MINUTE, midPointMinute); 25261c8a530973739aafa823d758240d2cd5dad96fe3Fredrik Roubert } else { 25271c8a530973739aafa823d758240d2cd5dad96fe3Fredrik Roubert int hourOfDay; 25281c8a530973739aafa823d758240d2cd5dad96fe3Fredrik Roubert 25291c8a530973739aafa823d758240d2cd5dad96fe3Fredrik Roubert if (cal.isSet(Calendar.HOUR_OF_DAY)) { // Hour is parsed in 24-hour format. 25301c8a530973739aafa823d758240d2cd5dad96fe3Fredrik Roubert hourOfDay = cal.get(Calendar.HOUR_OF_DAY); 25311c8a530973739aafa823d758240d2cd5dad96fe3Fredrik Roubert } else { // Hour is parsed in 12-hour format. 25321c8a530973739aafa823d758240d2cd5dad96fe3Fredrik Roubert hourOfDay = cal.get(Calendar.HOUR); 25331c8a530973739aafa823d758240d2cd5dad96fe3Fredrik Roubert // cal.get() turns 12 to 0 for 12-hour time; change 0 to 12 25341c8a530973739aafa823d758240d2cd5dad96fe3Fredrik Roubert // so 0 unambiguously means a 24-hour time from above. 25351c8a530973739aafa823d758240d2cd5dad96fe3Fredrik Roubert if (hourOfDay == 0) { hourOfDay = 12; } 25361c8a530973739aafa823d758240d2cd5dad96fe3Fredrik Roubert } 25371c8a530973739aafa823d758240d2cd5dad96fe3Fredrik Roubert assert(0 <= hourOfDay && hourOfDay <= 23); 25381c8a530973739aafa823d758240d2cd5dad96fe3Fredrik Roubert 25391c8a530973739aafa823d758240d2cd5dad96fe3Fredrik Roubert 25401c8a530973739aafa823d758240d2cd5dad96fe3Fredrik Roubert // If hour-of-day is 0 or 13 thru 23 then input time in unambiguously in 24-hour format. 25411c8a530973739aafa823d758240d2cd5dad96fe3Fredrik Roubert if (hourOfDay == 0 || (13 <= hourOfDay && hourOfDay <= 23)) { 25421c8a530973739aafa823d758240d2cd5dad96fe3Fredrik Roubert // Make hour-of-day take precedence over (hour + am/pm) by setting it again. 25431c8a530973739aafa823d758240d2cd5dad96fe3Fredrik Roubert cal.set(Calendar.HOUR_OF_DAY, hourOfDay); 25441c8a530973739aafa823d758240d2cd5dad96fe3Fredrik Roubert } else { 25451c8a530973739aafa823d758240d2cd5dad96fe3Fredrik Roubert // We have a 12-hour time and need to choose between am and pm. 25461c8a530973739aafa823d758240d2cd5dad96fe3Fredrik Roubert // Behave as if dayPeriod spanned 6 hours each way from its center point. 25471c8a530973739aafa823d758240d2cd5dad96fe3Fredrik Roubert // This will parse correctly for consistent time + period (e.g. 10 at night) as 25481c8a530973739aafa823d758240d2cd5dad96fe3Fredrik Roubert // well as provide a reasonable recovery for inconsistent time + period (e.g. 25491c8a530973739aafa823d758240d2cd5dad96fe3Fredrik Roubert // 9 in the afternoon). 25501c8a530973739aafa823d758240d2cd5dad96fe3Fredrik Roubert 25511c8a530973739aafa823d758240d2cd5dad96fe3Fredrik Roubert // Assume current time is in the AM. 25521c8a530973739aafa823d758240d2cd5dad96fe3Fredrik Roubert // - Change 12 back to 0 for easier handling of 12am. 25531c8a530973739aafa823d758240d2cd5dad96fe3Fredrik Roubert // - Append minutes as fractional hours because e.g. 8:15 and 8:45 could be parsed 25541c8a530973739aafa823d758240d2cd5dad96fe3Fredrik Roubert // into different half-days if center of dayPeriod is at 14:30. 25551c8a530973739aafa823d758240d2cd5dad96fe3Fredrik Roubert // - cal.get(MINUTE) will return 0 if MINUTE is unset, which works. 25561c8a530973739aafa823d758240d2cd5dad96fe3Fredrik Roubert if (hourOfDay == 12) { hourOfDay = 0; } 25571c8a530973739aafa823d758240d2cd5dad96fe3Fredrik Roubert double currentHour = hourOfDay + cal.get(Calendar.MINUTE) / 60.0; 25581c8a530973739aafa823d758240d2cd5dad96fe3Fredrik Roubert double midPointHour = ruleSet.getMidPointForDayPeriod(dayPeriod.value); 25591c8a530973739aafa823d758240d2cd5dad96fe3Fredrik Roubert 25601c8a530973739aafa823d758240d2cd5dad96fe3Fredrik Roubert double hoursAheadMidPoint = currentHour - midPointHour; 25611c8a530973739aafa823d758240d2cd5dad96fe3Fredrik Roubert 25621c8a530973739aafa823d758240d2cd5dad96fe3Fredrik Roubert // Assume current time is in the AM. 25631c8a530973739aafa823d758240d2cd5dad96fe3Fredrik Roubert if (-6 <= hoursAheadMidPoint && hoursAheadMidPoint < 6) { 25641c8a530973739aafa823d758240d2cd5dad96fe3Fredrik Roubert // Assumption holds; set time as such. 25651c8a530973739aafa823d758240d2cd5dad96fe3Fredrik Roubert cal.set(Calendar.AM_PM, 0); 25661c8a530973739aafa823d758240d2cd5dad96fe3Fredrik Roubert } else { 25671c8a530973739aafa823d758240d2cd5dad96fe3Fredrik Roubert cal.set(Calendar.AM_PM, 1); 25681c8a530973739aafa823d758240d2cd5dad96fe3Fredrik Roubert } 25691c8a530973739aafa823d758240d2cd5dad96fe3Fredrik Roubert } 25701c8a530973739aafa823d758240d2cd5dad96fe3Fredrik Roubert } 25711c8a530973739aafa823d758240d2cd5dad96fe3Fredrik Roubert } 25721c8a530973739aafa823d758240d2cd5dad96fe3Fredrik Roubert 25732ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller // At this point the fields of Calendar have been set. Calendar 25742ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller // will fill in default values for missing fields when the time 25752ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller // is computed. 25762ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller 25772ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller parsePos.setIndex(pos); 25782ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller 25792ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller // This part is a problem: When we call parsedDate.after, we compute the time. 25802ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller // Take the date April 3 2004 at 2:30 am. When this is first set up, the year 25812ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller // will be wrong if we're parsing a 2-digit year pattern. It will be 1904. 25822ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller // April 3 1904 is a Sunday (unlike 2004) so it is the DST onset day. 2:30 am 25832ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller // is therefore an "impossible" time, since the time goes from 1:59 to 3:00 am 25842ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller // on that day. It is therefore parsed out to fields as 3:30 am. Then we 25852ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller // add 100 years, and get April 3 2004 at 3:30 am. Note that April 3 2004 is 25862ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller // a Saturday, so it can have a 2:30 am -- and it should. [LIU] 25872ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller /* 25882ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller Date parsedDate = cal.getTime(); 25892ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller if( ambiguousYear[0] && !parsedDate.after(getDefaultCenturyStart()) ) { 25902ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller cal.add(Calendar.YEAR, 100); 25912ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller parsedDate = cal.getTime(); 25922ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } 25932ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller */ 25942ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller // Because of the above condition, save off the fields in case we need to readjust. 25952ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller // The procedure we use here is not particularly efficient, but there is no other 25962ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller // way to do this given the API restrictions present in Calendar. We minimize 25972ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller // inefficiency by only performing this computation when it might apply, that is, 25982ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller // when the two-digit year is equal to the start year, and thus might fall at the 25992ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller // front or the back of the default century. This only works because we adjust 26002ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller // the year correctly to start with in other cases -- see subParse(). 26012ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller try { 26022ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller TimeType tztype = tzTimeType.value; 26032ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller if (ambiguousYear[0] || tztype != TimeType.UNKNOWN) { 26042ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller // We need a copy of the fields, and we need to avoid triggering a call to 26052ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller // complete(), which will recalculate the fields. Since we can't access 26062ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller // the fields[] array in Calendar, we clone the entire object. This will 26072ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller // stop working if Calendar.clone() is ever rewritten to call complete(). 26082ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller Calendar copy; 26092ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller if (ambiguousYear[0]) { // the two-digit year == the default start year 26102ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller copy = (Calendar)cal.clone(); 26112ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller Date parsedDate = copy.getTime(); 26122ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller if (parsedDate.before(getDefaultCenturyStart())) { 26132ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller // We can't use add here because that does a complete() first. 26142ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller cal.set(Calendar.YEAR, getDefaultCenturyStartYear() + 100); 26152ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } 26162ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } 26172ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller if (tztype != TimeType.UNKNOWN) { 26182ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller copy = (Calendar)cal.clone(); 26192ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller TimeZone tz = copy.getTimeZone(); 26202ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller BasicTimeZone btz = null; 26212ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller if (tz instanceof BasicTimeZone) { 26222ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller btz = (BasicTimeZone)tz; 26232ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } 26242ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller 26252ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller // Get local millis 26262ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller copy.set(Calendar.ZONE_OFFSET, 0); 26272ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller copy.set(Calendar.DST_OFFSET, 0); 26282ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller long localMillis = copy.getTimeInMillis(); 26292ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller 26302ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller // Make sure parsed time zone type (Standard or Daylight) 26312ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller // matches the rule used by the parsed time zone. 26322ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller int[] offsets = new int[2]; 26332ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller if (btz != null) { 26342ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller if (tztype == TimeType.STANDARD) { 26352ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller btz.getOffsetFromLocal(localMillis, 26362ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller BasicTimeZone.LOCAL_STD, BasicTimeZone.LOCAL_STD, offsets); 26372ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } else { 26382ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller btz.getOffsetFromLocal(localMillis, 26392ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller BasicTimeZone.LOCAL_DST, BasicTimeZone.LOCAL_DST, offsets); 26402ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } 26412ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } else { 26422ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller // No good way to resolve ambiguous time at transition, 26432ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller // but following code work in most case. 26442ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller tz.getOffset(localMillis, true, offsets); 26452ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller 26462ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller if (tztype == TimeType.STANDARD && offsets[1] != 0 26472ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller || tztype == TimeType.DAYLIGHT && offsets[1] == 0) { 26482ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller // Roll back one day and try it again. 26492ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller // Note: This code assumes 1. timezone transition only happens 26502ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller // once within 24 hours at max 26512ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller // 2. the difference of local offsets at the transition is 26522ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller // less than 24 hours. 26532ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller tz.getOffset(localMillis - (24*60*60*1000), true, offsets); 26542ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } 26552ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } 26562ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller 26572ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller // Now, compare the results with parsed type, either standard or 26582ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller // daylight saving time 26592ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller int resolvedSavings = offsets[1]; 26602ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller if (tztype == TimeType.STANDARD) { 26612ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller if (offsets[1] != 0) { 26622ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller // Override DST_OFFSET = 0 in the result calendar 26632ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller resolvedSavings = 0; 26642ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } 26652ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } else { // tztype == TZTYPE_DST 26662ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller if (offsets[1] == 0) { 26672ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller if (btz != null) { 26682ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller long time = localMillis + offsets[0]; 26692ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller // We use the nearest daylight saving time rule. 26702ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller TimeZoneTransition beforeTrs, afterTrs; 26712ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller long beforeT = time, afterT = time; 26722ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller int beforeSav = 0, afterSav = 0; 26732ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller 26742ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller // Search for DST rule before or on the time 26752ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller while (true) { 26762ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller beforeTrs = btz.getPreviousTransition(beforeT, true); 26772ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller if (beforeTrs == null) { 26782ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller break; 26792ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } 26802ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller beforeT = beforeTrs.getTime() - 1; 26812ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller beforeSav = beforeTrs.getFrom().getDSTSavings(); 26822ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller if (beforeSav != 0) { 26832ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller break; 26842ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } 26852ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } 26862ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller 26872ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller // Search for DST rule after the time 26882ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller while (true) { 26892ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller afterTrs = btz.getNextTransition(afterT, false); 26902ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller if (afterTrs == null) { 26912ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller break; 26922ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } 26932ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller afterT = afterTrs.getTime(); 26942ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller afterSav = afterTrs.getTo().getDSTSavings(); 26952ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller if (afterSav != 0) { 26962ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller break; 26972ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } 26982ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } 26992ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller 27002ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller if (beforeTrs != null && afterTrs != null) { 27012ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller if (time - beforeT > afterT - time) { 27022ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller resolvedSavings = afterSav; 27032ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } else { 27042ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller resolvedSavings = beforeSav; 27052ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } 27062ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } else if (beforeTrs != null && beforeSav != 0) { 27072ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller resolvedSavings = beforeSav; 27082ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } else if (afterTrs != null && afterSav != 0) { 27092ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller resolvedSavings = afterSav; 27102ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } else { 27112ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller resolvedSavings = btz.getDSTSavings(); 27122ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } 27132ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } else { 27142ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller resolvedSavings = tz.getDSTSavings(); 27152ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } 27162ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller if (resolvedSavings == 0) { 27172ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller // Final fallback 27182ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller resolvedSavings = millisPerHour; 27192ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } 27202ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } 27212ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } 27222ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller cal.set(Calendar.ZONE_OFFSET, offsets[0]); 27232ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller cal.set(Calendar.DST_OFFSET, resolvedSavings); 27242ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } 27252ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } 27262ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } 27272ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller // An IllegalArgumentException will be thrown by Calendar.getTime() 27282ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller // if any fields are out of range, e.g., MONTH == 17. 27292ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller catch (IllegalArgumentException e) { 27302ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller parsePos.setErrorIndex(pos); 27312ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller parsePos.setIndex(start); 27322ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller if (backupTZ != null) { 27332ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller calendar.setTimeZone(backupTZ); 27342ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } 27352ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller return; 27362ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } 27372ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller // Set the parsed result if local calendar is used 27382ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller // instead of the input calendar 27392ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller if (resultCal != null) { 27402ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller resultCal.setTimeZone(cal.getTimeZone()); 27412ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller resultCal.setTimeInMillis(cal.getTimeInMillis()); 27422ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } 27432ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller // Restore the original time zone if required 27442ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller if (backupTZ != null) { 27452ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller calendar.setTimeZone(backupTZ); 27462ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } 27472ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } 27482ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller 27492ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller /** 27502ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * Matches text (starting at pos) with patl. Returns the new pos, and sets complete[0] 27512ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * if it matched the entire text. Whitespace sequences are treated as singletons. 27522ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * <p>If isLenient and if we fail to match the first time, some special hacks are put into place. 27532ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * <ul><li>we are between date and time fields, then one or more whitespace characters 27542ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * in the text are accepted instead.</li> 27552ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * <ul><li>we are after a non-numeric field, and the text starts with a ".", we skip it.</li> 27562ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * </ul> 27572ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller */ 27582ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller private int matchLiteral(String text, int pos, Object[] items, int itemIndex, boolean[] complete) { 27592ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller int originalPos = pos; 27602ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller String patternLiteral = (String)items[itemIndex]; 27612ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller int plen = patternLiteral.length(); 27622ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller int tlen = text.length(); 27632ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller int idx = 0; 27642ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller while (idx < plen && pos < tlen) { 27652ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller char pch = patternLiteral.charAt(idx); 27662ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller char ich = text.charAt(pos); 27672ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller if (PatternProps.isWhiteSpace(pch) 27682ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller && PatternProps.isWhiteSpace(ich)) { 27692ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller // White space characters found in both patten and input. 27702ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller // Skip contiguous white spaces. 27712ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller while ((idx + 1) < plen && 27722ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller PatternProps.isWhiteSpace(patternLiteral.charAt(idx + 1))) { 27732ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller ++idx; 27742ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } 27752ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller while ((pos + 1) < tlen && 27762ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller PatternProps.isWhiteSpace(text.charAt(pos + 1))) { 27772ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller ++pos; 27782ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } 27792ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } else if (pch != ich) { 27802ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller if (ich == '.' && pos == originalPos && 0 < itemIndex && getBooleanAttribute(DateFormat.BooleanAttribute.PARSE_ALLOW_WHITESPACE)) { 27812ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller Object before = items[itemIndex-1]; 27822ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller if (before instanceof PatternItem) { 27832ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller boolean isNumeric = ((PatternItem) before).isNumeric; 27842ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller if (!isNumeric) { 27852ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller ++pos; // just update pos 27862ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller continue; 27872ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } 27882ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } 27892ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } else if ((pch == ' ' || pch == '.') && getBooleanAttribute(DateFormat.BooleanAttribute.PARSE_ALLOW_WHITESPACE)) { 27902ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller ++idx; 27912ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller continue; 27922ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } else if (pos != originalPos && getBooleanAttribute(DateFormat.BooleanAttribute.PARSE_PARTIAL_LITERAL_MATCH)) { 27932ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller ++idx; 27942ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller continue; 27952ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } 27962ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller break; 27972ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } 27982ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller ++idx; 27992ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller ++pos; 28002ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } 28012ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller complete[0] = idx == plen; 28022ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller if (complete[0] == false && getBooleanAttribute(DateFormat.BooleanAttribute.PARSE_ALLOW_WHITESPACE) && 0 < itemIndex && itemIndex < items.length - 1) { 28032ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller // If fully lenient, accept " "* for any text between a date and a time field 28042ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller // We don't go more lenient, because we don't want to accept "12/31" for "12:31". 28052ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller // People may be trying to parse for a date, then for a time. 28062ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller if (originalPos < tlen) { 28072ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller Object before = items[itemIndex-1]; 28082ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller Object after = items[itemIndex+1]; 28092ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller if (before instanceof PatternItem && after instanceof PatternItem) { 28102ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller char beforeType = ((PatternItem) before).type; 28112ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller char afterType = ((PatternItem) after).type; 28122ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller if (DATE_PATTERN_TYPE.contains(beforeType) != DATE_PATTERN_TYPE.contains(afterType)) { 28132ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller int newPos = originalPos; 28142ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller while (true) { 28152ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller char ich = text.charAt(newPos); 28162ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller if (!PatternProps.isWhiteSpace(ich)) { 28172ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller break; 28182ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } 28192ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller ++newPos; 28202ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } 28212ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller complete[0] = newPos > originalPos; 28222ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller pos = newPos; 28232ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } 28242ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } 28252ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } 28262ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } 28272ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller return pos; 28282ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } 28291c8a530973739aafa823d758240d2cd5dad96fe3Fredrik Roubert 28302ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller static final UnicodeSet DATE_PATTERN_TYPE = new UnicodeSet("[GyYuUQqMLlwWd]").freeze(); 28312ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller 28322ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller /** 28332ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * Attempt to match the text at a given position against an array of 28342ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * strings. Since multiple strings in the array may match (for 28352ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * example, if the array contains "a", "ab", and "abc", all will match 28362ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * the input string "abcd") the longest match is returned. As a side 28372ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * effect, the given field of <code>cal</code> is set to the index 28382ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * of the best match, if there is one. 28392ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * @param text the time text being parsed. 28402ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * @param start where to start parsing. 28412ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * @param field the date field being parsed. 28422ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * @param data the string array to parsed. 28432ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * @param cal 28442ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * @return the new start position if matching succeeded; a negative 28452ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * number indicating matching failure, otherwise. As a side effect, 28462ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * sets the <code>cal</code> field <code>field</code> to the index 28472ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * of the best match, if matching succeeded. 28482ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller */ 28492ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller protected int matchString(String text, int start, int field, String[] data, Calendar cal) 28502ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller { 28512ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller return matchString(text, start, field, data, null, cal); 28522ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } 28532ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller 28542ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller /** 28552ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * Attempt to match the text at a given position against an array of 28562ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * strings. Since multiple strings in the array may match (for 28572ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * example, if the array contains "a", "ab", and "abc", all will match 28582ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * the input string "abcd") the longest match is returned. As a side 28592ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * effect, the given field of <code>cal</code> is set to the index 28602ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * of the best match, if there is one. 28612ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * @param text the time text being parsed. 28622ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * @param start where to start parsing. 28632ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * @param field the date field being parsed. 28642ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * @param data the string array to parsed. 28652ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * @param monthPattern leap month pattern, or null if none. 28662ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * @param cal 28672ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * @return the new start position if matching succeeded; a negative 28682ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * number indicating matching failure, otherwise. As a side effect, 28692ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * sets the <code>cal</code> field <code>field</code> to the index 28702ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * of the best match, if matching succeeded. 28712ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * @deprecated This API is ICU internal only. 2872836e6b40a94ec3fb7545a76cb072960442b7eee9Neil Fuller * @hide draft / provisional / internal are hidden on Android 28732ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller */ 28742ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller @Deprecated 28752ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller private int matchString(String text, int start, int field, String[] data, String monthPattern, Calendar cal) 28762ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller { 28772ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller int i = 0; 28782ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller int count = data.length; 28792ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller 28802ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller if (field == Calendar.DAY_OF_WEEK) i = 1; 28812ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller 28822ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller // There may be multiple strings in the data[] array which begin with 28832ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller // the same prefix (e.g., Cerven and Cervenec (June and July) in Czech). 28842ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller // We keep track of the longest match, and return that. Note that this 28852ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller // unfortunately requires us to test all array elements. 28862ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller int bestMatchLength = 0, bestMatch = -1; 28872ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller int isLeapMonth = 0; 28882ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller int matchLength = 0; 28892ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller 28902ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller for (; i<count; ++i) 28912ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller { 28922ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller int length = data[i].length(); 28932ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller // Always compare if we have no match yet; otherwise only compare 28942ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller // against potentially better matches (longer strings). 28952ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller if (length > bestMatchLength && 28962ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller (matchLength = regionMatchesWithOptionalDot(text, start, data[i], length)) >= 0) 28972ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller { 28982ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller bestMatch = i; 28992ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller bestMatchLength = matchLength; 29002ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller isLeapMonth = 0; 29012ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } 29022ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller if (monthPattern != null) { 29031c8a530973739aafa823d758240d2cd5dad96fe3Fredrik Roubert String leapMonthName = SimpleFormatterImpl.formatRawPattern( 29041c8a530973739aafa823d758240d2cd5dad96fe3Fredrik Roubert monthPattern, 1, 1, data[i]); 29052ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller length = leapMonthName.length(); 29062ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller if (length > bestMatchLength && 29072ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller (matchLength = regionMatchesWithOptionalDot(text, start, leapMonthName, length)) >= 0) 29082ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller { 29092ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller bestMatch = i; 29102ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller bestMatchLength = matchLength; 29112ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller isLeapMonth = 1; 29122ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } 29132ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } 29142ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } 29152ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller if (bestMatch >= 0) 29162ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller { 29172ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller if (field >= 0) { 29182ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller if (field == Calendar.YEAR) { 29192ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller bestMatch++; // only get here for cyclic year names, which match 1-based years 1-60 29202ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } 29212ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller cal.set(field, bestMatch); 29222ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller if (monthPattern != null) { 29232ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller cal.set(Calendar.IS_LEAP_MONTH, isLeapMonth); 29242ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } 29252ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } 29262ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller return start + bestMatchLength; 29272ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } 29282ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller return ~start; 29292ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } 29302ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller 29312ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller private int regionMatchesWithOptionalDot(String text, int start, String data, int length) { 29322ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller boolean matches = text.regionMatches(true, start, data, 0, length); 29332ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller if (matches) { 29342ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller return length; 29352ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } 29362ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller if (data.length() > 0 && data.charAt(data.length()-1) == '.') { 29372ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller if (text.regionMatches(true, start, data, 0, length-1)) { 29382ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller return length - 1; 29392ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } 29402ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } 29412ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller return -1; 29422ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } 29432ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller 29442ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller /** 29452ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * Attempt to match the text at a given position against an array of quarter 29462ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * strings. Since multiple strings in the array may match (for 29472ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * example, if the array contains "a", "ab", and "abc", all will match 29482ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * the input string "abcd") the longest match is returned. As a side 29492ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * effect, the given field of <code>cal</code> is set to the index 29502ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * of the best match, if there is one. 29512ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * @param text the time text being parsed. 29522ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * @param start where to start parsing. 29532ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * @param field the date field being parsed. 29542ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * @param data the string array to parsed. 29552ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * @return the new start position if matching succeeded; a negative 29562ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * number indicating matching failure, otherwise. As a side effect, 29572ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * sets the <code>cal</code> field <code>field</code> to the index 29582ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * of the best match, if matching succeeded. 29592ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller */ 29602ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller protected int matchQuarterString(String text, int start, int field, String[] data, Calendar cal) 29612ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller { 29622ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller int i = 0; 29632ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller int count = data.length; 29642ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller 29652ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller // There may be multiple strings in the data[] array which begin with 29662ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller // the same prefix (e.g., Cerven and Cervenec (June and July) in Czech). 29672ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller // We keep track of the longest match, and return that. Note that this 29682ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller // unfortunately requires us to test all array elements. 29692ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller int bestMatchLength = 0, bestMatch = -1; 29702ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller int matchLength = 0; 29712ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller for (; i<count; ++i) { 29722ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller int length = data[i].length(); 29732ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller // Always compare if we have no match yet; otherwise only compare 29742ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller // against potentially better matches (longer strings). 29752ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller if (length > bestMatchLength && 29762ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller (matchLength = regionMatchesWithOptionalDot(text, start, data[i], length)) >= 0) { 29772ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller 29782ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller bestMatch = i; 29792ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller bestMatchLength = matchLength; 29802ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } 29812ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } 29822ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller 29832ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller if (bestMatch >= 0) { 29842ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller cal.set(field, bestMatch * 3); 29852ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller return start + bestMatchLength; 29862ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } 29872ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller 29882ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller return -start; 29892ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } 29902ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller 29912ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller /** 29921c8a530973739aafa823d758240d2cd5dad96fe3Fredrik Roubert * Similar to matchQuarterString but customized for day periods. 29931c8a530973739aafa823d758240d2cd5dad96fe3Fredrik Roubert */ 29941c8a530973739aafa823d758240d2cd5dad96fe3Fredrik Roubert private int matchDayPeriodString(String text, int start, String[] data, int dataLength, 29951c8a530973739aafa823d758240d2cd5dad96fe3Fredrik Roubert Output<DayPeriodRules.DayPeriod> dayPeriod) 29961c8a530973739aafa823d758240d2cd5dad96fe3Fredrik Roubert { 29971c8a530973739aafa823d758240d2cd5dad96fe3Fredrik Roubert int bestMatchLength = 0, bestMatch = -1; 29981c8a530973739aafa823d758240d2cd5dad96fe3Fredrik Roubert int matchLength = 0; 29991c8a530973739aafa823d758240d2cd5dad96fe3Fredrik Roubert for (int i = 0; i < dataLength; ++i) { 30001c8a530973739aafa823d758240d2cd5dad96fe3Fredrik Roubert // Only try matching if the string exists. 30011c8a530973739aafa823d758240d2cd5dad96fe3Fredrik Roubert if (data[i] != null) { 30021c8a530973739aafa823d758240d2cd5dad96fe3Fredrik Roubert int length = data[i].length(); 30031c8a530973739aafa823d758240d2cd5dad96fe3Fredrik Roubert if (length > bestMatchLength && 30041c8a530973739aafa823d758240d2cd5dad96fe3Fredrik Roubert (matchLength = regionMatchesWithOptionalDot(text, start, data[i], length)) >= 0) { 30051c8a530973739aafa823d758240d2cd5dad96fe3Fredrik Roubert bestMatch = i; 30061c8a530973739aafa823d758240d2cd5dad96fe3Fredrik Roubert bestMatchLength = matchLength; 30071c8a530973739aafa823d758240d2cd5dad96fe3Fredrik Roubert } 30081c8a530973739aafa823d758240d2cd5dad96fe3Fredrik Roubert } 30091c8a530973739aafa823d758240d2cd5dad96fe3Fredrik Roubert } 30101c8a530973739aafa823d758240d2cd5dad96fe3Fredrik Roubert 30111c8a530973739aafa823d758240d2cd5dad96fe3Fredrik Roubert if (bestMatch >= 0) { 30121c8a530973739aafa823d758240d2cd5dad96fe3Fredrik Roubert dayPeriod.value = DayPeriodRules.DayPeriod.VALUES[bestMatch]; 30131c8a530973739aafa823d758240d2cd5dad96fe3Fredrik Roubert return start + bestMatchLength; 30141c8a530973739aafa823d758240d2cd5dad96fe3Fredrik Roubert } 30151c8a530973739aafa823d758240d2cd5dad96fe3Fredrik Roubert 30161c8a530973739aafa823d758240d2cd5dad96fe3Fredrik Roubert return -start; 30171c8a530973739aafa823d758240d2cd5dad96fe3Fredrik Roubert } 30181c8a530973739aafa823d758240d2cd5dad96fe3Fredrik Roubert 30191c8a530973739aafa823d758240d2cd5dad96fe3Fredrik Roubert /** 30202ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * Protected method that converts one field of the input string into a 30212ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * numeric field value in <code>cal</code>. Returns -start (for 30222ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * ParsePosition) if failed. Subclasses may override this method to 30232ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * modify or add parsing capabilities. 30242ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * @param text the time text to be parsed. 30252ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * @param start where to start parsing. 30262ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * @param ch the pattern character for the date field text to be parsed. 30272ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * @param count the count of a pattern character. 30282ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * @param obeyCount if true, then the next field directly abuts this one, 30292ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * and we should use the count to know when to stop parsing. 30302ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * @param ambiguousYear return parameter; upon return, if ambiguousYear[0] 30312ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * is true, then a two-digit year was parsed and may need to be readjusted. 30322ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * @param cal 30332ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * @return the new start position if matching succeeded; a negative 30342ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * number indicating matching failure, otherwise. As a side effect, 30352ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * set the appropriate field of <code>cal</code> with the parsed 30362ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * value. 30372ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller */ 30382ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller protected int subParse(String text, int start, char ch, int count, 30392ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller boolean obeyCount, boolean allowNegative, 30402ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller boolean[] ambiguousYear, Calendar cal) 30412ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller { 30422ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller return subParse(text, start, ch, count, obeyCount, allowNegative, ambiguousYear, cal, null, null); 30432ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } 30442ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller 30452ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller /** 30461c8a530973739aafa823d758240d2cd5dad96fe3Fredrik Roubert * Overloading to provide default argument (null) for day period. 30471c8a530973739aafa823d758240d2cd5dad96fe3Fredrik Roubert */ 30481c8a530973739aafa823d758240d2cd5dad96fe3Fredrik Roubert private int subParse(String text, int start, char ch, int count, 30491c8a530973739aafa823d758240d2cd5dad96fe3Fredrik Roubert boolean obeyCount, boolean allowNegative, 30501c8a530973739aafa823d758240d2cd5dad96fe3Fredrik Roubert boolean[] ambiguousYear, Calendar cal, 30511c8a530973739aafa823d758240d2cd5dad96fe3Fredrik Roubert MessageFormat numericLeapMonthFormatter, Output<TimeType> tzTimeType) { 30521c8a530973739aafa823d758240d2cd5dad96fe3Fredrik Roubert return subParse(text, start, ch, count, obeyCount, allowNegative, ambiguousYear, cal, null, null, null); 30531c8a530973739aafa823d758240d2cd5dad96fe3Fredrik Roubert } 30541c8a530973739aafa823d758240d2cd5dad96fe3Fredrik Roubert 30551c8a530973739aafa823d758240d2cd5dad96fe3Fredrik Roubert /** 30562ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * Protected method that converts one field of the input string into a 30572ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * numeric field value in <code>cal</code>. Returns -start (for 30582ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * ParsePosition) if failed. Subclasses may override this method to 30592ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * modify or add parsing capabilities. 30602ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * @param text the time text to be parsed. 30612ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * @param start where to start parsing. 30622ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * @param ch the pattern character for the date field text to be parsed. 30632ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * @param count the count of a pattern character. 30642ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * @param obeyCount if true, then the next field directly abuts this one, 30652ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * and we should use the count to know when to stop parsing. 30662ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * @param ambiguousYear return parameter; upon return, if ambiguousYear[0] 30672ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * is true, then a two-digit year was parsed and may need to be readjusted. 30682ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * @param cal 30692ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * @param numericLeapMonthFormatter if non-null, used to parse numeric leap months. 30702ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * @param tzTimeType the type of parsed time zone - standard, daylight or unknown (output). 30712ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * This parameter can be null if caller does not need the information. 30722ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * @return the new start position if matching succeeded; a negative 30732ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * number indicating matching failure, otherwise. As a side effect, 30742ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * set the appropriate field of <code>cal</code> with the parsed 30752ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * value. 30762ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * @deprecated This API is ICU internal only. 3077836e6b40a94ec3fb7545a76cb072960442b7eee9Neil Fuller * @hide draft / provisional / internal are hidden on Android 30782ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller */ 30792ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller @Deprecated 30802ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller @SuppressWarnings("fallthrough") 30812ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller private int subParse(String text, int start, char ch, int count, 30822ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller boolean obeyCount, boolean allowNegative, 30832ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller boolean[] ambiguousYear, Calendar cal, 30841c8a530973739aafa823d758240d2cd5dad96fe3Fredrik Roubert MessageFormat numericLeapMonthFormatter, Output<TimeType> tzTimeType, 30851c8a530973739aafa823d758240d2cd5dad96fe3Fredrik Roubert Output<DayPeriodRules.DayPeriod> dayPeriod) 30862ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller { 30872ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller Number number = null; 30882ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller NumberFormat currentNumberFormat = null; 30892ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller int value = 0; 30902ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller int i; 30912ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller ParsePosition pos = new ParsePosition(0); 30922ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller 30932ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller int patternCharIndex = getIndexFromChar(ch); 30942ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller if (patternCharIndex == -1) { 30952ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller return ~start; 30962ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } 30972ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller 30982ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller currentNumberFormat = getNumberFormat(ch); 30992ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller 31002ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller int field = PATTERN_INDEX_TO_CALENDAR_FIELD[patternCharIndex]; // -1 if irrelevant 31011c8a530973739aafa823d758240d2cd5dad96fe3Fredrik Roubert 31022ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller if (numericLeapMonthFormatter != null) { 31032ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller numericLeapMonthFormatter.setFormatByArgumentIndex(0, currentNumberFormat); 31042ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } 31052ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller boolean isChineseCalendar = ( cal.getType().equals("chinese") || cal.getType().equals("dangi") ); 31062ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller 31072ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller // If there are any spaces here, skip over them. If we hit the end 31082ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller // of the string, then fail. 31092ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller for (;;) { 31102ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller if (start >= text.length()) { 31112ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller return ~start; 31122ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } 31132ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller int c = UTF16.charAt(text, start); 31142ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller if (!UCharacter.isUWhiteSpace(c) || !PatternProps.isWhiteSpace(c)) { 31152ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller break; 31162ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } 31172ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller start += UTF16.getCharCount(c); 31182ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } 31192ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller pos.setIndex(start); 31202ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller 31212ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller // We handle a few special cases here where we need to parse 31222ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller // a number value. We handle further, more generic cases below. We need 31232ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller // to handle some of them here because some fields require extra processing on 31242ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller // the parsed value. 31252ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller if (patternCharIndex == 4 /*'k' HOUR_OF_DAY1_FIELD*/ || 31262ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller patternCharIndex == 15 /*'h' HOUR1_FIELD*/ || 31272ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller (patternCharIndex == 2 /*'M' MONTH_FIELD*/ && count <= 2) || 31282ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller patternCharIndex == 26 /*'L' STAND_ALONE_MONTH*/ || 31292ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller patternCharIndex == 19 /*'e' DOW_LOCAL*/ || 31302ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller patternCharIndex == 25 /*'c' STAND_ALONE_DAY_OF_WEEK*/ || 31312ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller patternCharIndex == 1 /*'y' YEAR */ || patternCharIndex == 18 /*'Y' YEAR_WOY */ || 31322ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller patternCharIndex == 30 /*'U' YEAR_NAME_FIELD, falls back to numeric */ || 31332ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller (patternCharIndex == 0 /*'G' ERA */ && isChineseCalendar) || 31342ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller patternCharIndex == 27 /* 'Q' - QUARTER*/ || 31352ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller patternCharIndex == 28 /* 'q' - STANDALONE QUARTER*/ || 31362ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller patternCharIndex == 8 /*'S' FRACTIONAL_SECOND */ ) 31372ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller { 31382ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller // It would be good to unify this with the obeyCount logic below, 31392ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller // but that's going to be difficult. 31401c8a530973739aafa823d758240d2cd5dad96fe3Fredrik Roubert 31412ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller boolean parsedNumericLeapMonth = false; 31422ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller if (numericLeapMonthFormatter != null && (patternCharIndex == 2 || patternCharIndex == 26)) { 31432ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller // First see if we can parse month number with leap month pattern 31442ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller Object[] args = numericLeapMonthFormatter.parse(text, pos); 31452ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller if (args != null && pos.getIndex() > start && (args[0] instanceof Number)) { 31462ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller parsedNumericLeapMonth = true; 31472ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller number = (Number)args[0]; 31482ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller cal.set(Calendar.IS_LEAP_MONTH, 1); 31492ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } else { 31502ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller pos.setIndex(start); 31512ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller cal.set(Calendar.IS_LEAP_MONTH, 0); 31522ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } 31532ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } 31541c8a530973739aafa823d758240d2cd5dad96fe3Fredrik Roubert 31552ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller if (!parsedNumericLeapMonth) { 31562ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller if (obeyCount) { 31572ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller if ((start+count) > text.length()) { 31582ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller return ~start; 31592ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } 31602ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller number = parseInt(text, count, pos, allowNegative,currentNumberFormat); 31612ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } else { 31622ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller number = parseInt(text, pos, allowNegative,currentNumberFormat); 31632ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } 31642ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller if (number == null && !allowNumericFallback(patternCharIndex)) { 31652ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller // only return if pattern is NOT one that allows numeric fallback 31662ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller return ~start; 31672ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } 31682ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } 31692ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller 31702ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller if (number != null) { 31712ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller value = number.intValue(); 31722ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } 31732ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } 31742ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller 31752ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller switch (patternCharIndex) 31762ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller { 31772ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller case 0: // 'G' - ERA 31782ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller if ( isChineseCalendar ) { 31792ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller // Numeric era handling moved from ChineseDateFormat, 31802ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller // If we didn't have a number, already returned -start above 31812ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller cal.set(Calendar.ERA, value); 31822ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller return pos.getIndex(); 31832ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } 31842ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller int ps = 0; 31852ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller if (count == 5) { 31862ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller ps = matchString(text, start, Calendar.ERA, formatData.narrowEras, null, cal); 31872ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } else if (count == 4) { 31882ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller ps = matchString(text, start, Calendar.ERA, formatData.eraNames, null, cal); 31892ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } else { 31902ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller ps = matchString(text, start, Calendar.ERA, formatData.eras, null, cal); 31912ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } 31922ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller 31932ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller // check return position, if it equals -start, then matchString error 31941c8a530973739aafa823d758240d2cd5dad96fe3Fredrik Roubert // special case the return code so we don't necessarily fail out until we 31952ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller // verify no year information also 31962ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller if (ps == ~start) 31972ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller ps = ISOSpecialEra; 31982ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller 31991c8a530973739aafa823d758240d2cd5dad96fe3Fredrik Roubert return ps; 32001c8a530973739aafa823d758240d2cd5dad96fe3Fredrik Roubert 32012ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller case 1: // 'y' - YEAR 32022ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller case 18: // 'Y' - YEAR_WOY 32032ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller // If there are 3 or more YEAR pattern characters, this indicates 32042ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller // that the year value is to be treated literally, without any 32052ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller // two-digit year adjustments (e.g., from "01" to 2001). Otherwise 32062ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller // we made adjustments to place the 2-digit year in the proper 32072ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller // century, for parsed strings from "00" to "99". Any other string 32082ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller // is treated literally: "2250", "-1", "1", "002". 32092ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller /* 'yy' is the only special case, 'y' is interpreted as number. [Richard/GCL]*/ 32102ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller /* Skip this for Chinese calendar, moved from ChineseDateFormat */ 32112ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller if ( override != null && (override.compareTo("hebr") == 0 || override.indexOf("y=hebr") >= 0) && value < 1000 ) { 32122ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller value += HEBREW_CAL_CUR_MILLENIUM_START_YEAR; 32132ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } else if (count == 2 && (pos.getIndex() - start) == 2 && cal.haveDefaultCentury() 32142ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller && UCharacter.isDigit(text.charAt(start)) 32152ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller && UCharacter.isDigit(text.charAt(start+1))) 32162ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller { 32172ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller // Assume for example that the defaultCenturyStart is 6/18/1903. 32182ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller // This means that two-digit years will be forced into the range 32192ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller // 6/18/1903 to 6/17/2003. As a result, years 00, 01, and 02 32202ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller // correspond to 2000, 2001, and 2002. Years 04, 05, etc. correspond 32212ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller // to 1904, 1905, etc. If the year is 03, then it is 2003 if the 32222ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller // other fields specify a date before 6/18, or 1903 if they specify a 32232ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller // date afterwards. As a result, 03 is an ambiguous year. All other 32242ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller // two-digit years are unambiguous. 32252ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller int ambiguousTwoDigitYear = getDefaultCenturyStartYear() % 100; 32262ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller ambiguousYear[0] = value == ambiguousTwoDigitYear; 32272ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller value += (getDefaultCenturyStartYear()/100)*100 + 32282ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller (value < ambiguousTwoDigitYear ? 100 : 0); 32292ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } 32302ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller cal.set(field, value); 32312ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller 32322ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller // Delayed checking for adjustment of Hebrew month numbers in non-leap years. 32332ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller if (DelayedHebrewMonthCheck) { 32342ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller if (!HebrewCalendar.isLeapYear(value)) { 32352ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller cal.add(Calendar.MONTH,1); 32362ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } 32372ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller DelayedHebrewMonthCheck = false; 32382ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } 32392ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller return pos.getIndex(); 32402ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller case 30: // 'U' - YEAR_NAME_FIELD 32412ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller if (formatData.shortYearNames != null) { 32422ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller int newStart = matchString(text, start, Calendar.YEAR, formatData.shortYearNames, null, cal); 32432ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller if (newStart > 0) { 32442ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller return newStart; 32452ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } 32462ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } 32472ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller if ( number != null && (getBooleanAttribute(DateFormat.BooleanAttribute.PARSE_ALLOW_NUMERIC) || formatData.shortYearNames == null || value > formatData.shortYearNames.length) ) { 32482ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller cal.set(Calendar.YEAR, value); 32492ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller return pos.getIndex(); 32502ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } 32512ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller return ~start; 32522ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller case 2: // 'M' - MONTH 32532ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller case 26: // 'L' - STAND_ALONE_MONTH 32542ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller if (count <= 2 || (number != null && getBooleanAttribute(DateFormat.BooleanAttribute.PARSE_ALLOW_NUMERIC))) { 32552ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller // i.e., M/MM, L/LL or lenient & have a number 32562ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller // Don't want to parse the month if it is a string 32572ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller // while pattern uses numeric style: M/MM, L/LL. 32582ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller // [We computed 'value' above.] 32592ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller cal.set(Calendar.MONTH, value - 1); 32602ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller // When parsing month numbers from the Hebrew Calendar, we might need 32612ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller // to adjust the month depending on whether or not it was a leap year. 32622ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller // We may or may not yet know what year it is, so might have to delay 32632ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller // checking until the year is parsed. 32642ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller if (cal.getType().equals("hebrew") && value >= 6) { 32652ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller if (cal.isSet(Calendar.YEAR)) { 32662ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller if (!HebrewCalendar.isLeapYear(cal.get(Calendar.YEAR))) { 32672ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller cal.set(Calendar.MONTH, value); 32682ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } 32692ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } else { 32702ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller DelayedHebrewMonthCheck = true; 32712ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } 32722ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } 32732ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller return pos.getIndex(); 32742ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } else { 32752ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller // count >= 3 // i.e., MMM/MMMM or LLL/LLLL 32762ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller // Want to be able to parse both short and long forms. 32772ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller boolean haveMonthPat = (formatData.leapMonthPatterns != null && formatData.leapMonthPatterns.length >= DateFormatSymbols.DT_MONTH_PATTERN_COUNT); 32782ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller // Try count == 4 first:, unless we're strict 32792ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller int newStart = 0; 32802ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller if(getBooleanAttribute(DateFormat.BooleanAttribute.PARSE_MULTIPLE_PATTERNS_FOR_MATCH) || count == 4) { 32812ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller newStart = (patternCharIndex == 2)? 32822ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller matchString(text, start, Calendar.MONTH, formatData.months, 32832ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller (haveMonthPat)? formatData.leapMonthPatterns[DateFormatSymbols.DT_LEAP_MONTH_PATTERN_FORMAT_WIDE]: null, cal): 32842ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller matchString(text, start, Calendar.MONTH, formatData.standaloneMonths, 32852ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller (haveMonthPat)? formatData.leapMonthPatterns[DateFormatSymbols.DT_LEAP_MONTH_PATTERN_STANDALONE_WIDE]: null, cal); 32862ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller if (newStart > 0) { 32872ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller return newStart; 32882ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } 32891c8a530973739aafa823d758240d2cd5dad96fe3Fredrik Roubert } 32902ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller // count == 4 failed, now try count == 3 32912ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller if(getBooleanAttribute(DateFormat.BooleanAttribute.PARSE_MULTIPLE_PATTERNS_FOR_MATCH) || count == 3) { 32922ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller return (patternCharIndex == 2)? 32932ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller matchString(text, start, Calendar.MONTH, formatData.shortMonths, 32942ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller (haveMonthPat)? formatData.leapMonthPatterns[DateFormatSymbols.DT_LEAP_MONTH_PATTERN_FORMAT_ABBREV]: null, cal): 32952ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller matchString(text, start, Calendar.MONTH, formatData.standaloneShortMonths, 32962ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller (haveMonthPat)? formatData.leapMonthPatterns[DateFormatSymbols.DT_LEAP_MONTH_PATTERN_STANDALONE_ABBREV]: null, cal); 32972ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } 32982ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller return newStart; 32992ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } 33002ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller case 4: // 'k' - HOUR_OF_DAY (1..24) 33012ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller // [We computed 'value' above.] 33022ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller if (value == cal.getMaximum(Calendar.HOUR_OF_DAY)+1) { 33032ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller value = 0; 33042ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } 33052ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller cal.set(Calendar.HOUR_OF_DAY, value); 33062ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller return pos.getIndex(); 33072ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller case 8: // 'S' - FRACTIONAL_SECOND 33082ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller // Fractional seconds left-justify 33092ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller i = pos.getIndex() - start; 33102ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller if (i < 3) { 33112ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller while (i < 3) { 33122ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller value *= 10; 33132ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller i++; 33142ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } 33152ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } else { 33162ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller int a = 1; 33172ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller while (i > 3) { 33182ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller a *= 10; 33192ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller i--; 33202ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } 33212ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller value /= a; 33222ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } 33232ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller cal.set(Calendar.MILLISECOND, value); 33242ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller return pos.getIndex(); 33252ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller case 19: // 'e' - DOW_LOCAL 33261c8a530973739aafa823d758240d2cd5dad96fe3Fredrik Roubert if(count <= 2 || (number != null && (getBooleanAttribute(DateFormat.BooleanAttribute.PARSE_ALLOW_NUMERIC))) ) { 33272ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller // i.e. e/ee or lenient and have a number 33282ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller cal.set(field, value); 33292ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller return pos.getIndex(); 33302ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } 33312ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller // else for eee-eeeeee, fall through to EEE-EEEEEE handling 33321c8a530973739aafa823d758240d2cd5dad96fe3Fredrik Roubert //$FALL-THROUGH$ 33332ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller case 9: { // 'E' - DAY_OF_WEEK 33342ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller // Want to be able to parse at least wide, abbrev, short, and narrow forms. 33352ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller int newStart = 0; 33362ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller if(getBooleanAttribute(DateFormat.BooleanAttribute.PARSE_MULTIPLE_PATTERNS_FOR_MATCH) || count == 4) { 33372ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller if ((newStart = matchString(text, start, Calendar.DAY_OF_WEEK, formatData.weekdays, null, cal)) > 0) { // try EEEE wide 33382ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller return newStart; 33391c8a530973739aafa823d758240d2cd5dad96fe3Fredrik Roubert } 33402ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } 33412ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller if(getBooleanAttribute(DateFormat.BooleanAttribute.PARSE_MULTIPLE_PATTERNS_FOR_MATCH) || count == 3) { 33422ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller if ((newStart = matchString(text, start, Calendar.DAY_OF_WEEK, formatData.shortWeekdays, null, cal)) > 0) { // try EEE abbrev 33432ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller return newStart; 33441c8a530973739aafa823d758240d2cd5dad96fe3Fredrik Roubert } 33452ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } 33462ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller if(getBooleanAttribute(DateFormat.BooleanAttribute.PARSE_MULTIPLE_PATTERNS_FOR_MATCH) || count == 6) { 33472ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller if (formatData.shorterWeekdays != null) { 33482ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller if((newStart = matchString(text, start, Calendar.DAY_OF_WEEK, formatData.shorterWeekdays, null, cal)) > 0) { // try EEEEEE short 33492ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller return newStart; 33502ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } 33512ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } 33522ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } 33532ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller if(getBooleanAttribute(DateFormat.BooleanAttribute.PARSE_MULTIPLE_PATTERNS_FOR_MATCH) || count == 5) { 33542ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller if (formatData.narrowWeekdays != null) { 33552ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller if((newStart = matchString(text, start, Calendar.DAY_OF_WEEK, formatData.narrowWeekdays, null, cal)) > 0) { // try EEEEE narrow 33562ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller return newStart; 33572ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } 33582ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } 33592ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } 33602ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller return newStart; 33612ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } 33622ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller case 25: { // 'c' - STAND_ALONE_DAY_OF_WEEK 33631c8a530973739aafa823d758240d2cd5dad96fe3Fredrik Roubert if(count == 1 || (number != null && (getBooleanAttribute(DateFormat.BooleanAttribute.PARSE_ALLOW_NUMERIC))) ) { 33642ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller // i.e. c or lenient and have a number 33652ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller cal.set(field, value); 33662ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller return pos.getIndex(); 33672ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } 33682ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller // Want to be able to parse at least wide, abbrev, short forms. 33692ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller int newStart = 0; 33702ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller if(getBooleanAttribute(DateFormat.BooleanAttribute.PARSE_MULTIPLE_PATTERNS_FOR_MATCH) || count == 4) { 33712ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller if ((newStart = matchString(text, start, Calendar.DAY_OF_WEEK, formatData.standaloneWeekdays, null, cal)) > 0) { // try cccc wide 33722ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller return newStart; 33731c8a530973739aafa823d758240d2cd5dad96fe3Fredrik Roubert } 33742ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } 33752ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller if(getBooleanAttribute(DateFormat.BooleanAttribute.PARSE_MULTIPLE_PATTERNS_FOR_MATCH) || count == 3) { 33762ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller if ((newStart = matchString(text, start, Calendar.DAY_OF_WEEK, formatData.standaloneShortWeekdays, null, cal)) > 0) { // try ccc abbrev 33772ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller return newStart; 33782ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } 33792ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } 33802ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller if(getBooleanAttribute(DateFormat.BooleanAttribute.PARSE_MULTIPLE_PATTERNS_FOR_MATCH) || count == 6) { 33812ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller if (formatData.standaloneShorterWeekdays != null) { 33822ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller return matchString(text, start, Calendar.DAY_OF_WEEK, formatData.standaloneShorterWeekdays, null, cal); // try cccccc short 33832ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } 33842ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } 33852ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller return newStart; 33862ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } 33872ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller case 14: { // 'a' - AM_PM 33882ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller // Optionally try both wide/abbrev and narrow forms. 33892ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller // formatData.ampmsNarrow may be null when deserializing DateFormatSymbolsfrom old version, 33902ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller // in which case our only option is wide form 33912ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller int newStart = 0; 33922ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller // try wide/abbrev a-aaaa 33932ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller if(formatData.ampmsNarrow == null || count < 5 || getBooleanAttribute(DateFormat.BooleanAttribute.PARSE_MULTIPLE_PATTERNS_FOR_MATCH)) { 33942ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller if ((newStart = matchString(text, start, Calendar.AM_PM, formatData.ampms, null, cal)) > 0) { 33952ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller return newStart; 33962ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } 33972ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } 33982ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller // try narrow aaaaa 33992ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller if(formatData.ampmsNarrow != null && (count >= 5 || getBooleanAttribute(DateFormat.BooleanAttribute.PARSE_MULTIPLE_PATTERNS_FOR_MATCH))) { 34002ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller if ((newStart = matchString(text, start, Calendar.AM_PM, formatData.ampmsNarrow, null, cal)) > 0) { 34012ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller return newStart; 34022ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } 34032ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } 34042ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller // no matches for given options 34052ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller return ~start; 34062ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } 34072ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller case 15: // 'h' - HOUR (1..12) 34082ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller // [We computed 'value' above.] 34092ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller if (value == cal.getLeastMaximum(Calendar.HOUR)+1) { 34102ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller value = 0; 34112ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } 34122ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller cal.set(Calendar.HOUR, value); 34132ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller return pos.getIndex(); 34142ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller case 17: // 'z' - ZONE_OFFSET 34152ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller { 34162ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller Style style = (count < 4) ? Style.SPECIFIC_SHORT : Style.SPECIFIC_LONG; 34172ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller TimeZone tz = tzFormat().parse(style, text, pos, tzTimeType); 34182ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller if (tz != null) { 34192ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller cal.setTimeZone(tz); 34202ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller return pos.getIndex(); 34212ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } 34222ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller return ~start; 34232ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } 34242ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller case 23: // 'Z' - TIMEZONE_RFC 34252ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller { 34262ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller Style style = (count < 4) ? Style.ISO_BASIC_LOCAL_FULL : ((count == 5) ? Style.ISO_EXTENDED_FULL : Style.LOCALIZED_GMT); 34272ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller TimeZone tz = tzFormat().parse(style, text, pos, tzTimeType); 34282ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller if (tz != null) { 34292ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller cal.setTimeZone(tz); 34302ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller return pos.getIndex(); 34312ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } 34322ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller return ~start; 34332ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } 34342ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller case 24: // 'v' - TIMEZONE_GENERIC 34352ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller { 34362ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller // Note: 'v' only supports count 1 and 4 34372ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller Style style = (count < 4) ? Style.GENERIC_SHORT : Style.GENERIC_LONG; 34382ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller TimeZone tz = tzFormat().parse(style, text, pos, tzTimeType); 34392ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller if (tz != null) { 34402ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller cal.setTimeZone(tz); 34412ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller return pos.getIndex(); 34422ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } 34432ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller return ~start; 34442ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } 34452ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller case 29: // 'V' - TIMEZONE_SPECIAL 34462ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller { 34472ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller Style style = null; 34482ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller switch (count) { 34492ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller case 1: 34502ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller style = Style.ZONE_ID_SHORT; 34512ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller break; 34522ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller case 2: 34532ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller style = Style.ZONE_ID; 34542ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller break; 34552ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller case 3: 34562ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller style = Style.EXEMPLAR_LOCATION; 34572ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller break; 34582ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller default: 34592ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller style = Style.GENERIC_LOCATION; 34602ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller break; 34612ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } 34622ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller TimeZone tz = tzFormat().parse(style, text, pos, tzTimeType); 34632ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller if (tz != null) { 34642ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller cal.setTimeZone(tz); 34652ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller return pos.getIndex(); 34662ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } 34672ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller return ~start; 34682ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } 34692ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller case 31: // 'O' - TIMEZONE_LOCALIZED_GMT_OFFSET 34702ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller { 34712ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller Style style = (count < 4) ? Style.LOCALIZED_GMT_SHORT : Style.LOCALIZED_GMT; 34722ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller TimeZone tz = tzFormat().parse(style, text, pos, tzTimeType); 34732ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller if (tz != null) { 34742ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller cal.setTimeZone(tz); 34752ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller return pos.getIndex(); 34762ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } 34772ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller return ~start; 34782ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } 34792ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller case 32: // 'X' - TIMEZONE_ISO 34802ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller { 34812ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller Style style; 34822ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller switch (count) { 34832ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller case 1: 34842ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller style = Style.ISO_BASIC_SHORT; 34852ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller break; 34862ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller case 2: 34872ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller style = Style.ISO_BASIC_FIXED; 34882ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller break; 34892ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller case 3: 34902ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller style = Style.ISO_EXTENDED_FIXED; 34912ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller break; 34922ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller case 4: 34932ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller style = Style.ISO_BASIC_FULL; 34942ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller break; 34952ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller default: // count >= 5 34962ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller style = Style.ISO_EXTENDED_FULL; 34972ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller break; 34982ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } 34992ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller TimeZone tz = tzFormat().parse(style, text, pos, tzTimeType); 35002ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller if (tz != null) { 35012ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller cal.setTimeZone(tz); 35022ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller return pos.getIndex(); 35032ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } 35042ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller return ~start; 35052ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } 35062ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller case 33: // 'x' - TIMEZONE_ISO_LOCAL 35072ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller { 35082ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller Style style; 35092ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller switch (count) { 35102ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller case 1: 35112ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller style = Style.ISO_BASIC_LOCAL_SHORT; 35122ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller break; 35132ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller case 2: 35142ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller style = Style.ISO_BASIC_LOCAL_FIXED; 35152ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller break; 35162ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller case 3: 35172ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller style = Style.ISO_EXTENDED_LOCAL_FIXED; 35182ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller break; 35192ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller case 4: 35202ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller style = Style.ISO_BASIC_LOCAL_FULL; 35212ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller break; 35222ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller default: // count >= 5 35232ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller style = Style.ISO_EXTENDED_LOCAL_FULL; 35242ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller break; 35252ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } 35262ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller TimeZone tz = tzFormat().parse(style, text, pos, tzTimeType); 35272ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller if (tz != null) { 35282ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller cal.setTimeZone(tz); 35292ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller return pos.getIndex(); 35302ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } 35312ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller return ~start; 35322ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } 35332ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller case 27: // 'Q' - QUARTER 35341c8a530973739aafa823d758240d2cd5dad96fe3Fredrik Roubert if (count <= 2 || (number != null && getBooleanAttribute(DateFormat.BooleanAttribute.PARSE_ALLOW_NUMERIC))) { 35352ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller // i.e., Q or QQ. or lenient & have number 35362ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller // Don't want to parse the quarter if it is a string 35372ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller // while pattern uses numeric style: Q or QQ. 35382ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller // [We computed 'value' above.] 35392ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller cal.set(Calendar.MONTH, (value - 1) * 3); 35402ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller return pos.getIndex(); 35412ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } else { 35422ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller // count >= 3 // i.e., QQQ or QQQQ 35432ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller // Want to be able to parse both short and long forms. 35442ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller // Try count == 4 first: 35452ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller int newStart = 0; 35462ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller if(getBooleanAttribute(DateFormat.BooleanAttribute.PARSE_MULTIPLE_PATTERNS_FOR_MATCH) || count == 4) { 35472ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller if((newStart = matchQuarterString(text, start, Calendar.MONTH, formatData.quarters, cal)) > 0) { 35482ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller return newStart; 35492ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } 35502ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } 35512ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller // count == 4 failed, now try count == 3 35522ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller if(getBooleanAttribute(DateFormat.BooleanAttribute.PARSE_MULTIPLE_PATTERNS_FOR_MATCH) || count == 3) { 35532ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller return matchQuarterString(text, start, Calendar.MONTH, 35542ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller formatData.shortQuarters, cal); 35552ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } 35562ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller return newStart; 35572ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } 35582ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller 35592ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller case 28: // 'q' - STANDALONE QUARTER 35601c8a530973739aafa823d758240d2cd5dad96fe3Fredrik Roubert if (count <= 2 || (number != null && getBooleanAttribute(DateFormat.BooleanAttribute.PARSE_ALLOW_NUMERIC))) { 35612ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller // i.e., q or qq. or lenient & have number 35622ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller // Don't want to parse the quarter if it is a string 35632ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller // while pattern uses numeric style: q or qq. 35642ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller // [We computed 'value' above.] 35652ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller cal.set(Calendar.MONTH, (value - 1) * 3); 35662ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller return pos.getIndex(); 35672ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } else { 35682ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller // count >= 3 // i.e., qqq or qqqq 35692ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller // Want to be able to parse both short and long forms. 35702ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller // Try count == 4 first: 35712ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller int newStart = 0; 35722ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller if(getBooleanAttribute(DateFormat.BooleanAttribute.PARSE_MULTIPLE_PATTERNS_FOR_MATCH) || count == 4) { 35732ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller if((newStart = matchQuarterString(text, start, Calendar.MONTH, formatData.standaloneQuarters, cal)) > 0) { 35742ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller return newStart; 35752ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } 35762ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } 35772ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller // count == 4 failed, now try count == 3 35782ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller if(getBooleanAttribute(DateFormat.BooleanAttribute.PARSE_MULTIPLE_PATTERNS_FOR_MATCH) || count == 3) { 35792ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller return matchQuarterString(text, start, Calendar.MONTH, 35802ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller formatData.standaloneShortQuarters, cal); 35812ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } 35822ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller return newStart; 35832ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } 35842ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller 35851c8a530973739aafa823d758240d2cd5dad96fe3Fredrik Roubert case 37: // TIME SEPARATOR (no pattern character currently defined, we should 35861c8a530973739aafa823d758240d2cd5dad96fe3Fredrik Roubert // not get here but leave support in for future definition. 35872ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller { 35882ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller // Try matching a time separator. 35892ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller ArrayList<String> data = new ArrayList<String>(3); 35902ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller data.add(formatData.getTimeSeparatorString()); 35912ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller 35922ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller // Add the default, if different from the locale. 35932ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller if (!formatData.getTimeSeparatorString().equals(DateFormatSymbols.DEFAULT_TIME_SEPARATOR)) { 35942ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller data.add(DateFormatSymbols.DEFAULT_TIME_SEPARATOR); 35952ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } 35962ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller 35972ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller // If lenient, add also the alternate, if different from the locale. 35982ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller if (getBooleanAttribute(DateFormat.BooleanAttribute.PARSE_PARTIAL_LITERAL_MATCH) && 35992ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller !formatData.getTimeSeparatorString().equals(DateFormatSymbols.ALTERNATE_TIME_SEPARATOR)) { 36002ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller data.add(DateFormatSymbols.ALTERNATE_TIME_SEPARATOR); 36012ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } 36022ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller 36032ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller return matchString(text, start, -1 /* => nothing to set */, data.toArray(new String[0]), cal); 36042ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } 36052ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller 36061c8a530973739aafa823d758240d2cd5dad96fe3Fredrik Roubert case 35: // 'b' -- fixed day period (am/pm/midnight/noon) 36071c8a530973739aafa823d758240d2cd5dad96fe3Fredrik Roubert { 36081c8a530973739aafa823d758240d2cd5dad96fe3Fredrik Roubert int ampmStart = subParse(text, start, 'a', count, obeyCount, allowNegative, ambiguousYear, cal, 36091c8a530973739aafa823d758240d2cd5dad96fe3Fredrik Roubert numericLeapMonthFormatter, tzTimeType, dayPeriod); 36101c8a530973739aafa823d758240d2cd5dad96fe3Fredrik Roubert 36111c8a530973739aafa823d758240d2cd5dad96fe3Fredrik Roubert if (ampmStart > 0) { 36121c8a530973739aafa823d758240d2cd5dad96fe3Fredrik Roubert return ampmStart; 36131c8a530973739aafa823d758240d2cd5dad96fe3Fredrik Roubert } else { 36141c8a530973739aafa823d758240d2cd5dad96fe3Fredrik Roubert int newStart = 0; 36151c8a530973739aafa823d758240d2cd5dad96fe3Fredrik Roubert if(getBooleanAttribute(DateFormat.BooleanAttribute.PARSE_MULTIPLE_PATTERNS_FOR_MATCH) || count == 3) { 36161c8a530973739aafa823d758240d2cd5dad96fe3Fredrik Roubert if ((newStart = matchDayPeriodString( 36171c8a530973739aafa823d758240d2cd5dad96fe3Fredrik Roubert text, start, formatData.abbreviatedDayPeriods, 2, dayPeriod)) > 0) { 36181c8a530973739aafa823d758240d2cd5dad96fe3Fredrik Roubert return newStart; 36191c8a530973739aafa823d758240d2cd5dad96fe3Fredrik Roubert } 36201c8a530973739aafa823d758240d2cd5dad96fe3Fredrik Roubert } 36211c8a530973739aafa823d758240d2cd5dad96fe3Fredrik Roubert if(getBooleanAttribute(DateFormat.BooleanAttribute.PARSE_MULTIPLE_PATTERNS_FOR_MATCH) || count == 4) { 36221c8a530973739aafa823d758240d2cd5dad96fe3Fredrik Roubert if ((newStart = matchDayPeriodString( 36231c8a530973739aafa823d758240d2cd5dad96fe3Fredrik Roubert text, start, formatData.wideDayPeriods, 2, dayPeriod)) > 0) { 36241c8a530973739aafa823d758240d2cd5dad96fe3Fredrik Roubert return newStart; 36251c8a530973739aafa823d758240d2cd5dad96fe3Fredrik Roubert } 36261c8a530973739aafa823d758240d2cd5dad96fe3Fredrik Roubert } 36271c8a530973739aafa823d758240d2cd5dad96fe3Fredrik Roubert if(getBooleanAttribute(DateFormat.BooleanAttribute.PARSE_MULTIPLE_PATTERNS_FOR_MATCH) || count == 4) { 36281c8a530973739aafa823d758240d2cd5dad96fe3Fredrik Roubert if ((newStart = matchDayPeriodString( 36291c8a530973739aafa823d758240d2cd5dad96fe3Fredrik Roubert text, start, formatData.narrowDayPeriods, 2, dayPeriod)) > 0) { 36301c8a530973739aafa823d758240d2cd5dad96fe3Fredrik Roubert return newStart; 36311c8a530973739aafa823d758240d2cd5dad96fe3Fredrik Roubert } 36321c8a530973739aafa823d758240d2cd5dad96fe3Fredrik Roubert } 36331c8a530973739aafa823d758240d2cd5dad96fe3Fredrik Roubert 36341c8a530973739aafa823d758240d2cd5dad96fe3Fredrik Roubert return newStart; 36351c8a530973739aafa823d758240d2cd5dad96fe3Fredrik Roubert } 36361c8a530973739aafa823d758240d2cd5dad96fe3Fredrik Roubert } 36371c8a530973739aafa823d758240d2cd5dad96fe3Fredrik Roubert 36381c8a530973739aafa823d758240d2cd5dad96fe3Fredrik Roubert case 36: // 'B' -- flexible day period 36391c8a530973739aafa823d758240d2cd5dad96fe3Fredrik Roubert { 36401c8a530973739aafa823d758240d2cd5dad96fe3Fredrik Roubert int newStart = 0; 36411c8a530973739aafa823d758240d2cd5dad96fe3Fredrik Roubert if(getBooleanAttribute(DateFormat.BooleanAttribute.PARSE_MULTIPLE_PATTERNS_FOR_MATCH) || count == 3) { 36421c8a530973739aafa823d758240d2cd5dad96fe3Fredrik Roubert if ((newStart = matchDayPeriodString( 36431c8a530973739aafa823d758240d2cd5dad96fe3Fredrik Roubert text, start, formatData.abbreviatedDayPeriods, 36441c8a530973739aafa823d758240d2cd5dad96fe3Fredrik Roubert formatData.abbreviatedDayPeriods.length, dayPeriod)) > 0) { 36451c8a530973739aafa823d758240d2cd5dad96fe3Fredrik Roubert return newStart; 36461c8a530973739aafa823d758240d2cd5dad96fe3Fredrik Roubert } 36471c8a530973739aafa823d758240d2cd5dad96fe3Fredrik Roubert } 36481c8a530973739aafa823d758240d2cd5dad96fe3Fredrik Roubert if(getBooleanAttribute(DateFormat.BooleanAttribute.PARSE_MULTIPLE_PATTERNS_FOR_MATCH) || count == 4) { 36491c8a530973739aafa823d758240d2cd5dad96fe3Fredrik Roubert if ((newStart = matchDayPeriodString( 36501c8a530973739aafa823d758240d2cd5dad96fe3Fredrik Roubert text, start, formatData.wideDayPeriods, 36511c8a530973739aafa823d758240d2cd5dad96fe3Fredrik Roubert formatData.wideDayPeriods.length, dayPeriod)) > 0) { 36521c8a530973739aafa823d758240d2cd5dad96fe3Fredrik Roubert return newStart; 36531c8a530973739aafa823d758240d2cd5dad96fe3Fredrik Roubert } 36541c8a530973739aafa823d758240d2cd5dad96fe3Fredrik Roubert } 36551c8a530973739aafa823d758240d2cd5dad96fe3Fredrik Roubert if(getBooleanAttribute(DateFormat.BooleanAttribute.PARSE_MULTIPLE_PATTERNS_FOR_MATCH) || count == 4) { 36561c8a530973739aafa823d758240d2cd5dad96fe3Fredrik Roubert if ((newStart = matchDayPeriodString( 36571c8a530973739aafa823d758240d2cd5dad96fe3Fredrik Roubert text, start, formatData.narrowDayPeriods, 36581c8a530973739aafa823d758240d2cd5dad96fe3Fredrik Roubert formatData.narrowDayPeriods.length, dayPeriod)) > 0) { 36591c8a530973739aafa823d758240d2cd5dad96fe3Fredrik Roubert return newStart; 36601c8a530973739aafa823d758240d2cd5dad96fe3Fredrik Roubert } 36611c8a530973739aafa823d758240d2cd5dad96fe3Fredrik Roubert } 36621c8a530973739aafa823d758240d2cd5dad96fe3Fredrik Roubert 36631c8a530973739aafa823d758240d2cd5dad96fe3Fredrik Roubert return newStart; 36641c8a530973739aafa823d758240d2cd5dad96fe3Fredrik Roubert } 36651c8a530973739aafa823d758240d2cd5dad96fe3Fredrik Roubert 36662ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller default: 36672ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller // case 3: // 'd' - DATE 36682ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller // case 5: // 'H' - HOUR_OF_DAY (0..23) 36692ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller // case 6: // 'm' - MINUTE 36702ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller // case 7: // 's' - SECOND 36712ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller // case 10: // 'D' - DAY_OF_YEAR 36722ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller // case 11: // 'F' - DAY_OF_WEEK_IN_MONTH 36732ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller // case 12: // 'w' - WEEK_OF_YEAR 36742ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller // case 13: // 'W' - WEEK_OF_MONTH 36751c8a530973739aafa823d758240d2cd5dad96fe3Fredrik Roubert // case 16: // 'K' - HOUR (0..11) 36762ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller // case 20: // 'u' - EXTENDED_YEAR 36772ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller // case 21: // 'g' - JULIAN_DAY 36782ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller // case 22: // 'A' - MILLISECONDS_IN_DAY 36792ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller // case 34: // 36802ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller 36812ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller // Handle "generic" fields 36822ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller if (obeyCount) { 36832ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller if ((start+count) > text.length()) return -start; 36842ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller number = parseInt(text, count, pos, allowNegative,currentNumberFormat); 36852ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } else { 36862ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller number = parseInt(text, pos, allowNegative,currentNumberFormat); 36872ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } 36882ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller if (number != null) { 36892ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller if (patternCharIndex != DateFormat.RELATED_YEAR) { 36902ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller cal.set(field, number.intValue()); 36912ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } else { 36922ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller cal.setRelatedYear(number.intValue()); 36932ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } 36942ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller return pos.getIndex(); 36952ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } 36962ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller return ~start; 36972ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } 36982ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } 36992ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller 37002ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller /** 37012ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * return true if the pattern specified by patternCharIndex is one that allows 37022ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * numeric fallback regardless of actual pattern size. 37032ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller */ 37042ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller private boolean allowNumericFallback(int patternCharIndex) { 37052ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller if (patternCharIndex == 26 /*'L' STAND_ALONE_MONTH*/ || 37062ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller patternCharIndex == 19 /*'e' DOW_LOCAL*/ || 37072ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller patternCharIndex == 25 /*'c' STAND_ALONE_DAY_OF_WEEK*/ || 37082ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller patternCharIndex == 30 /*'U' YEAR_NAME_FIELD*/ || 37092ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller patternCharIndex == 27 /* 'Q' - QUARTER*/ || 37102ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller patternCharIndex == 28 /* 'q' - STANDALONE QUARTER*/) { 37112ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller return true; 37122ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } 37132ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller return false; 37142ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } 37151c8a530973739aafa823d758240d2cd5dad96fe3Fredrik Roubert 37162ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller /** 37172ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * Parse an integer using numberFormat. This method is semantically 37182ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * const, but actually may modify fNumberFormat. 37192ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller */ 37202ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller private Number parseInt(String text, 37212ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller ParsePosition pos, 37222ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller boolean allowNegative, 37232ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller NumberFormat fmt) { 37242ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller return parseInt(text, -1, pos, allowNegative, fmt); 37252ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } 37262ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller 37272ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller /** 37282ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * Parse an integer using numberFormat up to maxDigits. 37292ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller */ 37302ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller private Number parseInt(String text, 37312ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller int maxDigits, 37322ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller ParsePosition pos, 37332ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller boolean allowNegative, 37342ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller NumberFormat fmt) { 37352ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller Number number; 37362ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller int oldPos = pos.getIndex(); 37372ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller if (allowNegative) { 37382ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller number = fmt.parse(text, pos); 37392ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } else { 37402ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller // Invalidate negative numbers 37412ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller if (fmt instanceof DecimalFormat) { 37422ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller String oldPrefix = ((DecimalFormat)fmt).getNegativePrefix(); 37432ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller ((DecimalFormat)fmt).setNegativePrefix(SUPPRESS_NEGATIVE_PREFIX); 37442ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller number = fmt.parse(text, pos); 37452ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller ((DecimalFormat)fmt).setNegativePrefix(oldPrefix); 37462ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } else { 37472ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller boolean dateNumberFormat = (fmt instanceof DateNumberFormat); 37482ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller if (dateNumberFormat) { 37492ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller ((DateNumberFormat)fmt).setParsePositiveOnly(true); 37502ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } 37512ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller number = fmt.parse(text, pos); 37522ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller if (dateNumberFormat) { 37532ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller ((DateNumberFormat)fmt).setParsePositiveOnly(false); 37542ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } 37552ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } 37562ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } 37572ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller if (maxDigits > 0) { 37582ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller // adjust the result to fit into 37592ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller // the maxDigits and move the position back 37602ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller int nDigits = pos.getIndex() - oldPos; 37612ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller if (nDigits > maxDigits) { 37622ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller double val = number.doubleValue(); 37632ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller nDigits -= maxDigits; 37642ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller while (nDigits > 0) { 37652ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller val /= 10; 37662ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller nDigits--; 37672ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } 37682ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller pos.setIndex(oldPos + maxDigits); 37692ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller number = Integer.valueOf((int)val); 37702ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } 37712ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } 37722ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller return number; 37732ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } 37742ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller 37752ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller 37762ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller /** 37772ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * Translate a pattern, mapping each character in the from string to the 37782ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * corresponding character in the to string. 37792ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller */ 37802ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller private String translatePattern(String pat, String from, String to) { 37812ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller StringBuilder result = new StringBuilder(); 37822ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller boolean inQuote = false; 37832ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller for (int i = 0; i < pat.length(); ++i) { 37842ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller char c = pat.charAt(i); 37852ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller if (inQuote) { 37862ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller if (c == '\'') 37872ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller inQuote = false; 37882ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } else { 37892ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller if (c == '\'') { 37902ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller inQuote = true; 37912ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } else if (isSyntaxChar(c)) { 37922ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller int ci = from.indexOf(c); 37932ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller if (ci != -1) { 37942ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller c = to.charAt(ci); 37952ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } 37962ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller // do not worry on translatepattern if the character is not listed 37972ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller // we do the validity check elsewhere 37982ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } 37992ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } 38002ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller result.append(c); 38012ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } 38022ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller if (inQuote) { 38032ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller throw new IllegalArgumentException("Unfinished quote in pattern"); 38042ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } 38052ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller return result.toString(); 38062ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } 38072ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller 38082ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller /** 38092ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * Return a pattern string describing this date format. 38102ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller */ 38112ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller public String toPattern() { 38122ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller return pattern; 38132ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } 38142ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller 38152ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller /** 38162ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * Return a localized pattern string describing this date format. 3817f86f25d102340da66b9c7cb6b2d5ecdc0de43ecfFredrik Roubert * <p> 3818f86f25d102340da66b9c7cb6b2d5ecdc0de43ecfFredrik Roubert * <b>Note:</b> This implementation depends on {@link DateFormatSymbols#getLocalPatternChars()} 3819f86f25d102340da66b9c7cb6b2d5ecdc0de43ecfFredrik Roubert * to get localized format pattern characters. ICU does not include 3820f86f25d102340da66b9c7cb6b2d5ecdc0de43ecfFredrik Roubert * localized pattern character data, therefore, unless user sets localized 3821f86f25d102340da66b9c7cb6b2d5ecdc0de43ecfFredrik Roubert * pattern characters manually, this method returns the same result as 3822f86f25d102340da66b9c7cb6b2d5ecdc0de43ecfFredrik Roubert * {@link #toPattern()}. 38232ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller */ 38242ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller public String toLocalizedPattern() { 38252ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller return translatePattern(pattern, 38262ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller DateFormatSymbols.patternChars, 38272ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller formatData.localPatternChars); 38282ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } 38292ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller 38302ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller /** 38312ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * Apply the given unlocalized pattern string to this date format. 38322ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller */ 38332ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller public void applyPattern(String pat) 38342ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller { 38352ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller this.pattern = pat; 38361c8a530973739aafa823d758240d2cd5dad96fe3Fredrik Roubert parsePattern(); 38371c8a530973739aafa823d758240d2cd5dad96fe3Fredrik Roubert 38382ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller setLocale(null, null); 38392ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller // reset parsed pattern items 38402ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller patternItems = null; 38412ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } 38422ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller 38432ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller /** 38442ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * Apply the given localized pattern string to this date format. 38452ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller */ 38462ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller public void applyLocalizedPattern(String pat) { 38472ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller this.pattern = translatePattern(pat, 38482ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller formatData.localPatternChars, 38492ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller DateFormatSymbols.patternChars); 38502ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller setLocale(null, null); 38512ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } 38522ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller 38532ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller /** 38542ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * Gets the date/time formatting data. 38552ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * @return a copy of the date-time formatting data associated 38562ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * with this date-time formatter. 38572ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller */ 38582ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller public DateFormatSymbols getDateFormatSymbols() 38592ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller { 38602ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller return (DateFormatSymbols)formatData.clone(); 38612ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } 38622ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller 38632ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller /** 38642ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * Allows you to set the date/time formatting data. 38652ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * @param newFormatSymbols the new symbols 38662ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller */ 38672ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller public void setDateFormatSymbols(DateFormatSymbols newFormatSymbols) 38682ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller { 38692ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller this.formatData = (DateFormatSymbols)newFormatSymbols.clone(); 38702ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } 38712ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller 38722ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller /** 38732ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * Method for subclasses to access the DateFormatSymbols. 38742ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller */ 38752ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller protected DateFormatSymbols getSymbols() { 38762ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller return formatData; 38772ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } 38782ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller 38792ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller /** 38801537b2f39245c07b00aa78c3600f7aebcb172490Neil Fuller * <strong>[icu]</strong> Gets the time zone formatter which this date/time 38812ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * formatter uses to format and parse a time zone. 38821c8a530973739aafa823d758240d2cd5dad96fe3Fredrik Roubert * 38832ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * @return the time zone formatter which this date/time 38842ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * formatter uses. 38852ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller */ 38862ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller public TimeZoneFormat getTimeZoneFormat() { 38872ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller return tzFormat().freeze(); 38882ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } 38892ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller 38902ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller /** 38911537b2f39245c07b00aa78c3600f7aebcb172490Neil Fuller * <strong>[icu]</strong> Allows you to set the time zone formatter. 38921c8a530973739aafa823d758240d2cd5dad96fe3Fredrik Roubert * 38932ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * @param tzfmt the new time zone formatter 38942ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller */ 38952ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller public void setTimeZoneFormat(TimeZoneFormat tzfmt) { 38962ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller if (tzfmt.isFrozen()) { 38972ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller // If frozen, use it as is. 38982ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller tzFormat = tzfmt; 38992ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } else { 39002ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller // If not frozen, clone and freeze. 39012ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller tzFormat = tzfmt.cloneAsThawed().freeze(); 39022ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } 39032ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } 39042ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller 39052ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller /** 39062ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * Overrides Cloneable 39072ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller */ 3908f86f25d102340da66b9c7cb6b2d5ecdc0de43ecfFredrik Roubert @Override 39092ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller public Object clone() { 39102ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller SimpleDateFormat other = (SimpleDateFormat) super.clone(); 39112ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller other.formatData = (DateFormatSymbols) formatData.clone(); 39122ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller // We must create a new copy of work buffer used by 39132ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller // the fast numeric field format code. 39142ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller if (this.decimalBuf != null) { 39152ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller other.decimalBuf = new char[DECIMAL_BUF_SIZE]; 39162ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } 39172ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller return other; 39182ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } 39192ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller 39202ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller /** 39212ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * Override hashCode. 39222ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * Generates the hash code for the SimpleDateFormat object 39232ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller */ 3924f86f25d102340da66b9c7cb6b2d5ecdc0de43ecfFredrik Roubert @Override 39252ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller public int hashCode() 39262ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller { 39272ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller return pattern.hashCode(); 39282ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller // just enough fields for a reasonable distribution 39292ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } 39302ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller 39312ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller /** 39322ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * Override equals. 39332ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller */ 3934f86f25d102340da66b9c7cb6b2d5ecdc0de43ecfFredrik Roubert @Override 39352ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller public boolean equals(Object obj) 39362ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller { 39372ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller if (!super.equals(obj)) return false; // super does class check 39382ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller SimpleDateFormat that = (SimpleDateFormat) obj; 39392ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller return (pattern.equals(that.pattern) 39402ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller && formatData.equals(that.formatData)); 39412ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } 39422ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller 39432ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller /** 39442ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * Override writeObject. 39452ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * See http://docs.oracle.com/javase/6/docs/api/java/io/ObjectOutputStream.html 39462ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller */ 39472ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller private void writeObject(ObjectOutputStream stream) throws IOException{ 39482ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller if (defaultCenturyStart == null) { 39492ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller // if defaultCenturyStart is not yet initialized, 39502ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller // calculate and set value before serialization. 39512ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller initializeDefaultCenturyStart(defaultCenturyBase); 39522ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } 39532ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller initializeTimeZoneFormat(false); 39542ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller stream.defaultWriteObject(); 39552ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller stream.writeInt(getContext(DisplayContext.Type.CAPITALIZATION).value()); 39562ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } 39572ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller 39582ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller /** 39592ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * Override readObject. 39602ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * See http://docs.oracle.com/javase/6/docs/api/java/io/ObjectInputStream.html 39612ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller */ 39622ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller private void readObject(ObjectInputStream stream) 39632ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller throws IOException, ClassNotFoundException { 39642ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller stream.defaultReadObject(); 39652ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller int capitalizationSettingValue = (serialVersionOnStream > 1)? stream.readInt(): -1; 39662ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller ///CLOVER:OFF 39672ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller // don't have old serial data to test with 39682ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller if (serialVersionOnStream < 1) { 39692ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller // didn't have defaultCenturyStart field 39702ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller defaultCenturyBase = System.currentTimeMillis(); 39712ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } 39722ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller ///CLOVER:ON 39732ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller else { 39742ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller // fill in dependent transient field 39752ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller parseAmbiguousDatesAsAfter(defaultCenturyStart); 39762ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } 39772ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller serialVersionOnStream = currentSerialVersion; 39782ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller locale = getLocale(ULocale.VALID_LOCALE); 39792ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller if (locale == null) { 39802ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller // ICU4J 3.6 or older versions did not have UFormat locales 39812ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller // in the serialized data. This is just for preventing the 39822ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller // worst case scenario... 39832ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller locale = ULocale.getDefault(Category.FORMAT); 39842ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } 39852ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller 39862ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller initLocalZeroPaddingNumberFormat(); 39872ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller 39882ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller setContext(DisplayContext.CAPITALIZATION_NONE); 39892ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller if (capitalizationSettingValue >= 0) { 39902ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller for (DisplayContext context: DisplayContext.values()) { 39912ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller if (context.value() == capitalizationSettingValue) { 39922ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller setContext(context); 39932ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller break; 39942ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } 39952ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } 39962ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } 39971c8a530973739aafa823d758240d2cd5dad96fe3Fredrik Roubert 39982ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller // if serialized pre-56 update & turned off partial match switch to new enum value 39992ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller if(getBooleanAttribute(DateFormat.BooleanAttribute.PARSE_PARTIAL_MATCH) == false) { 40002ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller setBooleanAttribute(DateFormat.BooleanAttribute.PARSE_PARTIAL_LITERAL_MATCH, false); 40012ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } 40021c8a530973739aafa823d758240d2cd5dad96fe3Fredrik Roubert 40031c8a530973739aafa823d758240d2cd5dad96fe3Fredrik Roubert parsePattern(); 40042ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } 40052ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller 40062ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller /** 40072ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * Format the object to an attributed string, and return the corresponding iterator 40082ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * Overrides superclass method. 40092ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * 40102ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * @param obj The object to format 40112ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * @return <code>AttributedCharacterIterator</code> describing the formatted value. 40122ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller */ 4013f86f25d102340da66b9c7cb6b2d5ecdc0de43ecfFredrik Roubert @Override 40142ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller public AttributedCharacterIterator formatToCharacterIterator(Object obj) { 40152ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller Calendar cal = calendar; 40162ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller if (obj instanceof Calendar) { 40172ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller cal = (Calendar)obj; 40182ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } else if (obj instanceof Date) { 40192ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller calendar.setTime((Date)obj); 40202ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } else if (obj instanceof Number) { 40212ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller calendar.setTimeInMillis(((Number)obj).longValue()); 40222ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } else { 40232ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller throw new IllegalArgumentException("Cannot format given Object as a Date"); 40242ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } 40252ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller StringBuffer toAppendTo = new StringBuffer(); 40262ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller FieldPosition pos = new FieldPosition(0); 40272ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller List<FieldPosition> attributes = new ArrayList<FieldPosition>(); 40282ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller format(cal, getContext(DisplayContext.Type.CAPITALIZATION), toAppendTo, pos, attributes); 40292ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller 40302ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller AttributedString as = new AttributedString(toAppendTo.toString()); 40312ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller 40322ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller // add DateFormat field attributes to the AttributedString 40332ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller for (int i = 0; i < attributes.size(); i++) { 40342ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller FieldPosition fp = attributes.get(i); 40352ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller Format.Field attribute = fp.getFieldAttribute(); 40362ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller as.addAttribute(attribute, attribute, fp.getBeginIndex(), fp.getEndIndex()); 40372ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } 40382ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller // return the CharacterIterator from AttributedString 40392ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller return as.getIterator(); 40402ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } 40412ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller 40422ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller /** 40432ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * Get the locale of this simple date formatter. 40442ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * It is package accessible. also used in DateIntervalFormat. 40452ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * 40462ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * @return locale in this simple date formatter 40472ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller */ 40482ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller ULocale getLocale() 40492ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller { 40502ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller return locale; 40512ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } 40522ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller 40532ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller 40542ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller 40552ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller /** 40562ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * Check whether the 'field' is smaller than all the fields covered in 40572ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * pattern, return true if it is. 40582ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * The sequence of calendar field, 40592ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * from large to small is: ERA, YEAR, MONTH, DATE, AM_PM, HOUR, MINUTE,... 40602ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * @param field the calendar field need to check against 40612ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * @return true if the 'field' is smaller than all the fields 40622ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * covered in pattern. false otherwise. 40632ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller */ 40642ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller 40652ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller boolean isFieldUnitIgnored(int field) { 40662ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller return isFieldUnitIgnored(pattern, field); 40672ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } 40682ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller 40692ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller 40702ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller /* 40712ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * Check whether the 'field' is smaller than all the fields covered in 40722ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * pattern, return true if it is. 40732ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * The sequence of calendar field, 40742ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * from large to small is: ERA, YEAR, MONTH, DATE, AM_PM, HOUR, MINUTE,... 40752ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * @param pattern the pattern to check against 40762ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * @param field the calendar field need to check against 40772ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * @return true if the 'field' is smaller than all the fields 40782ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * covered in pattern. false otherwise. 40792ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller */ 40802ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller static boolean isFieldUnitIgnored(String pattern, int field) { 40812ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller int fieldLevel = CALENDAR_FIELD_TO_LEVEL[field]; 40822ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller int level; 40832ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller char ch; 40842ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller boolean inQuote = false; 40852ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller char prevCh = 0; 40862ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller int count = 0; 40872ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller 40882ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller for (int i = 0; i < pattern.length(); ++i) { 40892ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller ch = pattern.charAt(i); 40902ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller if (ch != prevCh && count > 0) { 40912ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller level = getLevelFromChar(prevCh); 40922ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller if (fieldLevel <= level) { 40932ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller return false; 40942ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } 40952ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller count = 0; 40962ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } 40972ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller if (ch == '\'') { 40982ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller if ((i+1) < pattern.length() && pattern.charAt(i+1) == '\'') { 40992ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller ++i; 41002ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } else { 41012ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller inQuote = ! inQuote; 41022ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } 41032ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } else if (!inQuote && isSyntaxChar(ch)) { 41042ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller prevCh = ch; 41052ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller ++count; 41062ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } 41072ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } 41082ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller if (count > 0) { 41092ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller // last item 41102ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller level = getLevelFromChar(prevCh); 41112ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller if (fieldLevel <= level) { 41122ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller return false; 41132ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } 41142ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } 41152ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller return true; 41162ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } 41172ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller 41182ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller 41192ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller /** 41202ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * Format date interval by algorithm. 41212ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * It is supposed to be used only by CLDR survey tool. 41222ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * 41232ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * @param fromCalendar calendar set to the from date in date interval 41242ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * to be formatted into date interval stirng 41252ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * @param toCalendar calendar set to the to date in date interval 41262ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * to be formatted into date interval stirng 41272ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * @param appendTo Output parameter to receive result. 41282ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * Result is appended to existing contents. 41292ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * @param pos On input: an alignment field, if desired. 41302ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * On output: the offsets of the alignment field. 41312ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * @exception IllegalArgumentException when there is non-recognized 41322ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * pattern letter 41332ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * @return Reference to 'appendTo' parameter. 41342ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * @deprecated This API is ICU internal only. 413593cf604e9dd0525f15bc0a7450b2a35f3884c298Neil Fuller * @hide original deprecated declaration 4136836e6b40a94ec3fb7545a76cb072960442b7eee9Neil Fuller * @hide draft / provisional / internal are hidden on Android 41372ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller */ 41382ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller @Deprecated 41392ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller public final StringBuffer intervalFormatByAlgorithm(Calendar fromCalendar, 41402ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller Calendar toCalendar, 41412ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller StringBuffer appendTo, 41422ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller FieldPosition pos) 41432ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller throws IllegalArgumentException 41442ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller { 41452ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller // not support different calendar types and time zones 41462ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller if ( !fromCalendar.isEquivalentTo(toCalendar) ) { 41472ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller throw new IllegalArgumentException("can not format on two different calendars"); 41482ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } 41492ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller 41502ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller Object[] items = getPatternItems(); 41512ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller int diffBegin = -1; 41522ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller int diffEnd = -1; 41532ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller 41542ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller /* look for different formatting string range */ 41552ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller // look for start of difference 41562ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller try { 41572ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller for (int i = 0; i < items.length; i++) { 41582ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller if ( diffCalFieldValue(fromCalendar, toCalendar, items, i) ) { 41592ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller diffBegin = i; 41602ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller break; 41612ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } 41622ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } 41632ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller 41642ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller if ( diffBegin == -1 ) { 41652ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller // no difference, single date format 41662ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller return format(fromCalendar, appendTo, pos); 41672ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } 41682ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller 41692ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller // look for end of difference 41702ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller for (int i = items.length-1; i >= diffBegin; i--) { 41712ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller if ( diffCalFieldValue(fromCalendar, toCalendar, items, i) ) { 41722ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller diffEnd = i; 41732ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller break; 41742ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } 41752ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } 41762ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } catch ( IllegalArgumentException e ) { 41772ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller throw new IllegalArgumentException(e.toString()); 41782ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } 41792ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller 41802ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller // full range is different 41812ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller if ( diffBegin == 0 && diffEnd == items.length-1 ) { 41822ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller format(fromCalendar, appendTo, pos); 41832ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller appendTo.append(" \u2013 "); // default separator 41842ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller format(toCalendar, appendTo, pos); 41852ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller return appendTo; 41862ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } 41872ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller 41882ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller 41892ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller /* search for largest calendar field within the different range */ 41902ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller int highestLevel = 1000; 41912ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller for (int i = diffBegin; i <= diffEnd; i++) { 41922ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller if ( items[i] instanceof String) { 41932ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller continue; 41942ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } 41952ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller PatternItem item = (PatternItem)items[i]; 41962ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller char ch = item.type; 41972ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller int patternCharIndex = getIndexFromChar(ch); 41982ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller if (patternCharIndex == -1) { 41992ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller throw new IllegalArgumentException("Illegal pattern character " + 42002ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller "'" + ch + "' in \"" + 42012ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller pattern + '"'); 42022ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } 42032ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller 42042ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller if ( patternCharIndex < highestLevel ) { 42052ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller highestLevel = patternCharIndex; 42062ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } 42072ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } 42082ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller 42092ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller /* re-calculate diff range, including those calendar field which 42102ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller is in lower level than the largest calendar field covered 42112ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller in diff range calculated. */ 42122ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller try { 42132ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller for (int i = 0; i < diffBegin; i++) { 42142ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller if ( lowerLevel(items, i, highestLevel) ) { 42152ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller diffBegin = i; 42162ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller break; 42172ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } 42182ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } 42192ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller 42202ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller 42212ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller for (int i = items.length-1; i > diffEnd; i--) { 42222ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller if ( lowerLevel(items, i, highestLevel) ) { 42232ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller diffEnd = i; 42242ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller break; 42252ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } 42262ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } 42272ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } catch ( IllegalArgumentException e ) { 42282ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller throw new IllegalArgumentException(e.toString()); 42292ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } 42302ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller 42312ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller 42322ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller // full range is different 42332ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller if ( diffBegin == 0 && diffEnd == items.length-1 ) { 42342ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller format(fromCalendar, appendTo, pos); 42352ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller appendTo.append(" \u2013 "); // default separator 42362ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller format(toCalendar, appendTo, pos); 42372ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller return appendTo; 42382ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } 42392ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller 42402ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller 42412ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller // formatting 42422ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller // Initialize 42432ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller pos.setBeginIndex(0); 42442ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller pos.setEndIndex(0); 42452ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller DisplayContext capSetting = getContext(DisplayContext.Type.CAPITALIZATION); 42462ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller 42472ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller // formatting date 1 42482ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller for (int i = 0; i <= diffEnd; i++) { 42492ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller if (items[i] instanceof String) { 42502ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller appendTo.append((String)items[i]); 42512ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } else { 42522ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller PatternItem item = (PatternItem)items[i]; 42532ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller if (useFastFormat) { 42542ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller subFormat(appendTo, item.type, item.length, appendTo.length(), 42552ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller i, capSetting, pos, fromCalendar); 42562ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } else { 42572ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller appendTo.append(subFormat(item.type, item.length, appendTo.length(), 42582ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller i, capSetting, pos, fromCalendar)); 42592ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } 42602ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } 42612ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } 42622ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller 42632ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller appendTo.append(" \u2013 "); // default separator 42642ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller 42652ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller // formatting date 2 42662ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller for (int i = diffBegin; i < items.length; i++) { 42672ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller if (items[i] instanceof String) { 42682ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller appendTo.append((String)items[i]); 42692ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } else { 42702ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller PatternItem item = (PatternItem)items[i]; 42712ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller if (useFastFormat) { 42722ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller subFormat(appendTo, item.type, item.length, appendTo.length(), 42732ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller i, capSetting, pos, toCalendar); 42742ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } else { 42752ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller appendTo.append(subFormat(item.type, item.length, appendTo.length(), 42762ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller i, capSetting, pos, toCalendar)); 42772ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } 42782ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } 42792ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } 42802ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller return appendTo; 42812ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } 42822ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller 42832ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller 42842ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller /** 42852ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * check whether the i-th item in 2 calendar is in different value. 42862ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * 42872ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * It is supposed to be used only by CLDR survey tool. 42882ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * It is used by intervalFormatByAlgorithm(). 42892ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * 42902ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * @param fromCalendar one calendar 42912ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * @param toCalendar the other calendar 42922ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * @param items pattern items 42932ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * @param i the i-th item in pattern items 42942ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * @exception IllegalArgumentException when there is non-recognized 42952ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * pattern letter 42962ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * @return true is i-th item in 2 calendar is in different 42972ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * value, false otherwise. 42982ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller */ 42992ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller private boolean diffCalFieldValue(Calendar fromCalendar, 43002ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller Calendar toCalendar, 43012ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller Object[] items, 43022ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller int i) throws IllegalArgumentException { 43032ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller if ( items[i] instanceof String) { 43042ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller return false; 43052ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } 43062ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller PatternItem item = (PatternItem)items[i]; 43072ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller char ch = item.type; 43082ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller int patternCharIndex = getIndexFromChar(ch); 43092ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller if (patternCharIndex == -1) { 43102ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller throw new IllegalArgumentException("Illegal pattern character " + 43112ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller "'" + ch + "' in \"" + 43122ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller pattern + '"'); 43132ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } 43142ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller 43152ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller final int field = PATTERN_INDEX_TO_CALENDAR_FIELD[patternCharIndex]; 43162ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller if (field >= 0) { 43172ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller int value = fromCalendar.get(field); 43182ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller int value_2 = toCalendar.get(field); 43192ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller if ( value != value_2 ) { 43202ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller return true; 43212ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } 43222ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } 43232ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller return false; 43242ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } 43252ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller 43262ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller 43272ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller /** 43282ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * check whether the i-th item's level is lower than the input 'level' 43292ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * 43302ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * It is supposed to be used only by CLDR survey tool. 43312ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * It is used by intervalFormatByAlgorithm(). 43322ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * 43332ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * @param items the pattern items 43342ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * @param i the i-th item in pattern items 43352ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * @param level the level with which the i-th pattern item compared to 43362ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * @exception IllegalArgumentException when there is non-recognized 43372ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * pattern letter 43382ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * @return true if i-th pattern item is lower than 'level', 43392ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * false otherwise 43402ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller */ 43412ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller private boolean lowerLevel(Object[] items, int i, int level) 43422ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller throws IllegalArgumentException { 43432ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller if (items[i] instanceof String) { 43442ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller return false; 43452ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } 43462ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller PatternItem item = (PatternItem)items[i]; 43472ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller char ch = item.type; 43482ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller int patternCharIndex = getLevelFromChar(ch); 43492ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller if (patternCharIndex == -1) { 43502ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller throw new IllegalArgumentException("Illegal pattern character " + 43512ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller "'" + ch + "' in \"" + 43522ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller pattern + '"'); 43532ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } 43542ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller 43552ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller if (patternCharIndex >= level) { 43562ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller return true; 43572ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } 43582ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller return false; 43592ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } 43602ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller 43612ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller /** 43622ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * allow the user to set the NumberFormat for several fields 43632ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * It can be a single field like: "y"(year) or "M"(month) 43642ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * It can be several field combined together: "yMd"(year, month and date) 43651c8a530973739aafa823d758240d2cd5dad96fe3Fredrik Roubert * Note: 43662ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * 1 symbol field is enough for multiple symbol fields (so "y" will override "yy", "yyy") 43672ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * If the field is not numeric, then override has no effect (like "MMM" will use abbreviation, not numerical field) 43681c8a530973739aafa823d758240d2cd5dad96fe3Fredrik Roubert * 43692ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * @param fields the fields to override 43701c8a530973739aafa823d758240d2cd5dad96fe3Fredrik Roubert * @param overrideNF the NumbeferFormat used 43712ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * @exception IllegalArgumentException when the fields contain invalid field 43722ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller */ 43732ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller public void setNumberFormat(String fields, NumberFormat overrideNF) { 43742ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller overrideNF.setGroupingUsed(false); 43752ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller String nsName = "$" + UUID.randomUUID().toString(); 43761c8a530973739aafa823d758240d2cd5dad96fe3Fredrik Roubert 43772ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller // initialize mapping if not there 43782ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller if (numberFormatters == null) { 43792ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller numberFormatters = new HashMap<String, NumberFormat>(); 43802ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } 43812ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller if (overrideMap == null) { 43822ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller overrideMap = new HashMap<Character, String>(); 43832ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } 43842ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller 43852ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller // separate string into char and add to maps 43862ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller for (int i = 0; i < fields.length(); i++) { 43872ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller char field = fields.charAt(i); 43882ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller if (DateFormatSymbols.patternChars.indexOf(field) == -1) { 43892ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller throw new IllegalArgumentException("Illegal field character " + "'" + field + "' in setNumberFormat."); 43902ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } 43912ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller overrideMap.put(field, nsName); 43922ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller numberFormatters.put(nsName, overrideNF); 43932ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } 43942ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller 43952ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller // Since one or more of the override number formatters might be complex, 43962ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller // we can't rely on the fast numfmt where we have a partial field override. 43972ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller useLocalZeroPaddingNumberFormat = false; 43982ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } 43991c8a530973739aafa823d758240d2cd5dad96fe3Fredrik Roubert 44002ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller /** 44012ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * give the NumberFormat used for the field like 'y'(year) and 'M'(year) 44022ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * 44032ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * @param field the field the user wants 44042ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * @return override NumberFormat used for the field 44052ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller */ 44062ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller public NumberFormat getNumberFormat(char field) { 44072ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller Character ovrField; 44082ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller ovrField = Character.valueOf(field); 44092ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller if (overrideMap != null && overrideMap.containsKey(ovrField)) { 44102ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller String nsName = overrideMap.get(ovrField).toString(); 44112ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller NumberFormat nf = numberFormatters.get(nsName); 44122ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller return nf; 44132ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } else { 44142ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller return numberFormat; 44152ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } 44162ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } 44172ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller 44182ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller private void initNumberFormatters(ULocale loc) { 44192ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller 44202ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller numberFormatters = new HashMap<String, NumberFormat>(); 44212ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller overrideMap = new HashMap<Character, String>(); 44222ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller processOverrideString(loc,override); 44232ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller 44242ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } 44252ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller 44262ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller private void processOverrideString(ULocale loc, String str) { 44272ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller 44282ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller if ( str == null || str.length() == 0 ) 44292ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller return; 44302ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller 44312ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller int start = 0; 44322ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller int end; 44332ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller String nsName; 44342ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller Character ovrField; 44352ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller boolean moreToProcess = true; 44362ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller boolean fullOverride; 44372ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller 44382ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller while (moreToProcess) { 44392ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller int delimiterPosition = str.indexOf(";",start); 44402ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller if (delimiterPosition == -1) { 44412ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller moreToProcess = false; 44422ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller end = str.length(); 44432ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } else { 44442ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller end = delimiterPosition; 44452ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } 44462ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller 44472ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller String currentString = str.substring(start,end); 44482ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller int equalSignPosition = currentString.indexOf("="); 44492ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller if (equalSignPosition == -1) { // Simple override string such as "hebrew" 44502ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller nsName = currentString; 44512ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller fullOverride = true; 44522ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } else { // Field specific override string such as "y=hebrew" 44532ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller nsName = currentString.substring(equalSignPosition+1); 44542ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller ovrField = Character.valueOf(currentString.charAt(0)); 44552ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller overrideMap.put(ovrField,nsName); 44562ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller fullOverride = false; 44572ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } 44582ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller 44592ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller ULocale ovrLoc = new ULocale(loc.getBaseName()+"@numbers="+nsName); 44602ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller NumberFormat nf = NumberFormat.createInstance(ovrLoc,NumberFormat.NUMBERSTYLE); 44612ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller nf.setGroupingUsed(false); 44621c8a530973739aafa823d758240d2cd5dad96fe3Fredrik Roubert 44632ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller if (fullOverride) { 44642ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller setNumberFormat(nf); 44652ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } else { 44662ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller // Since one or more of the override number formatters might be complex, 44672ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller // we can't rely on the fast numfmt where we have a partial field override. 44682ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller useLocalZeroPaddingNumberFormat = false; 44692ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } 44702ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller 44712ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller if (!fullOverride && !numberFormatters.containsKey(nsName)) { 44722ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller numberFormatters.put(nsName,nf); 44732ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } 44742ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller 44752ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller start = delimiterPosition + 1; 44762ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } 44772ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } 44781c8a530973739aafa823d758240d2cd5dad96fe3Fredrik Roubert 44791c8a530973739aafa823d758240d2cd5dad96fe3Fredrik Roubert private void parsePattern() { 44801c8a530973739aafa823d758240d2cd5dad96fe3Fredrik Roubert hasMinute = false; 44811c8a530973739aafa823d758240d2cd5dad96fe3Fredrik Roubert hasSecond = false; 44821c8a530973739aafa823d758240d2cd5dad96fe3Fredrik Roubert 44831c8a530973739aafa823d758240d2cd5dad96fe3Fredrik Roubert boolean inQuote = false; 44841c8a530973739aafa823d758240d2cd5dad96fe3Fredrik Roubert for (int i = 0; i < pattern.length(); ++i) { 44851c8a530973739aafa823d758240d2cd5dad96fe3Fredrik Roubert char ch = pattern.charAt(i); 44861c8a530973739aafa823d758240d2cd5dad96fe3Fredrik Roubert if (ch == '\'') { 44871c8a530973739aafa823d758240d2cd5dad96fe3Fredrik Roubert inQuote = !inQuote; 44881c8a530973739aafa823d758240d2cd5dad96fe3Fredrik Roubert } 44891c8a530973739aafa823d758240d2cd5dad96fe3Fredrik Roubert if (!inQuote) { 44901c8a530973739aafa823d758240d2cd5dad96fe3Fredrik Roubert if (ch == 'm') { 44911c8a530973739aafa823d758240d2cd5dad96fe3Fredrik Roubert hasMinute = true; 44921c8a530973739aafa823d758240d2cd5dad96fe3Fredrik Roubert } 44931c8a530973739aafa823d758240d2cd5dad96fe3Fredrik Roubert if (ch == 's') { 44941c8a530973739aafa823d758240d2cd5dad96fe3Fredrik Roubert hasSecond = true; 44951c8a530973739aafa823d758240d2cd5dad96fe3Fredrik Roubert } 44961c8a530973739aafa823d758240d2cd5dad96fe3Fredrik Roubert } 44971c8a530973739aafa823d758240d2cd5dad96fe3Fredrik Roubert } 44981c8a530973739aafa823d758240d2cd5dad96fe3Fredrik Roubert } 44992ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller} 4500