1ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru/*
2ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru*******************************************************************************
31b7d32f919554dda9c193b32188251337bc756f1Fredrik Roubert* Copyright (C) 1997-2015, International Business Machines Corporation and    *
4ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru* others. All Rights Reserved.                                                *
5ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru*******************************************************************************
6ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru*
7ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru* File SMPDTFMT.CPP
8ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru*
9ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru* Modification History:
10ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru*
11ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru*   Date        Name        Description
12ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru*   02/19/97    aliu        Converted from java.
13ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru*   03/31/97    aliu        Modified extensively to work with 50 locales.
14ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru*   04/01/97    aliu        Added support for centuries.
15ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru*   07/09/97    helena      Made ParsePosition into a class.
16ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru*   07/21/98    stephen     Added initializeDefaultCentury.
17ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru*                             Removed getZoneIndex (added in DateFormatSymbols)
18ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru*                             Removed subParseLong
19ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru*                             Removed chk
20ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru*  02/22/99     stephen     Removed character literals for EBCDIC safety
21ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru*   10/14/99    aliu        Updated 2-digit year parsing so that only "00" thru
22ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru*                           "99" are recognized. {j28 4182066}
23ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru*   11/15/99    weiv        Added support for week of year/day of week format
24ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru********************************************************************************
25ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru*/
26ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
27ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru#define ZID_KEY_MAX 128
28ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
29ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru#include "unicode/utypes.h"
30ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
31ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru#if !UCONFIG_NO_FORMATTING
32ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru#include "unicode/smpdtfmt.h"
33ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru#include "unicode/dtfmtsym.h"
34ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru#include "unicode/ures.h"
35ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru#include "unicode/msgfmt.h"
36ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru#include "unicode/calendar.h"
37ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru#include "unicode/gregocal.h"
38ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru#include "unicode/timezone.h"
39ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru#include "unicode/decimfmt.h"
40ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru#include "unicode/dcfmtsym.h"
41ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru#include "unicode/uchar.h"
42b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho#include "unicode/uniset.h"
43ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru#include "unicode/ustring.h"
44b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#include "unicode/basictz.h"
45b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#include "unicode/simpletz.h"
46b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#include "unicode/rbtz.h"
47103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius#include "unicode/tzfmt.h"
48103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius#include "unicode/utf16.h"
49b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#include "unicode/vtzone.h"
5054dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius#include "unicode/udisplaycontext.h"
51fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius#include "unicode/brkiter.h"
52b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#include "olsontz.h"
53b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho#include "patternprops.h"
5450294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho#include "fphdlimp.h"
5550294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho#include "gregoimp.h"
5650294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho#include "hebrwcal.h"
57ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru#include "cstring.h"
58ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru#include "uassert.h"
59b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#include "cmemory.h"
60b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#include "umutex.h"
61ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru#include <float.h>
62b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho#include "smpdtfst.h"
631b7d32f919554dda9c193b32188251337bc756f1Fredrik Roubert#include "sharednumberformat.h"
641b7d32f919554dda9c193b32188251337bc756f1Fredrik Roubert#include "ustr_imp.h"
65ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
66ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru#if defined( U_DEBUG_CALSVC ) || defined (U_DEBUG_CAL)
67ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru#include <stdio.h>
68ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru#endif
69ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
70ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru// *****************************************************************************
71ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru// class SimpleDateFormat
72ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru// *****************************************************************************
73ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
74ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste QueruU_NAMESPACE_BEGIN
75ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
76ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru/**
77ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru * Last-resort string to use for "GMT" when constructing time zone strings.
78ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru */
79ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru// For time zones that have no names, use strings GMT+minutes and
80ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru// GMT-minutes. For instance, in France the time zone is GMT+60.
81ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru// Also accepted are GMT+H:MM or GMT-H:MM.
8254dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius// Currently not being used
8354dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius//static const UChar gGmt[]      = {0x0047, 0x004D, 0x0054, 0x0000};         // "GMT"
8454dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius//static const UChar gGmtPlus[]  = {0x0047, 0x004D, 0x0054, 0x002B, 0x0000}; // "GMT+"
8554dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius//static const UChar gGmtMinus[] = {0x0047, 0x004D, 0x0054, 0x002D, 0x0000}; // "GMT-"
8654dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius//static const UChar gDefGmtPat[]       = {0x0047, 0x004D, 0x0054, 0x007B, 0x0030, 0x007D, 0x0000}; /* GMT{0} */
8754dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius//static const UChar gDefGmtNegHmsPat[] = {0x002D, 0x0048, 0x0048, 0x003A, 0x006D, 0x006D, 0x003A, 0x0073, 0x0073, 0x0000}; /* -HH:mm:ss */
8854dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius//static const UChar gDefGmtNegHmPat[]  = {0x002D, 0x0048, 0x0048, 0x003A, 0x006D, 0x006D, 0x0000}; /* -HH:mm */
8954dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius//static const UChar gDefGmtPosHmsPat[] = {0x002B, 0x0048, 0x0048, 0x003A, 0x006D, 0x006D, 0x003A, 0x0073, 0x0073, 0x0000}; /* +HH:mm:ss */
9054dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius//static const UChar gDefGmtPosHmPat[]  = {0x002B, 0x0048, 0x0048, 0x003A, 0x006D, 0x006D, 0x0000}; /* +HH:mm */
9154dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius//static const UChar gUt[]       = {0x0055, 0x0054, 0x0000};  // "UT"
9254dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius//static const UChar gUtc[]      = {0x0055, 0x0054, 0x0043, 0x0000};  // "UT"
9385bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho
94b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Querutypedef enum GmtPatSize {
95b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    kGmtLen = 3,
96b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    kGmtPatLen = 6,
97b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    kNegHmsLen = 9,
98b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    kNegHmLen = 6,
99b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    kPosHmsLen = 9,
10085bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    kPosHmLen = 6,
10185bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    kUtLen = 2,
10285bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    kUtcLen = 3
103b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru} GmtPatSize;
104ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
10585bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho// Stuff needed for numbering system overrides
10685bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho
10785bf2e2fbc60a9f938064abc8127d61da7d19882Claire Hotypedef enum OvrStrType {
10885bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    kOvrStrDate = 0,
10985bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    kOvrStrTime = 1,
11085bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    kOvrStrBoth = 2
11185bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho} OvrStrType;
11285bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho
11385bf2e2fbc60a9f938064abc8127d61da7d19882Claire Hostatic const UDateFormatField kDateFields[] = {
11485bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    UDAT_YEAR_FIELD,
11585bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    UDAT_MONTH_FIELD,
11685bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    UDAT_DATE_FIELD,
11785bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    UDAT_DAY_OF_YEAR_FIELD,
11885bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    UDAT_DAY_OF_WEEK_IN_MONTH_FIELD,
11985bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    UDAT_WEEK_OF_YEAR_FIELD,
12085bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    UDAT_WEEK_OF_MONTH_FIELD,
12185bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    UDAT_YEAR_WOY_FIELD,
12285bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    UDAT_EXTENDED_YEAR_FIELD,
12385bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    UDAT_JULIAN_DAY_FIELD,
12485bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    UDAT_STANDALONE_DAY_FIELD,
12585bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    UDAT_STANDALONE_MONTH_FIELD,
12685bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    UDAT_QUARTER_FIELD,
127103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius    UDAT_STANDALONE_QUARTER_FIELD,
128fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius    UDAT_YEAR_NAME_FIELD,
129fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius    UDAT_RELATED_YEAR_FIELD };
130fceb39872958b9fa2505e63f8b8699a9e0f882f4ccorneliusstatic const int8_t kDateFieldsCount = 16;
13185bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho
13285bf2e2fbc60a9f938064abc8127d61da7d19882Claire Hostatic const UDateFormatField kTimeFields[] = {
13385bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    UDAT_HOUR_OF_DAY1_FIELD,
13427f654740f2a26ad62a5c155af9199af9e69b889claireho    UDAT_HOUR_OF_DAY0_FIELD,
13585bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    UDAT_MINUTE_FIELD,
13685bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    UDAT_SECOND_FIELD,
13785bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    UDAT_FRACTIONAL_SECOND_FIELD,
13885bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    UDAT_HOUR1_FIELD,
13985bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    UDAT_HOUR0_FIELD,
14085bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    UDAT_MILLISECONDS_IN_DAY_FIELD,
1418393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius    UDAT_TIMEZONE_RFC_FIELD,
1428393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius    UDAT_TIMEZONE_LOCALIZED_GMT_OFFSET_FIELD };
1438393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Corneliusstatic const int8_t kTimeFieldsCount = 10;
14485bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho
14585bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho
146ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru// This is a pattern-of-last-resort used when we can't load a usable pattern out
147ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru// of a resource.
148ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Querustatic const UChar gDefaultPattern[] =
149ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru{
150ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    0x79, 0x79, 0x79, 0x79, 0x4D, 0x4D, 0x64, 0x64, 0x20, 0x68, 0x68, 0x3A, 0x6D, 0x6D, 0x20, 0x61, 0
151ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru};  /* "yyyyMMdd hh:mm a" */
152ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
153ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru// This prefix is designed to NEVER MATCH real text, in order to
154ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru// suppress the parsing of negative numbers.  Adjust as needed (if
155ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru// this becomes valid Unicode).
156ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Querustatic const UChar SUPPRESS_NEGATIVE_PREFIX[] = {0xAB00, 0};
157ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
158ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru/**
159ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru * These are the tags we expect to see in normal resource bundle files associated
160ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru * with a locale.
161ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru */
162ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Querustatic const char gDateTimePatternsTag[]="DateTimePatterns";
163ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
16454dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius//static const UChar gEtcUTC[] = {0x45, 0x74, 0x63, 0x2F, 0x55, 0x54, 0x43, 0x00}; // "Etc/UTC"
165ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Querustatic const UChar QUOTE = 0x27; // Single quote
166b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
167b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho/*
168b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho * The field range check bias for each UDateFormatField.
169b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho * The bias is added to the minimum and maximum values
170b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho * before they are compared to the parsed number.
171b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho * For example, the calendar stores zero-based month numbers
172b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho * but the parsed month numbers start at 1, so the bias is 1.
173b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho *
174b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho * A value of -1 means that the value is not checked.
175b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho */
176b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2clairehostatic const int32_t gFieldRangeBias[] = {
177b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho    -1,  // 'G' - UDAT_ERA_FIELD
178b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho    -1,  // 'y' - UDAT_YEAR_FIELD
179b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho     1,  // 'M' - UDAT_MONTH_FIELD
180b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho     0,  // 'd' - UDAT_DATE_FIELD
181b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho    -1,  // 'k' - UDAT_HOUR_OF_DAY1_FIELD
182b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho    -1,  // 'H' - UDAT_HOUR_OF_DAY0_FIELD
183b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho     0,  // 'm' - UDAT_MINUTE_FIELD
1841b7d32f919554dda9c193b32188251337bc756f1Fredrik Roubert     0,  // 's' - UDAT_SECOND_FIELD
185b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho    -1,  // 'S' - UDAT_FRACTIONAL_SECOND_FIELD (0-999?)
186b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho    -1,  // 'E' - UDAT_DAY_OF_WEEK_FIELD (1-7?)
187b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho    -1,  // 'D' - UDAT_DAY_OF_YEAR_FIELD (1 - 366?)
188b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho    -1,  // 'F' - UDAT_DAY_OF_WEEK_IN_MONTH_FIELD (1-5?)
189b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho    -1,  // 'w' - UDAT_WEEK_OF_YEAR_FIELD (1-52?)
190b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho    -1,  // 'W' - UDAT_WEEK_OF_MONTH_FIELD (1-5?)
191b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho    -1,  // 'a' - UDAT_AM_PM_FIELD
192b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho    -1,  // 'h' - UDAT_HOUR1_FIELD
193b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho    -1,  // 'K' - UDAT_HOUR0_FIELD
194b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho    -1,  // 'z' - UDAT_TIMEZONE_FIELD
195b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho    -1,  // 'Y' - UDAT_YEAR_WOY_FIELD
196b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho    -1,  // 'e' - UDAT_DOW_LOCAL_FIELD
197b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho    -1,  // 'u' - UDAT_EXTENDED_YEAR_FIELD
198b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho    -1,  // 'g' - UDAT_JULIAN_DAY_FIELD
199b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho    -1,  // 'A' - UDAT_MILLISECONDS_IN_DAY_FIELD
200b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho    -1,  // 'Z' - UDAT_TIMEZONE_RFC_FIELD
201b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho    -1,  // 'v' - UDAT_TIMEZONE_GENERIC_FIELD
202b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho     0,  // 'c' - UDAT_STANDALONE_DAY_FIELD
203b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho     1,  // 'L' - UDAT_STANDALONE_MONTH_FIELD
204b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho    -1,  // 'Q' - UDAT_QUARTER_FIELD (1-4?)
205b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho    -1,  // 'q' - UDAT_STANDALONE_QUARTER_FIELD
206fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius    -1,  // 'V' - UDAT_TIMEZONE_SPECIAL_FIELD
207103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius    -1,  // 'U' - UDAT_YEAR_NAME_FIELD
2088393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius    -1,  // 'O' - UDAT_TIMEZONE_LOCALIZED_GMT_OFFSET_FIELD
2098393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius    -1,  // 'X' - UDAT_TIMEZONE_ISO_FIELD
2108393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius    -1,  // 'x' - UDAT_TIMEZONE_ISO_LOCAL_FIELD
211fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius    -1,  // 'r' - UDAT_RELATED_YEAR_FIELD
2121b7d32f919554dda9c193b32188251337bc756f1Fredrik Roubert    -1,  // ':' - UDAT_TIME_SEPARATOR_FIELD
213b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho};
214b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho
21554dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius// When calendar uses hebr numbering (i.e. he@calendar=hebrew),
21654dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius// offset the years within the current millenium down to 1-999
21754dcd9b6a06071f647dac967e9e267abb9410720Craig Corneliusstatic const int32_t HEBREW_CAL_CUR_MILLENIUM_START_YEAR = 5000;
21854dcd9b6a06071f647dac967e9e267abb9410720Craig Corneliusstatic const int32_t HEBREW_CAL_CUR_MILLENIUM_END_YEAR = 6000;
21954dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius
22054dcd9b6a06071f647dac967e9e267abb9410720Craig Corneliusstatic UMutex LOCK = U_MUTEX_INITIALIZER;
221b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
222b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QueruUOBJECT_DEFINE_RTTI_IMPLEMENTATION(SimpleDateFormat)
223ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
2241b7d32f919554dda9c193b32188251337bc756f1Fredrik RoubertSimpleDateFormat::NSOverride::~NSOverride() {
2251b7d32f919554dda9c193b32188251337bc756f1Fredrik Roubert    if (snf != NULL) {
2261b7d32f919554dda9c193b32188251337bc756f1Fredrik Roubert        snf->removeRef();
2271b7d32f919554dda9c193b32188251337bc756f1Fredrik Roubert    }
2281b7d32f919554dda9c193b32188251337bc756f1Fredrik Roubert}
2291b7d32f919554dda9c193b32188251337bc756f1Fredrik Roubert
2301b7d32f919554dda9c193b32188251337bc756f1Fredrik Roubert
2311b7d32f919554dda9c193b32188251337bc756f1Fredrik Roubertvoid SimpleDateFormat::NSOverride::free() {
2321b7d32f919554dda9c193b32188251337bc756f1Fredrik Roubert    NSOverride *cur = this;
2331b7d32f919554dda9c193b32188251337bc756f1Fredrik Roubert    while (cur) {
2341b7d32f919554dda9c193b32188251337bc756f1Fredrik Roubert        NSOverride *next = cur->next;
2351b7d32f919554dda9c193b32188251337bc756f1Fredrik Roubert        delete cur;
2361b7d32f919554dda9c193b32188251337bc756f1Fredrik Roubert        cur = next;
2371b7d32f919554dda9c193b32188251337bc756f1Fredrik Roubert    }
2381b7d32f919554dda9c193b32188251337bc756f1Fredrik Roubert}
2391b7d32f919554dda9c193b32188251337bc756f1Fredrik Roubert
2401b7d32f919554dda9c193b32188251337bc756f1Fredrik Roubert// no matter what the locale's default number format looked like, we want
2411b7d32f919554dda9c193b32188251337bc756f1Fredrik Roubert// to modify it so that it doesn't use thousands separators, doesn't always
2421b7d32f919554dda9c193b32188251337bc756f1Fredrik Roubert// show the decimal point, and recognizes integers only when parsing
2431b7d32f919554dda9c193b32188251337bc756f1Fredrik Roubertstatic void fixNumberFormatForDates(NumberFormat &nf) {
2441b7d32f919554dda9c193b32188251337bc756f1Fredrik Roubert    nf.setGroupingUsed(FALSE);
2451b7d32f919554dda9c193b32188251337bc756f1Fredrik Roubert    DecimalFormat* decfmt = dynamic_cast<DecimalFormat*>(&nf);
2461b7d32f919554dda9c193b32188251337bc756f1Fredrik Roubert    if (decfmt != NULL) {
2471b7d32f919554dda9c193b32188251337bc756f1Fredrik Roubert        decfmt->setDecimalSeparatorAlwaysShown(FALSE);
2481b7d32f919554dda9c193b32188251337bc756f1Fredrik Roubert    }
2491b7d32f919554dda9c193b32188251337bc756f1Fredrik Roubert    nf.setParseIntegerOnly(TRUE);
2501b7d32f919554dda9c193b32188251337bc756f1Fredrik Roubert    nf.setMinimumFractionDigits(0); // To prevent "Jan 1.00, 1997.00"
2511b7d32f919554dda9c193b32188251337bc756f1Fredrik Roubert}
2521b7d32f919554dda9c193b32188251337bc756f1Fredrik Roubert
2531b7d32f919554dda9c193b32188251337bc756f1Fredrik Roubertstatic const SharedNumberFormat *createSharedNumberFormat(
2541b7d32f919554dda9c193b32188251337bc756f1Fredrik Roubert        NumberFormat *nfToAdopt) {
2551b7d32f919554dda9c193b32188251337bc756f1Fredrik Roubert    fixNumberFormatForDates(*nfToAdopt);
2561b7d32f919554dda9c193b32188251337bc756f1Fredrik Roubert    const SharedNumberFormat *result = new SharedNumberFormat(nfToAdopt);
2571b7d32f919554dda9c193b32188251337bc756f1Fredrik Roubert    if (result == NULL) {
2581b7d32f919554dda9c193b32188251337bc756f1Fredrik Roubert        delete nfToAdopt;
2591b7d32f919554dda9c193b32188251337bc756f1Fredrik Roubert    }
2601b7d32f919554dda9c193b32188251337bc756f1Fredrik Roubert    return result;
2611b7d32f919554dda9c193b32188251337bc756f1Fredrik Roubert}
2621b7d32f919554dda9c193b32188251337bc756f1Fredrik Roubert
2631b7d32f919554dda9c193b32188251337bc756f1Fredrik Roubertstatic const SharedNumberFormat *createSharedNumberFormat(
2641b7d32f919554dda9c193b32188251337bc756f1Fredrik Roubert        const Locale &loc, UErrorCode &status) {
2651b7d32f919554dda9c193b32188251337bc756f1Fredrik Roubert    NumberFormat *nf = NumberFormat::createInstance(loc, status);
2661b7d32f919554dda9c193b32188251337bc756f1Fredrik Roubert    if (U_FAILURE(status)) {
2671b7d32f919554dda9c193b32188251337bc756f1Fredrik Roubert        return NULL;
2681b7d32f919554dda9c193b32188251337bc756f1Fredrik Roubert    }
2691b7d32f919554dda9c193b32188251337bc756f1Fredrik Roubert    const SharedNumberFormat *result = createSharedNumberFormat(nf);
2701b7d32f919554dda9c193b32188251337bc756f1Fredrik Roubert    if (result == NULL) {
2711b7d32f919554dda9c193b32188251337bc756f1Fredrik Roubert        status = U_MEMORY_ALLOCATION_ERROR;
2721b7d32f919554dda9c193b32188251337bc756f1Fredrik Roubert    }
2731b7d32f919554dda9c193b32188251337bc756f1Fredrik Roubert    return result;
2741b7d32f919554dda9c193b32188251337bc756f1Fredrik Roubert}
2751b7d32f919554dda9c193b32188251337bc756f1Fredrik Roubert
2761b7d32f919554dda9c193b32188251337bc756f1Fredrik Roubertstatic const SharedNumberFormat **allocSharedNumberFormatters() {
2771b7d32f919554dda9c193b32188251337bc756f1Fredrik Roubert    const SharedNumberFormat **result = (const SharedNumberFormat**)
2781b7d32f919554dda9c193b32188251337bc756f1Fredrik Roubert            uprv_malloc(UDAT_FIELD_COUNT * sizeof(const SharedNumberFormat*));
2791b7d32f919554dda9c193b32188251337bc756f1Fredrik Roubert    if (result == NULL) {
2801b7d32f919554dda9c193b32188251337bc756f1Fredrik Roubert        return NULL;
2811b7d32f919554dda9c193b32188251337bc756f1Fredrik Roubert    }
2821b7d32f919554dda9c193b32188251337bc756f1Fredrik Roubert    for (int32_t i = 0; i < UDAT_FIELD_COUNT; ++i) {
2831b7d32f919554dda9c193b32188251337bc756f1Fredrik Roubert        result[i] = NULL;
2841b7d32f919554dda9c193b32188251337bc756f1Fredrik Roubert    }
2851b7d32f919554dda9c193b32188251337bc756f1Fredrik Roubert    return result;
2861b7d32f919554dda9c193b32188251337bc756f1Fredrik Roubert}
2871b7d32f919554dda9c193b32188251337bc756f1Fredrik Roubert
2881b7d32f919554dda9c193b32188251337bc756f1Fredrik Roubertstatic void freeSharedNumberFormatters(const SharedNumberFormat ** list) {
2891b7d32f919554dda9c193b32188251337bc756f1Fredrik Roubert    for (int32_t i = 0; i < UDAT_FIELD_COUNT; ++i) {
2901b7d32f919554dda9c193b32188251337bc756f1Fredrik Roubert        SharedObject::clearPtr(list[i]);
2911b7d32f919554dda9c193b32188251337bc756f1Fredrik Roubert    }
2921b7d32f919554dda9c193b32188251337bc756f1Fredrik Roubert    uprv_free(list);
2931b7d32f919554dda9c193b32188251337bc756f1Fredrik Roubert}
2941b7d32f919554dda9c193b32188251337bc756f1Fredrik Roubert
2951b7d32f919554dda9c193b32188251337bc756f1Fredrik Roubertconst NumberFormat *SimpleDateFormat::getNumberFormatByIndex(
2961b7d32f919554dda9c193b32188251337bc756f1Fredrik Roubert        UDateFormatField index) const {
2971b7d32f919554dda9c193b32188251337bc756f1Fredrik Roubert    if (fSharedNumberFormatters == NULL ||
2981b7d32f919554dda9c193b32188251337bc756f1Fredrik Roubert        fSharedNumberFormatters[index] == NULL) {
2991b7d32f919554dda9c193b32188251337bc756f1Fredrik Roubert        return fNumberFormat;
3001b7d32f919554dda9c193b32188251337bc756f1Fredrik Roubert    }
3011b7d32f919554dda9c193b32188251337bc756f1Fredrik Roubert    return &(**fSharedNumberFormatters[index]);
3021b7d32f919554dda9c193b32188251337bc756f1Fredrik Roubert}
3031b7d32f919554dda9c193b32188251337bc756f1Fredrik Roubert
3041b7d32f919554dda9c193b32188251337bc756f1Fredrik Roubertclass SimpleDateFormatMutableNFNode {
3051b7d32f919554dda9c193b32188251337bc756f1Fredrik Roubert public:
3061b7d32f919554dda9c193b32188251337bc756f1Fredrik Roubert    const NumberFormat *key;
3071b7d32f919554dda9c193b32188251337bc756f1Fredrik Roubert    NumberFormat *value;
3081b7d32f919554dda9c193b32188251337bc756f1Fredrik Roubert    SimpleDateFormatMutableNFNode()
3091b7d32f919554dda9c193b32188251337bc756f1Fredrik Roubert            : key(NULL), value(NULL) { }
3101b7d32f919554dda9c193b32188251337bc756f1Fredrik Roubert    ~SimpleDateFormatMutableNFNode() {
3111b7d32f919554dda9c193b32188251337bc756f1Fredrik Roubert        delete value;
3121b7d32f919554dda9c193b32188251337bc756f1Fredrik Roubert    }
3131b7d32f919554dda9c193b32188251337bc756f1Fredrik Roubert private:
3141b7d32f919554dda9c193b32188251337bc756f1Fredrik Roubert    SimpleDateFormatMutableNFNode(const SimpleDateFormatMutableNFNode &);
3151b7d32f919554dda9c193b32188251337bc756f1Fredrik Roubert    SimpleDateFormatMutableNFNode &operator=(const SimpleDateFormatMutableNFNode &);
3161b7d32f919554dda9c193b32188251337bc756f1Fredrik Roubert};
3171b7d32f919554dda9c193b32188251337bc756f1Fredrik Roubert
3181b7d32f919554dda9c193b32188251337bc756f1Fredrik Roubert// Single threaded cache of non const NumberFormats. Designed to be stack
3191b7d32f919554dda9c193b32188251337bc756f1Fredrik Roubert// allocated and used for a single format call.
3201b7d32f919554dda9c193b32188251337bc756f1Fredrik Roubertclass SimpleDateFormatMutableNFs : public UMemory {
3211b7d32f919554dda9c193b32188251337bc756f1Fredrik Roubert public:
3221b7d32f919554dda9c193b32188251337bc756f1Fredrik Roubert    SimpleDateFormatMutableNFs() {
3231b7d32f919554dda9c193b32188251337bc756f1Fredrik Roubert    }
3241b7d32f919554dda9c193b32188251337bc756f1Fredrik Roubert
3251b7d32f919554dda9c193b32188251337bc756f1Fredrik Roubert    // Returns a non-const clone of nf which can be safely modified.
3261b7d32f919554dda9c193b32188251337bc756f1Fredrik Roubert    // Subsequent calls with same nf will return the same non-const clone.
3271b7d32f919554dda9c193b32188251337bc756f1Fredrik Roubert    // This object maintains ownership of all returned non-const
3281b7d32f919554dda9c193b32188251337bc756f1Fredrik Roubert    // NumberFormat objects. On memory allocation error returns NULL.
3291b7d32f919554dda9c193b32188251337bc756f1Fredrik Roubert    // Caller must check for NULL return value.
3301b7d32f919554dda9c193b32188251337bc756f1Fredrik Roubert    NumberFormat *get(const NumberFormat *nf) {
3311b7d32f919554dda9c193b32188251337bc756f1Fredrik Roubert        if (nf == NULL) {
3321b7d32f919554dda9c193b32188251337bc756f1Fredrik Roubert            return NULL;
3331b7d32f919554dda9c193b32188251337bc756f1Fredrik Roubert        }
3341b7d32f919554dda9c193b32188251337bc756f1Fredrik Roubert        int32_t idx = 0;
3351b7d32f919554dda9c193b32188251337bc756f1Fredrik Roubert        while (nodes[idx].value) {
3361b7d32f919554dda9c193b32188251337bc756f1Fredrik Roubert            if (nf == nodes[idx].key) {
3371b7d32f919554dda9c193b32188251337bc756f1Fredrik Roubert                return nodes[idx].value;
3381b7d32f919554dda9c193b32188251337bc756f1Fredrik Roubert            }
3391b7d32f919554dda9c193b32188251337bc756f1Fredrik Roubert            ++idx;
3401b7d32f919554dda9c193b32188251337bc756f1Fredrik Roubert        }
3411b7d32f919554dda9c193b32188251337bc756f1Fredrik Roubert        U_ASSERT(idx < UDAT_FIELD_COUNT);
3421b7d32f919554dda9c193b32188251337bc756f1Fredrik Roubert        nodes[idx].key = nf;
3431b7d32f919554dda9c193b32188251337bc756f1Fredrik Roubert        nodes[idx].value = (NumberFormat *) nf->clone();
3441b7d32f919554dda9c193b32188251337bc756f1Fredrik Roubert        return nodes[idx].value;
3451b7d32f919554dda9c193b32188251337bc756f1Fredrik Roubert    }
3461b7d32f919554dda9c193b32188251337bc756f1Fredrik Roubert private:
3471b7d32f919554dda9c193b32188251337bc756f1Fredrik Roubert    // +1 extra for sentinel. If each field had its own NumberFormat, this
3481b7d32f919554dda9c193b32188251337bc756f1Fredrik Roubert    // cache would have to allocate UDAT_FIELD_COUNT mutable versions worst
3491b7d32f919554dda9c193b32188251337bc756f1Fredrik Roubert    // case.
3501b7d32f919554dda9c193b32188251337bc756f1Fredrik Roubert    SimpleDateFormatMutableNFNode nodes[UDAT_FIELD_COUNT + 1];
3511b7d32f919554dda9c193b32188251337bc756f1Fredrik Roubert    SimpleDateFormatMutableNFs(const SimpleDateFormatMutableNFs &);
3521b7d32f919554dda9c193b32188251337bc756f1Fredrik Roubert    SimpleDateFormatMutableNFs &operator=(const SimpleDateFormatMutableNFs &);
3531b7d32f919554dda9c193b32188251337bc756f1Fredrik Roubert};
3541b7d32f919554dda9c193b32188251337bc756f1Fredrik Roubert
355ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru//----------------------------------------------------------------------
356ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
357ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste QueruSimpleDateFormat::~SimpleDateFormat()
358ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru{
359ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    delete fSymbols;
3601b7d32f919554dda9c193b32188251337bc756f1Fredrik Roubert    if (fSharedNumberFormatters) {
3611b7d32f919554dda9c193b32188251337bc756f1Fredrik Roubert        freeSharedNumberFormatters(fSharedNumberFormatters);
36285bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    }
363b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho    if (fTimeZoneFormat) {
364b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho        delete fTimeZoneFormat;
365b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho    }
36685bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho
367fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius#if !UCONFIG_NO_BREAK_ITERATION
368fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius    delete fCapitalizationBrkIter;
369fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius#endif
370ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru}
371ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
372ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru//----------------------------------------------------------------------
373ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
374ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste QueruSimpleDateFormat::SimpleDateFormat(UErrorCode& status)
375ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru  :   fLocale(Locale::getDefault()),
376ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru      fSymbols(NULL),
377b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho      fTimeZoneFormat(NULL),
3781b7d32f919554dda9c193b32188251337bc756f1Fredrik Roubert      fSharedNumberFormatters(NULL),
379fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius      fCapitalizationBrkIter(NULL)
380ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru{
381fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius    initializeBooleanAttributes();
382ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    construct(kShort, (EStyle) (kShort + kDateOffset), fLocale, status);
383ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    initializeDefaultCentury();
384ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru}
385ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
386ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru//----------------------------------------------------------------------
387ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
388ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste QueruSimpleDateFormat::SimpleDateFormat(const UnicodeString& pattern,
389ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                                   UErrorCode &status)
390ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru:   fPattern(pattern),
391ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    fLocale(Locale::getDefault()),
392ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    fSymbols(NULL),
393b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho    fTimeZoneFormat(NULL),
3941b7d32f919554dda9c193b32188251337bc756f1Fredrik Roubert    fSharedNumberFormatters(NULL),
395fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius    fCapitalizationBrkIter(NULL)
396ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru{
39785bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    fDateOverride.setToBogus();
39885bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    fTimeOverride.setToBogus();
399fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius    initializeBooleanAttributes();
4001b7d32f919554dda9c193b32188251337bc756f1Fredrik Roubert    initializeCalendar(NULL,fLocale,status);
4011b7d32f919554dda9c193b32188251337bc756f1Fredrik Roubert    fSymbols = DateFormatSymbols::createForLocale(fLocale, status);
402ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    initialize(fLocale, status);
403ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    initializeDefaultCentury();
40485bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho
40585bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho}
40685bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho//----------------------------------------------------------------------
40785bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho
40885bf2e2fbc60a9f938064abc8127d61da7d19882Claire HoSimpleDateFormat::SimpleDateFormat(const UnicodeString& pattern,
40985bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho                                   const UnicodeString& override,
41085bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho                                   UErrorCode &status)
41185bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho:   fPattern(pattern),
41285bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    fLocale(Locale::getDefault()),
41385bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    fSymbols(NULL),
414b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho    fTimeZoneFormat(NULL),
4151b7d32f919554dda9c193b32188251337bc756f1Fredrik Roubert    fSharedNumberFormatters(NULL),
416fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius    fCapitalizationBrkIter(NULL)
41785bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho{
41885bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    fDateOverride.setTo(override);
41985bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    fTimeOverride.setToBogus();
420fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius    initializeBooleanAttributes();
4211b7d32f919554dda9c193b32188251337bc756f1Fredrik Roubert    initializeCalendar(NULL,fLocale,status);
4221b7d32f919554dda9c193b32188251337bc756f1Fredrik Roubert    fSymbols = DateFormatSymbols::createForLocale(fLocale, status);
42385bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    initialize(fLocale, status);
42485bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    initializeDefaultCentury();
42585bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho
42685bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    processOverrideString(fLocale,override,kOvrStrBoth,status);
42785bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho
428ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru}
429ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
430ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru//----------------------------------------------------------------------
431ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
432ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste QueruSimpleDateFormat::SimpleDateFormat(const UnicodeString& pattern,
433ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                                   const Locale& locale,
434ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                                   UErrorCode& status)
435ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru:   fPattern(pattern),
436ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    fLocale(locale),
437b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho    fTimeZoneFormat(NULL),
4381b7d32f919554dda9c193b32188251337bc756f1Fredrik Roubert    fSharedNumberFormatters(NULL),
439fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius    fCapitalizationBrkIter(NULL)
440ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru{
44185bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho
44285bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    fDateOverride.setToBogus();
44385bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    fTimeOverride.setToBogus();
444fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius    initializeBooleanAttributes();
44585bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho
4461b7d32f919554dda9c193b32188251337bc756f1Fredrik Roubert    initializeCalendar(NULL,fLocale,status);
4471b7d32f919554dda9c193b32188251337bc756f1Fredrik Roubert    fSymbols = DateFormatSymbols::createForLocale(fLocale, status);
448ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    initialize(fLocale, status);
449ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    initializeDefaultCentury();
450ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru}
451ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
452ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru//----------------------------------------------------------------------
453ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
454ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste QueruSimpleDateFormat::SimpleDateFormat(const UnicodeString& pattern,
45585bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho                                   const UnicodeString& override,
45685bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho                                   const Locale& locale,
45785bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho                                   UErrorCode& status)
45885bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho:   fPattern(pattern),
45985bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    fLocale(locale),
460b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho    fTimeZoneFormat(NULL),
4611b7d32f919554dda9c193b32188251337bc756f1Fredrik Roubert    fSharedNumberFormatters(NULL),
462fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius    fCapitalizationBrkIter(NULL)
46385bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho{
46485bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho
46585bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    fDateOverride.setTo(override);
46685bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    fTimeOverride.setToBogus();
467fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius    initializeBooleanAttributes();
46885bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho
4691b7d32f919554dda9c193b32188251337bc756f1Fredrik Roubert    initializeCalendar(NULL,fLocale,status);
4701b7d32f919554dda9c193b32188251337bc756f1Fredrik Roubert    fSymbols = DateFormatSymbols::createForLocale(fLocale, status);
47185bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    initialize(fLocale, status);
47285bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    initializeDefaultCentury();
47385bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho
47485bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    processOverrideString(locale,override,kOvrStrBoth,status);
47585bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho
47685bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho}
47785bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho
47885bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho//----------------------------------------------------------------------
47985bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho
48085bf2e2fbc60a9f938064abc8127d61da7d19882Claire HoSimpleDateFormat::SimpleDateFormat(const UnicodeString& pattern,
481ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                                   DateFormatSymbols* symbolsToAdopt,
482ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                                   UErrorCode& status)
483ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru:   fPattern(pattern),
484ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    fLocale(Locale::getDefault()),
485ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    fSymbols(symbolsToAdopt),
486b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho    fTimeZoneFormat(NULL),
4871b7d32f919554dda9c193b32188251337bc756f1Fredrik Roubert    fSharedNumberFormatters(NULL),
488fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius    fCapitalizationBrkIter(NULL)
489ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru{
49085bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho
49185bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    fDateOverride.setToBogus();
49285bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    fTimeOverride.setToBogus();
493fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius    initializeBooleanAttributes();
49485bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho
495ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    initializeCalendar(NULL,fLocale,status);
496ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    initialize(fLocale, status);
497ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    initializeDefaultCentury();
498ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru}
499ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
500ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru//----------------------------------------------------------------------
501ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
502ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste QueruSimpleDateFormat::SimpleDateFormat(const UnicodeString& pattern,
503ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                                   const DateFormatSymbols& symbols,
504ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                                   UErrorCode& status)
505ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru:   fPattern(pattern),
506ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    fLocale(Locale::getDefault()),
507ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    fSymbols(new DateFormatSymbols(symbols)),
508b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho    fTimeZoneFormat(NULL),
5091b7d32f919554dda9c193b32188251337bc756f1Fredrik Roubert    fSharedNumberFormatters(NULL),
510fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius    fCapitalizationBrkIter(NULL)
511ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru{
51285bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho
51385bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    fDateOverride.setToBogus();
51485bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    fTimeOverride.setToBogus();
515fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius    initializeBooleanAttributes();
51685bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho
517ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    initializeCalendar(NULL, fLocale, status);
518ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    initialize(fLocale, status);
519ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    initializeDefaultCentury();
520ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru}
521ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
522ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru//----------------------------------------------------------------------
523ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
524ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru// Not for public consumption; used by DateFormat
525ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste QueruSimpleDateFormat::SimpleDateFormat(EStyle timeStyle,
526ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                                   EStyle dateStyle,
527ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                                   const Locale& locale,
528ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                                   UErrorCode& status)
529ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru:   fLocale(locale),
530ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    fSymbols(NULL),
531b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho    fTimeZoneFormat(NULL),
5321b7d32f919554dda9c193b32188251337bc756f1Fredrik Roubert    fSharedNumberFormatters(NULL),
533fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius    fCapitalizationBrkIter(NULL)
534ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru{
535fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius    initializeBooleanAttributes();
536ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    construct(timeStyle, dateStyle, fLocale, status);
537ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    if(U_SUCCESS(status)) {
538ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru      initializeDefaultCentury();
539ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    }
540ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru}
541ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
542ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru//----------------------------------------------------------------------
543ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
544ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru/**
545ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru * Not for public consumption; used by DateFormat.  This constructor
546ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru * never fails.  If the resource data is not available, it uses the
547ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru * the last resort symbols.
548ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru */
549ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste QueruSimpleDateFormat::SimpleDateFormat(const Locale& locale,
550ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                                   UErrorCode& status)
551ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru:   fPattern(gDefaultPattern),
552ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    fLocale(locale),
553ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    fSymbols(NULL),
554b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho    fTimeZoneFormat(NULL),
5551b7d32f919554dda9c193b32188251337bc756f1Fredrik Roubert    fSharedNumberFormatters(NULL),
556fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius    fCapitalizationBrkIter(NULL)
557ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru{
558ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    if (U_FAILURE(status)) return;
559fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius    initializeBooleanAttributes();
5601b7d32f919554dda9c193b32188251337bc756f1Fredrik Roubert    initializeCalendar(NULL, fLocale, status);
5611b7d32f919554dda9c193b32188251337bc756f1Fredrik Roubert    fSymbols = DateFormatSymbols::createForLocale(fLocale, status);
562ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    if (U_FAILURE(status))
563ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    {
564ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        status = U_ZERO_ERROR;
565ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        delete fSymbols;
566ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        // This constructor doesn't fail; it uses last resort data
567ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        fSymbols = new DateFormatSymbols(status);
568ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        /* test for NULL */
569ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        if (fSymbols == 0) {
570ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            status = U_MEMORY_ALLOCATION_ERROR;
571ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            return;
572ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        }
573ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    }
574ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
57585bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    fDateOverride.setToBogus();
57685bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    fTimeOverride.setToBogus();
57785bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho
578ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    initialize(fLocale, status);
579ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    if(U_SUCCESS(status)) {
580ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru      initializeDefaultCentury();
581ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    }
582ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru}
583ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
584ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru//----------------------------------------------------------------------
585ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
586ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste QueruSimpleDateFormat::SimpleDateFormat(const SimpleDateFormat& other)
587ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru:   DateFormat(other),
588103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius    fLocale(other.fLocale),
589ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    fSymbols(NULL),
590b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho    fTimeZoneFormat(NULL),
5911b7d32f919554dda9c193b32188251337bc756f1Fredrik Roubert    fSharedNumberFormatters(NULL),
592fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius    fCapitalizationBrkIter(NULL)
593ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru{
594fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius    initializeBooleanAttributes();
595ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    *this = other;
596ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru}
597ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
598ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru//----------------------------------------------------------------------
599ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
600ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste QueruSimpleDateFormat& SimpleDateFormat::operator=(const SimpleDateFormat& other)
601ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru{
602ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    if (this == &other) {
603ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        return *this;
604ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    }
605ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    DateFormat::operator=(other);
6061b7d32f919554dda9c193b32188251337bc756f1Fredrik Roubert    fDateOverride = other.fDateOverride;
6071b7d32f919554dda9c193b32188251337bc756f1Fredrik Roubert    fTimeOverride = other.fTimeOverride;
608ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
609ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    delete fSymbols;
610ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    fSymbols = NULL;
611ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
612ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    if (other.fSymbols)
613ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        fSymbols = new DateFormatSymbols(*other.fSymbols);
614ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
615ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    fDefaultCenturyStart         = other.fDefaultCenturyStart;
616ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    fDefaultCenturyStartYear     = other.fDefaultCenturyStartYear;
617ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    fHaveDefaultCentury          = other.fHaveDefaultCentury;
618ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
619ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    fPattern = other.fPattern;
620ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
621b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho    // TimeZoneFormat in ICU4C only depends on a locale for now
622b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho    if (fLocale != other.fLocale) {
623b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho        delete fTimeZoneFormat;
624103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius        fTimeZoneFormat = NULL; // forces lazy instantiation with the other locale
625103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius        fLocale = other.fLocale;
626b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho    }
627b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho
628fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius#if !UCONFIG_NO_BREAK_ITERATION
629fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius    if (other.fCapitalizationBrkIter != NULL) {
630fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius        fCapitalizationBrkIter = (other.fCapitalizationBrkIter)->clone();
631fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius    }
632fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius#endif
633103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius
6341b7d32f919554dda9c193b32188251337bc756f1Fredrik Roubert    if (fSharedNumberFormatters != NULL) {
6351b7d32f919554dda9c193b32188251337bc756f1Fredrik Roubert        freeSharedNumberFormatters(fSharedNumberFormatters);
6361b7d32f919554dda9c193b32188251337bc756f1Fredrik Roubert        fSharedNumberFormatters = NULL;
6371b7d32f919554dda9c193b32188251337bc756f1Fredrik Roubert    }
6381b7d32f919554dda9c193b32188251337bc756f1Fredrik Roubert    if (other.fSharedNumberFormatters != NULL) {
6391b7d32f919554dda9c193b32188251337bc756f1Fredrik Roubert        fSharedNumberFormatters = allocSharedNumberFormatters();
6401b7d32f919554dda9c193b32188251337bc756f1Fredrik Roubert        if (fSharedNumberFormatters) {
6411b7d32f919554dda9c193b32188251337bc756f1Fredrik Roubert            for (int32_t i = 0; i < UDAT_FIELD_COUNT; ++i) {
6421b7d32f919554dda9c193b32188251337bc756f1Fredrik Roubert                SharedObject::copyPtr(
6431b7d32f919554dda9c193b32188251337bc756f1Fredrik Roubert                        other.fSharedNumberFormatters[i],
6441b7d32f919554dda9c193b32188251337bc756f1Fredrik Roubert                        fSharedNumberFormatters[i]);
6451b7d32f919554dda9c193b32188251337bc756f1Fredrik Roubert            }
6461b7d32f919554dda9c193b32188251337bc756f1Fredrik Roubert        }
6471b7d32f919554dda9c193b32188251337bc756f1Fredrik Roubert    }
6481b7d32f919554dda9c193b32188251337bc756f1Fredrik Roubert
649ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    return *this;
650ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru}
651ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
652ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru//----------------------------------------------------------------------
653ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
654ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste QueruFormat*
655ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste QueruSimpleDateFormat::clone() const
656ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru{
657ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    return new SimpleDateFormat(*this);
658ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru}
659ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
660ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru//----------------------------------------------------------------------
661ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
662ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste QueruUBool
663ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste QueruSimpleDateFormat::operator==(const Format& other) const
664ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru{
665ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    if (DateFormat::operator==(other)) {
666fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius        // The DateFormat::operator== check for fCapitalizationContext equality above
667fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius        //   is sufficient to check equality of all derived context-related data.
668ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        // DateFormat::operator== guarantees following cast is safe
669ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        SimpleDateFormat* that = (SimpleDateFormat*)&other;
670ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        return (fPattern             == that->fPattern &&
671ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                fSymbols             != NULL && // Check for pathological object
672ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                that->fSymbols       != NULL && // Check for pathological object
673ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                *fSymbols            == *that->fSymbols &&
674ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                fHaveDefaultCentury  == that->fHaveDefaultCentury &&
675fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius                fDefaultCenturyStart == that->fDefaultCenturyStart);
676ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    }
677ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    return FALSE;
678ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru}
679ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
680ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru//----------------------------------------------------------------------
681ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
682ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queruvoid SimpleDateFormat::construct(EStyle timeStyle,
683ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                                 EStyle dateStyle,
684ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                                 const Locale& locale,
685ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                                 UErrorCode& status)
686ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru{
687ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    // called by several constructors to load pattern data from the resources
688ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    if (U_FAILURE(status)) return;
689ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
690ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    // We will need the calendar to know what type of symbols to load.
691ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    initializeCalendar(NULL, locale, status);
692ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    if (U_FAILURE(status)) return;
693ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
694ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    CalendarData calData(locale, fCalendar?fCalendar->getType():NULL, status);
695ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    UResourceBundle *dateTimePatterns = calData.getByKey(gDateTimePatternsTag, status);
69685bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    UResourceBundle *currentBundle;
69785bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho
698ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    if (U_FAILURE(status)) return;
699ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
700ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    if (ures_getSize(dateTimePatterns) <= kDateTime)
701ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    {
702ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        status = U_INVALID_FORMAT_ERROR;
703ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        return;
704ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    }
705ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
706ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    setLocaleIDs(ures_getLocaleByType(dateTimePatterns, ULOC_VALID_LOCALE, &status),
707ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                 ures_getLocaleByType(dateTimePatterns, ULOC_ACTUAL_LOCALE, &status));
708ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
709ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    // create a symbols object from the locale
7101b7d32f919554dda9c193b32188251337bc756f1Fredrik Roubert    fSymbols = DateFormatSymbols::createForLocale(locale, status);
711ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    if (U_FAILURE(status)) return;
712ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    /* test for NULL */
713ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    if (fSymbols == 0) {
714ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        status = U_MEMORY_ALLOCATION_ERROR;
715ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        return;
716ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    }
717ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
71885bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    const UChar *resStr,*ovrStr;
71985bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    int32_t resStrLen,ovrStrLen = 0;
72085bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    fDateOverride.setToBogus();
72185bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    fTimeOverride.setToBogus();
722ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
723ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    // if the pattern should include both date and time information, use the date/time
724ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    // pattern string as a guide to tell use how to glue together the appropriate date
725ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    // and time pattern strings.  The actual gluing-together is handled by a convenience
726ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    // method on MessageFormat.
727ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    if ((timeStyle != kNone) && (dateStyle != kNone))
728ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    {
729ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        Formattable timeDateArray[2];
730ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
731ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        // use Formattable::adoptString() so that we can use fastCopyFrom()
732ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        // instead of Formattable::setString()'s unaware, safe, deep string clone
733ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        // see Jitterbug 2296
73450294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho
73585bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho        currentBundle = ures_getByIndex(dateTimePatterns, (int32_t)timeStyle, NULL, &status);
73685bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho        if (U_FAILURE(status)) {
73785bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho           status = U_INVALID_FORMAT_ERROR;
73885bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho           return;
73985bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho        }
74085bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho        switch (ures_getType(currentBundle)) {
74185bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho            case URES_STRING: {
74285bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho               resStr = ures_getString(currentBundle, &resStrLen, &status);
74385bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho               break;
74485bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho            }
74585bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho            case URES_ARRAY: {
74685bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho               resStr = ures_getStringByIndex(currentBundle, 0, &resStrLen, &status);
74785bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho               ovrStr = ures_getStringByIndex(currentBundle, 1, &ovrStrLen, &status);
74885bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho               fTimeOverride.setTo(TRUE, ovrStr, ovrStrLen);
74985bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho               break;
75085bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho            }
75185bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho            default: {
75285bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho               status = U_INVALID_FORMAT_ERROR;
75385bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho               ures_close(currentBundle);
75485bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho               return;
75585bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho            }
75650294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho        }
75785bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho        ures_close(currentBundle);
75850294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho
75985bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho        UnicodeString *tempus1 = new UnicodeString(TRUE, resStr, resStrLen);
76085bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho        // NULL pointer check
76185bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho        if (tempus1 == NULL) {
76285bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho            status = U_MEMORY_ALLOCATION_ERROR;
76385bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho            return;
76485bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho        }
76585bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho        timeDateArray[0].adoptString(tempus1);
76650294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho
76785bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho        currentBundle = ures_getByIndex(dateTimePatterns, (int32_t)dateStyle, NULL, &status);
76885bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho        if (U_FAILURE(status)) {
76985bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho           status = U_INVALID_FORMAT_ERROR;
77085bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho           return;
77185bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho        }
77285bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho        switch (ures_getType(currentBundle)) {
77385bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho            case URES_STRING: {
77485bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho               resStr = ures_getString(currentBundle, &resStrLen, &status);
77550294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho               break;
77685bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho            }
77785bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho            case URES_ARRAY: {
77885bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho               resStr = ures_getStringByIndex(currentBundle, 0, &resStrLen, &status);
77985bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho               ovrStr = ures_getStringByIndex(currentBundle, 1, &ovrStrLen, &status);
78085bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho               fDateOverride.setTo(TRUE, ovrStr, ovrStrLen);
78150294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho               break;
78285bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho            }
78385bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho            default: {
78485bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho               status = U_INVALID_FORMAT_ERROR;
78585bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho               ures_close(currentBundle);
78685bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho               return;
78785bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho            }
78850294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho        }
78985bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho        ures_close(currentBundle);
79085bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho
79185bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho        UnicodeString *tempus2 = new UnicodeString(TRUE, resStr, resStrLen);
79285bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho        // Null pointer check
79385bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho        if (tempus2 == NULL) {
79485bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho            status = U_MEMORY_ALLOCATION_ERROR;
79585bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho            return;
79685bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho        }
79785bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho        timeDateArray[1].adoptString(tempus2);
798ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
79985bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho        int32_t glueIndex = kDateTime;
80085bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho        int32_t patternsSize = ures_getSize(dateTimePatterns);
80185bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho        if (patternsSize >= (kDateTimeOffset + kShort + 1)) {
80285bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho            // Get proper date time format
80385bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho            glueIndex = (int32_t)(kDateTimeOffset + (dateStyle - kDateOffset));
80485bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho        }
80585bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho
80685bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho        resStr = ures_getStringByIndex(dateTimePatterns, glueIndex, &resStrLen, &status);
807ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        MessageFormat::format(UnicodeString(TRUE, resStr, resStrLen), timeDateArray, 2, fPattern, status);
808ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    }
809ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    // if the pattern includes just time data or just date date, load the appropriate
810ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    // pattern string from the resources
811ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    // setTo() - see DateFormatSymbols::assignArray comments
812ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    else if (timeStyle != kNone) {
81385bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho        currentBundle = ures_getByIndex(dateTimePatterns, (int32_t)timeStyle, NULL, &status);
81485bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho        if (U_FAILURE(status)) {
81585bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho           status = U_INVALID_FORMAT_ERROR;
81685bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho           return;
81785bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho        }
81885bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho        switch (ures_getType(currentBundle)) {
81985bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho            case URES_STRING: {
82085bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho               resStr = ures_getString(currentBundle, &resStrLen, &status);
82150294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho               break;
82285bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho            }
82385bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho            case URES_ARRAY: {
82485bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho               resStr = ures_getStringByIndex(currentBundle, 0, &resStrLen, &status);
82585bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho               ovrStr = ures_getStringByIndex(currentBundle, 1, &ovrStrLen, &status);
82685bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho               fDateOverride.setTo(TRUE, ovrStr, ovrStrLen);
82750294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho               break;
82885bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho            }
82985bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho            default: {
83085bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho               status = U_INVALID_FORMAT_ERROR;
83185bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho                ures_close(currentBundle);
83285bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho               return;
83385bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho            }
83450294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho        }
835ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        fPattern.setTo(TRUE, resStr, resStrLen);
83685bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho        ures_close(currentBundle);
837ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    }
838ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    else if (dateStyle != kNone) {
83985bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho        currentBundle = ures_getByIndex(dateTimePatterns, (int32_t)dateStyle, NULL, &status);
84085bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho        if (U_FAILURE(status)) {
84185bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho           status = U_INVALID_FORMAT_ERROR;
84285bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho           return;
84385bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho        }
84485bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho        switch (ures_getType(currentBundle)) {
84585bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho            case URES_STRING: {
84685bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho               resStr = ures_getString(currentBundle, &resStrLen, &status);
84750294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho               break;
84885bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho            }
84985bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho            case URES_ARRAY: {
85085bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho               resStr = ures_getStringByIndex(currentBundle, 0, &resStrLen, &status);
85185bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho               ovrStr = ures_getStringByIndex(currentBundle, 1, &ovrStrLen, &status);
85285bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho               fDateOverride.setTo(TRUE, ovrStr, ovrStrLen);
85350294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho               break;
85485bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho            }
85585bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho            default: {
85685bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho               status = U_INVALID_FORMAT_ERROR;
85785bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho               ures_close(currentBundle);
85885bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho               return;
85985bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho            }
86050294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho        }
861ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        fPattern.setTo(TRUE, resStr, resStrLen);
86285bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho        ures_close(currentBundle);
863ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    }
86450294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho
865ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    // and if it includes _neither_, that's an error
866ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    else
867ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        status = U_INVALID_FORMAT_ERROR;
868ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
869ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    // finally, finish initializing by creating a Calendar and a NumberFormat
870ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    initialize(locale, status);
871ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru}
872ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
873ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru//----------------------------------------------------------------------
874ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
875ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste QueruCalendar*
876ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste QueruSimpleDateFormat::initializeCalendar(TimeZone* adoptZone, const Locale& locale, UErrorCode& status)
877ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru{
878ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    if(!U_FAILURE(status)) {
879ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        fCalendar = Calendar::createInstance(adoptZone?adoptZone:TimeZone::createDefault(), locale, status);
880ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    }
881ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    return fCalendar;
882ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru}
883ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
884ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queruvoid
885ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste QueruSimpleDateFormat::initialize(const Locale& locale,
886ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                             UErrorCode& status)
887ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru{
888ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    if (U_FAILURE(status)) return;
889ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
890ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    // We don't need to check that the row count is >= 1, since all 2d arrays have at
891ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    // least one row
892ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    fNumberFormat = NumberFormat::createInstance(locale, status);
893ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    if (fNumberFormat != NULL && U_SUCCESS(status))
894ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    {
8951b7d32f919554dda9c193b32188251337bc756f1Fredrik Roubert        fixNumberFormatForDates(*fNumberFormat);
896b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho        //fNumberFormat->setLenient(TRUE); // Java uses a custom DateNumberFormat to format/parse
897b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho
89885bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho        initNumberFormatters(locale,status);
89950294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho
900ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    }
901ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    else if (U_SUCCESS(status))
902ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    {
903ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        status = U_MISSING_RESOURCE_ERROR;
904ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    }
905ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru}
906ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
907ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru/* Initialize the fields we use to disambiguate ambiguous years. Separate
908ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru * so we can call it from readObject().
909ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru */
91050294ead5e5d23f5bbfed76e00e6b510bd41eee1clairehovoid SimpleDateFormat::initializeDefaultCentury()
911ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru{
912ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru  if(fCalendar) {
913ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    fHaveDefaultCentury = fCalendar->haveDefaultCentury();
914ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    if(fHaveDefaultCentury) {
915ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru      fDefaultCenturyStart = fCalendar->defaultCenturyStart();
916ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru      fDefaultCenturyStartYear = fCalendar->defaultCenturyStartYear();
917ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    } else {
918ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru      fDefaultCenturyStart = DBL_MIN;
919ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru      fDefaultCenturyStartYear = -1;
920ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    }
921ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru  }
922ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru}
923ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
924fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius/*
925fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius * Initialize the boolean attributes. Separate so we can call it from all constructors.
926fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius */
927fceb39872958b9fa2505e63f8b8699a9e0f882f4ccorneliusvoid SimpleDateFormat::initializeBooleanAttributes()
928fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius{
929fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius    UErrorCode status = U_ZERO_ERROR;
930fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius
931fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius    setBooleanAttribute(UDAT_PARSE_ALLOW_WHITESPACE, true, status);
932fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius    setBooleanAttribute(UDAT_PARSE_ALLOW_NUMERIC, true, status);
933fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius    setBooleanAttribute(UDAT_PARSE_PARTIAL_MATCH, true, status);
934fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius    setBooleanAttribute(UDAT_PARSE_MULTIPLE_PATTERNS_FOR_MATCH, true, status);
935fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius}
936fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius
937ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru/* Define one-century window into which to disambiguate dates using
938ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru * two-digit years. Make public in JDK 1.2.
939ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru */
94050294ead5e5d23f5bbfed76e00e6b510bd41eee1clairehovoid SimpleDateFormat::parseAmbiguousDatesAsAfter(UDate startDate, UErrorCode& status)
941ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru{
942ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    if(U_FAILURE(status)) {
943ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        return;
944ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    }
945ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    if(!fCalendar) {
946ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru      status = U_ILLEGAL_ARGUMENT_ERROR;
947ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru      return;
948ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    }
94950294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho
950ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    fCalendar->setTime(startDate, status);
951ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    if(U_SUCCESS(status)) {
952ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        fHaveDefaultCentury = TRUE;
953ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        fDefaultCenturyStart = startDate;
954ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        fDefaultCenturyStartYear = fCalendar->get(UCAL_YEAR, status);
955ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    }
956ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru}
95750294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho
958ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru//----------------------------------------------------------------------
959ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
960ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste QueruUnicodeString&
961ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste QueruSimpleDateFormat::format(Calendar& cal, UnicodeString& appendTo, FieldPosition& pos) const
962ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru{
96350294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho  UErrorCode status = U_ZERO_ERROR;
96450294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho  FieldPositionOnlyHandler handler(pos);
96554dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius  return _format(cal, appendTo, handler, status);
96650294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho}
96750294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho
96850294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho//----------------------------------------------------------------------
96950294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho
97050294ead5e5d23f5bbfed76e00e6b510bd41eee1clairehoUnicodeString&
97150294ead5e5d23f5bbfed76e00e6b510bd41eee1clairehoSimpleDateFormat::format(Calendar& cal, UnicodeString& appendTo,
97250294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho                         FieldPositionIterator* posIter, UErrorCode& status) const
97350294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho{
97450294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho  FieldPositionIteratorHandler handler(posIter, status);
97554dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius  return _format(cal, appendTo, handler, status);
97650294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho}
97750294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho
97850294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho//----------------------------------------------------------------------
979ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
98050294ead5e5d23f5bbfed76e00e6b510bd41eee1clairehoUnicodeString&
98154dcd9b6a06071f647dac967e9e267abb9410720Craig CorneliusSimpleDateFormat::_format(Calendar& cal, UnicodeString& appendTo,
98254dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius                            FieldPositionHandler& handler, UErrorCode& status) const
98350294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho{
984103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius    if ( U_FAILURE(status) ) {
985103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius       return appendTo;
986103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius    }
987103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius    Calendar* workCal = &cal;
988103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius    Calendar* calClone = NULL;
98985bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    if (&cal != fCalendar && uprv_strcmp(cal.getType(), fCalendar->getType()) != 0) {
99085bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho        // Different calendar type
99185bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho        // We use the time and time zone from the input calendar, but
99285bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho        // do not use the input calendar for field calculation.
993103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius        calClone = fCalendar->clone();
994103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius        if (calClone != NULL) {
995103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius            UDate t = cal.getTime(status);
996103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius            calClone->setTime(t, status);
997103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius            calClone->setTimeZone(cal.getTimeZone());
998103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius            workCal = calClone;
999103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius        } else {
1000103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius            status = U_MEMORY_ALLOCATION_ERROR;
1001103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius            return appendTo;
1002103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius        }
100385bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    }
100485bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho
1005ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    UBool inQuote = FALSE;
1006ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    UChar prevCh = 0;
1007ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    int32_t count = 0;
1008103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius    int32_t fieldNum = 0;
1009fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius    UDisplayContext capitalizationContext = getContext(UDISPCTX_TYPE_CAPITALIZATION, status);
101050294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho
10111b7d32f919554dda9c193b32188251337bc756f1Fredrik Roubert    // Create temporary cache of mutable number format objects. This way
10121b7d32f919554dda9c193b32188251337bc756f1Fredrik Roubert    // subFormat won't have to clone the const NumberFormat for each field.
10131b7d32f919554dda9c193b32188251337bc756f1Fredrik Roubert    // if several fields share the same NumberFormat, which will almost
10141b7d32f919554dda9c193b32188251337bc756f1Fredrik Roubert    // always be the case, this is a big save.
10151b7d32f919554dda9c193b32188251337bc756f1Fredrik Roubert    SimpleDateFormatMutableNFs mutableNFs;
1016ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    // loop through the pattern string character by character
1017ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    for (int32_t i = 0; i < fPattern.length() && U_SUCCESS(status); ++i) {
1018ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        UChar ch = fPattern[i];
101950294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho
1020ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        // Use subFormat() to format a repeated pattern character
1021ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        // when a different pattern or non-pattern character is seen
1022ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        if (ch != prevCh && count > 0) {
10231b7d32f919554dda9c193b32188251337bc756f1Fredrik Roubert            subFormat(appendTo, prevCh, count, capitalizationContext, fieldNum++, handler, *workCal, mutableNFs, status);
1024ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            count = 0;
1025ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        }
1026ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        if (ch == QUOTE) {
1027ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            // Consecutive single quotes are a single quote literal,
1028ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            // either outside of quotes or between quotes
1029ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            if ((i+1) < fPattern.length() && fPattern[i+1] == QUOTE) {
1030ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                appendTo += (UChar)QUOTE;
1031ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                ++i;
1032ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            } else {
1033ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                inQuote = ! inQuote;
1034ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            }
103550294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho        }
10361b7d32f919554dda9c193b32188251337bc756f1Fredrik Roubert        else if (!inQuote && isSyntaxChar(ch)) {
1037ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            // ch is a date-time pattern character to be interpreted
1038ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            // by subFormat(); count the number of times it is repeated
1039ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            prevCh = ch;
1040ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            ++count;
1041ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        }
1042ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        else {
1043ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            // Append quoted characters and unquoted non-pattern characters
1044ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            appendTo += ch;
1045ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        }
1046ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    }
1047ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
1048ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    // Format the last item in the pattern, if any
1049ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    if (count > 0) {
10501b7d32f919554dda9c193b32188251337bc756f1Fredrik Roubert        subFormat(appendTo, prevCh, count, capitalizationContext, fieldNum++, handler, *workCal, mutableNFs, status);
105185bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    }
105285bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho
1053103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius    if (calClone != NULL) {
1054103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius        delete calClone;
1055ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    }
1056ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
1057ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    return appendTo;
1058ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru}
1059ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
1060ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru//----------------------------------------------------------------------
1061ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
106285bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho/* Map calendar field into calendar field level.
106385bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho * the larger the level, the smaller the field unit.
106485bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho * For example, UCAL_ERA level is 0, UCAL_YEAR level is 10,
106585bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho * UCAL_MONTH level is 20.
106685bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho * NOTE: if new fields adds in, the table needs to update.
106785bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho */
106885bf2e2fbc60a9f938064abc8127d61da7d19882Claire Hoconst int32_t
106985bf2e2fbc60a9f938064abc8127d61da7d19882Claire HoSimpleDateFormat::fgCalendarFieldToLevel[] =
107085bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho{
107185bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    /*GyM*/ 0, 10, 20,
107285bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    /*wW*/ 20, 30,
107385bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    /*dDEF*/ 30, 20, 30, 30,
107485bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    /*ahHm*/ 40, 50, 50, 60,
1075fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius    /*sS*/ 70, 80,
107650294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    /*z?Y*/ 0, 0, 10,
107785bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    /*eug*/ 30, 10, 0,
1078fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius    /*A?.*/ 40, 0, 0
107985bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho};
108085bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho
10811b7d32f919554dda9c193b32188251337bc756f1Fredrik Roubertint32_t SimpleDateFormat::getLevelFromChar(UChar ch) {
10821b7d32f919554dda9c193b32188251337bc756f1Fredrik Roubert    // Map date field LETTER into calendar field level.
10831b7d32f919554dda9c193b32188251337bc756f1Fredrik Roubert    // the larger the level, the smaller the field unit.
10841b7d32f919554dda9c193b32188251337bc756f1Fredrik Roubert    // NOTE: if new fields adds in, the table needs to update.
10851b7d32f919554dda9c193b32188251337bc756f1Fredrik Roubert    static const int32_t mapCharToLevel[] = {
10861b7d32f919554dda9c193b32188251337bc756f1Fredrik Roubert            -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
10871b7d32f919554dda9c193b32188251337bc756f1Fredrik Roubert        //
10881b7d32f919554dda9c193b32188251337bc756f1Fredrik Roubert            -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
10891b7d32f919554dda9c193b32188251337bc756f1Fredrik Roubert        //       !   "   #   $   %   &   '   (   )   *   +   ,   -   .   /
10901b7d32f919554dda9c193b32188251337bc756f1Fredrik Roubert            -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
10911b7d32f919554dda9c193b32188251337bc756f1Fredrik Roubert        //   0   1   2   3   4   5   6   7   8   9   :   ;   <   =   >   ?
10921b7d32f919554dda9c193b32188251337bc756f1Fredrik Roubert            -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,  0, -1, -1, -1, -1, -1,
10931b7d32f919554dda9c193b32188251337bc756f1Fredrik Roubert        //   @   A   B   C   D   E   F   G   H   I   J   K   L   M   N   O
10941b7d32f919554dda9c193b32188251337bc756f1Fredrik Roubert            -1, 40, -1, -1, 20, 30, 30,  0, 50, -1, -1, 50, 20, 20, -1,  0,
10951b7d32f919554dda9c193b32188251337bc756f1Fredrik Roubert        //   P   Q   R   S   T   U   V   W   X   Y   Z   [   \   ]   ^   _
10961b7d32f919554dda9c193b32188251337bc756f1Fredrik Roubert            -1, 20, -1, 80, -1, 10,  0, 30,  0, 10,  0, -1, -1, -1, -1, -1,
10971b7d32f919554dda9c193b32188251337bc756f1Fredrik Roubert        //   `   a   b   c   d   e   f   g   h   i   j   k   l   m   n   o
10981b7d32f919554dda9c193b32188251337bc756f1Fredrik Roubert            -1, 40, -1, 30, 30, 30, -1,  0, 50, -1, -1, 50,  0, 60, -1, -1,
10991b7d32f919554dda9c193b32188251337bc756f1Fredrik Roubert        //   p   q   r   s   t   u   v   w   x   y   z   {   |   }   ~
11001b7d32f919554dda9c193b32188251337bc756f1Fredrik Roubert            -1, 20, 10, 70, -1, 10,  0, 20,  0, 10,  0, -1, -1, -1, -1, -1
11011b7d32f919554dda9c193b32188251337bc756f1Fredrik Roubert    };
11021b7d32f919554dda9c193b32188251337bc756f1Fredrik Roubert
11031b7d32f919554dda9c193b32188251337bc756f1Fredrik Roubert    return ch < UPRV_LENGTHOF(mapCharToLevel) ? mapCharToLevel[ch] : -1;
11041b7d32f919554dda9c193b32188251337bc756f1Fredrik Roubert}
110585bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho
11061b7d32f919554dda9c193b32188251337bc756f1Fredrik RoubertUBool SimpleDateFormat::isSyntaxChar(UChar ch) {
11071b7d32f919554dda9c193b32188251337bc756f1Fredrik Roubert    static const UBool mapCharToIsSyntax[] = {
11081b7d32f919554dda9c193b32188251337bc756f1Fredrik Roubert        //
11091b7d32f919554dda9c193b32188251337bc756f1Fredrik Roubert        FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE,
11101b7d32f919554dda9c193b32188251337bc756f1Fredrik Roubert        //
11111b7d32f919554dda9c193b32188251337bc756f1Fredrik Roubert        FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE,
11121b7d32f919554dda9c193b32188251337bc756f1Fredrik Roubert        //
11131b7d32f919554dda9c193b32188251337bc756f1Fredrik Roubert        FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE,
11141b7d32f919554dda9c193b32188251337bc756f1Fredrik Roubert        //
11151b7d32f919554dda9c193b32188251337bc756f1Fredrik Roubert        FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE,
11161b7d32f919554dda9c193b32188251337bc756f1Fredrik Roubert        //         !      "      #      $      %      &      '
11171b7d32f919554dda9c193b32188251337bc756f1Fredrik Roubert        FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE,
11181b7d32f919554dda9c193b32188251337bc756f1Fredrik Roubert        //  (      )      *      +      ,      -      .      /
11191b7d32f919554dda9c193b32188251337bc756f1Fredrik Roubert        FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE,
11201b7d32f919554dda9c193b32188251337bc756f1Fredrik Roubert        //  0      1      2      3      4      5      6      7
11211b7d32f919554dda9c193b32188251337bc756f1Fredrik Roubert        FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE,
11221b7d32f919554dda9c193b32188251337bc756f1Fredrik Roubert        //  8      9      :      ;      <      =      >      ?
11231b7d32f919554dda9c193b32188251337bc756f1Fredrik Roubert        FALSE, FALSE,  TRUE, FALSE, FALSE, FALSE, FALSE, FALSE,
11241b7d32f919554dda9c193b32188251337bc756f1Fredrik Roubert        //  @      A      B      C      D      E      F      G
11251b7d32f919554dda9c193b32188251337bc756f1Fredrik Roubert        FALSE,  TRUE,  TRUE,  TRUE,  TRUE,  TRUE,  TRUE,  TRUE,
11261b7d32f919554dda9c193b32188251337bc756f1Fredrik Roubert        //  H      I      J      K      L      M      N      O
11271b7d32f919554dda9c193b32188251337bc756f1Fredrik Roubert         TRUE,  TRUE,  TRUE,  TRUE,  TRUE,  TRUE,  TRUE,  TRUE,
11281b7d32f919554dda9c193b32188251337bc756f1Fredrik Roubert        //  P      Q      R      S      T      U      V      W
11291b7d32f919554dda9c193b32188251337bc756f1Fredrik Roubert         TRUE,  TRUE,  TRUE,  TRUE,  TRUE,  TRUE,  TRUE,  TRUE,
11301b7d32f919554dda9c193b32188251337bc756f1Fredrik Roubert        //  X      Y      Z      [      \      ]      ^      _
11311b7d32f919554dda9c193b32188251337bc756f1Fredrik Roubert         TRUE,  TRUE,  TRUE, FALSE, FALSE, FALSE, FALSE, FALSE,
11321b7d32f919554dda9c193b32188251337bc756f1Fredrik Roubert        //  `      a      b      c      d      e      f      g
11331b7d32f919554dda9c193b32188251337bc756f1Fredrik Roubert        FALSE,  TRUE,  TRUE,  TRUE,  TRUE,  TRUE,  TRUE,  TRUE,
11341b7d32f919554dda9c193b32188251337bc756f1Fredrik Roubert        //  h      i      j      k      l      m      n      o
11351b7d32f919554dda9c193b32188251337bc756f1Fredrik Roubert         TRUE,  TRUE,  TRUE,  TRUE,  TRUE,  TRUE,  TRUE,  TRUE,
11361b7d32f919554dda9c193b32188251337bc756f1Fredrik Roubert        //  p      q      r      s      t      u      v      w
11371b7d32f919554dda9c193b32188251337bc756f1Fredrik Roubert         TRUE,  TRUE,  TRUE,  TRUE,  TRUE,  TRUE,  TRUE,  TRUE,
11381b7d32f919554dda9c193b32188251337bc756f1Fredrik Roubert        //  x      y      z      {      |      }      ~
11391b7d32f919554dda9c193b32188251337bc756f1Fredrik Roubert         TRUE,  TRUE,  TRUE, FALSE, FALSE, FALSE, FALSE, FALSE
11401b7d32f919554dda9c193b32188251337bc756f1Fredrik Roubert    };
11411b7d32f919554dda9c193b32188251337bc756f1Fredrik Roubert
11421b7d32f919554dda9c193b32188251337bc756f1Fredrik Roubert    return ch < UPRV_LENGTHOF(mapCharToIsSyntax) ? mapCharToIsSyntax[ch] : FALSE;
11431b7d32f919554dda9c193b32188251337bc756f1Fredrik Roubert}
114485bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho
1145ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru// Map index into pattern character string to Calendar field number.
1146ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queruconst UCalendarDateFields
1147ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste QueruSimpleDateFormat::fgPatternIndexToCalendarField[] =
1148ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru{
1149ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    /*GyM*/ UCAL_ERA, UCAL_YEAR, UCAL_MONTH,
1150ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    /*dkH*/ UCAL_DATE, UCAL_HOUR_OF_DAY, UCAL_HOUR_OF_DAY,
1151ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    /*msS*/ UCAL_MINUTE, UCAL_SECOND, UCAL_MILLISECOND,
1152ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    /*EDF*/ UCAL_DAY_OF_WEEK, UCAL_DAY_OF_YEAR, UCAL_DAY_OF_WEEK_IN_MONTH,
1153ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    /*wWa*/ UCAL_WEEK_OF_YEAR, UCAL_WEEK_OF_MONTH, UCAL_AM_PM,
1154ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    /*hKz*/ UCAL_HOUR, UCAL_HOUR, UCAL_ZONE_OFFSET,
1155ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    /*Yeu*/ UCAL_YEAR_WOY, UCAL_DOW_LOCAL, UCAL_EXTENDED_YEAR,
1156ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    /*gAZ*/ UCAL_JULIAN_DAY, UCAL_MILLISECONDS_IN_DAY, UCAL_ZONE_OFFSET,
1157ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    /*v*/   UCAL_ZONE_OFFSET,
115885bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    /*c*/   UCAL_DOW_LOCAL,
1159ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    /*L*/   UCAL_MONTH,
1160ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    /*Q*/   UCAL_MONTH,
1161ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    /*q*/   UCAL_MONTH,
1162ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    /*V*/   UCAL_ZONE_OFFSET,
1163103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius    /*U*/   UCAL_YEAR,
11648393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius    /*O*/   UCAL_ZONE_OFFSET,
11658393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius    /*Xx*/  UCAL_ZONE_OFFSET, UCAL_ZONE_OFFSET,
1166fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius    /*r*/   UCAL_EXTENDED_YEAR,
11671b7d32f919554dda9c193b32188251337bc756f1Fredrik Roubert    /*:*/   UCAL_FIELD_COUNT, /* => no useful mapping to any calendar field */
1168ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru};
1169ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
1170ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru// Map index into pattern character string to DateFormat field number
1171ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queruconst UDateFormatField
1172ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste QueruSimpleDateFormat::fgPatternIndexToDateFormatField[] = {
1173ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    /*GyM*/ UDAT_ERA_FIELD, UDAT_YEAR_FIELD, UDAT_MONTH_FIELD,
1174ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    /*dkH*/ UDAT_DATE_FIELD, UDAT_HOUR_OF_DAY1_FIELD, UDAT_HOUR_OF_DAY0_FIELD,
1175ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    /*msS*/ UDAT_MINUTE_FIELD, UDAT_SECOND_FIELD, UDAT_FRACTIONAL_SECOND_FIELD,
1176ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    /*EDF*/ UDAT_DAY_OF_WEEK_FIELD, UDAT_DAY_OF_YEAR_FIELD, UDAT_DAY_OF_WEEK_IN_MONTH_FIELD,
1177ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    /*wWa*/ UDAT_WEEK_OF_YEAR_FIELD, UDAT_WEEK_OF_MONTH_FIELD, UDAT_AM_PM_FIELD,
1178ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    /*hKz*/ UDAT_HOUR1_FIELD, UDAT_HOUR0_FIELD, UDAT_TIMEZONE_FIELD,
1179ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    /*Yeu*/ UDAT_YEAR_WOY_FIELD, UDAT_DOW_LOCAL_FIELD, UDAT_EXTENDED_YEAR_FIELD,
1180ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    /*gAZ*/ UDAT_JULIAN_DAY_FIELD, UDAT_MILLISECONDS_IN_DAY_FIELD, UDAT_TIMEZONE_RFC_FIELD,
1181ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    /*v*/   UDAT_TIMEZONE_GENERIC_FIELD,
1182ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    /*c*/   UDAT_STANDALONE_DAY_FIELD,
1183ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    /*L*/   UDAT_STANDALONE_MONTH_FIELD,
1184ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    /*Q*/   UDAT_QUARTER_FIELD,
1185ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    /*q*/   UDAT_STANDALONE_QUARTER_FIELD,
1186ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    /*V*/   UDAT_TIMEZONE_SPECIAL_FIELD,
1187103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius    /*U*/   UDAT_YEAR_NAME_FIELD,
11888393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius    /*O*/   UDAT_TIMEZONE_LOCALIZED_GMT_OFFSET_FIELD,
11898393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius    /*Xx*/  UDAT_TIMEZONE_ISO_FIELD, UDAT_TIMEZONE_ISO_LOCAL_FIELD,
1190fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius    /*r*/   UDAT_RELATED_YEAR_FIELD,
11911b7d32f919554dda9c193b32188251337bc756f1Fredrik Roubert    /*:*/   UDAT_TIME_SEPARATOR_FIELD,
1192ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru};
1193ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
1194ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru//----------------------------------------------------------------------
1195ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
1196ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru/**
1197ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru * Append symbols[value] to dst.  Make sure the array index is not out
1198ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru * of bounds.
1199ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru */
1200ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Querustatic inline void
1201ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru_appendSymbol(UnicodeString& dst,
1202ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru              int32_t value,
1203ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru              const UnicodeString* symbols,
1204ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru              int32_t symbolsCount) {
1205ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    U_ASSERT(0 <= value && value < symbolsCount);
1206ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    if (0 <= value && value < symbolsCount) {
1207ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        dst += symbols[value];
1208ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    }
1209ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru}
1210ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
1211103e9ffba2cba345d0078eb8b8db33249f81840aCraig Corneliusstatic inline void
1212103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius_appendSymbolWithMonthPattern(UnicodeString& dst, int32_t value, const UnicodeString* symbols, int32_t symbolsCount,
1213103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius              const UnicodeString* monthPattern, UErrorCode& status) {
1214103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius    U_ASSERT(0 <= value && value < symbolsCount);
1215103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius    if (0 <= value && value < symbolsCount) {
1216103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius        if (monthPattern == NULL) {
1217103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius            dst += symbols[value];
1218b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        } else {
1219103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius            Formattable monthName((const UnicodeString&)(symbols[value]));
1220103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius            MessageFormat::format(*monthPattern, &monthName, 1, dst, status);
1221b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        }
1222b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    }
1223ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru}
1224ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
1225103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius//----------------------------------------------------------------------
122685bf2e2fbc60a9f938064abc8127d61da7d19882Claire Hovoid
122785bf2e2fbc60a9f938064abc8127d61da7d19882Claire HoSimpleDateFormat::initNumberFormatters(const Locale &locale,UErrorCode &status) {
122885bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    if (U_FAILURE(status)) {
122985bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho        return;
123085bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    }
123185bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    if ( fDateOverride.isBogus() && fTimeOverride.isBogus() ) {
123285bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho        return;
123385bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    }
123485bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    umtx_lock(&LOCK);
12351b7d32f919554dda9c193b32188251337bc756f1Fredrik Roubert    if (fSharedNumberFormatters == NULL) {
12361b7d32f919554dda9c193b32188251337bc756f1Fredrik Roubert        fSharedNumberFormatters = allocSharedNumberFormatters();
12371b7d32f919554dda9c193b32188251337bc756f1Fredrik Roubert        if (fSharedNumberFormatters == NULL) {
123885bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho            status = U_MEMORY_ALLOCATION_ERROR;
123985bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho        }
124085bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    }
124185bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    umtx_unlock(&LOCK);
124250294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho
1243f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius    if (U_FAILURE(status)) {
1244f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius        return;
1245f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius    }
1246f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius
124785bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    processOverrideString(locale,fDateOverride,kOvrStrDate,status);
124885bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    processOverrideString(locale,fTimeOverride,kOvrStrTime,status);
124985bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho}
125085bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho
125185bf2e2fbc60a9f938064abc8127d61da7d19882Claire Hovoid
125285bf2e2fbc60a9f938064abc8127d61da7d19882Claire HoSimpleDateFormat::processOverrideString(const Locale &locale, const UnicodeString &str, int8_t type, UErrorCode &status) {
1253f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius    if (str.isBogus() || U_FAILURE(status)) {
125485bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho        return;
125585bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    }
1256f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius
125785bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    int32_t start = 0;
125885bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    int32_t len;
125985bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    UnicodeString nsName;
126085bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    UnicodeString ovrField;
126185bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    UBool moreToProcess = TRUE;
12621b7d32f919554dda9c193b32188251337bc756f1Fredrik Roubert    NSOverride *overrideList = NULL;
126385bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho
126485bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    while (moreToProcess) {
1265b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho        int32_t delimiterPosition = str.indexOf((UChar)ULOC_KEYWORD_ITEM_SEPARATOR_UNICODE,start);
126685bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho        if (delimiterPosition == -1) {
126785bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho            moreToProcess = FALSE;
126885bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho            len = str.length() - start;
126985bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho        } else {
127085bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho            len = delimiterPosition - start;
127185bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho        }
127285bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho        UnicodeString currentString(str,start,len);
1273b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho        int32_t equalSignPosition = currentString.indexOf((UChar)ULOC_KEYWORD_ASSIGN_UNICODE,0);
127485bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho        if (equalSignPosition == -1) { // Simple override string such as "hebrew"
127585bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho            nsName.setTo(currentString);
127685bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho            ovrField.setToBogus();
127785bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho        } else { // Field specific override string such as "y=hebrew"
127885bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho            nsName.setTo(currentString,equalSignPosition+1);
127985bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho            ovrField.setTo(currentString,0,1); // We just need the first character.
128085bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho        }
128185bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho
128285bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho        int32_t nsNameHash = nsName.hashCode();
128385bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho        // See if the numbering system is in the override list, if not, then add it.
12841b7d32f919554dda9c193b32188251337bc756f1Fredrik Roubert        NSOverride *cur = overrideList;
12851b7d32f919554dda9c193b32188251337bc756f1Fredrik Roubert        const SharedNumberFormat *snf = NULL;
128685bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho        UBool found = FALSE;
128785bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho        while ( cur && !found ) {
128885bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho            if ( cur->hash == nsNameHash ) {
12891b7d32f919554dda9c193b32188251337bc756f1Fredrik Roubert                snf = cur->snf;
129085bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho                found = TRUE;
129185bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho            }
129285bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho            cur = cur->next;
129385bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho        }
129485bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho
129585bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho        if (!found) {
12961b7d32f919554dda9c193b32188251337bc756f1Fredrik Roubert           LocalPointer<NSOverride> cur(new NSOverride);
12971b7d32f919554dda9c193b32188251337bc756f1Fredrik Roubert           if (!cur.isNull()) {
129885bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho               char kw[ULOC_KEYWORD_AND_VALUES_CAPACITY];
129985bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho               uprv_strcpy(kw,"numbers=");
130085bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho               nsName.extract(0,len,kw+8,ULOC_KEYWORD_AND_VALUES_CAPACITY-8,US_INV);
130185bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho
130285bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho               Locale ovrLoc(locale.getLanguage(),locale.getCountry(),locale.getVariant(),kw);
13031b7d32f919554dda9c193b32188251337bc756f1Fredrik Roubert               cur->hash = nsNameHash;
13041b7d32f919554dda9c193b32188251337bc756f1Fredrik Roubert               cur->next = overrideList;
13051b7d32f919554dda9c193b32188251337bc756f1Fredrik Roubert               SharedObject::copyPtr(
13061b7d32f919554dda9c193b32188251337bc756f1Fredrik Roubert                       createSharedNumberFormat(ovrLoc, status), cur->snf);
13071b7d32f919554dda9c193b32188251337bc756f1Fredrik Roubert               if (U_FAILURE(status)) {
13081b7d32f919554dda9c193b32188251337bc756f1Fredrik Roubert                   if (overrideList) {
13091b7d32f919554dda9c193b32188251337bc756f1Fredrik Roubert                       overrideList->free();
131085bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho                   }
13111b7d32f919554dda9c193b32188251337bc756f1Fredrik Roubert                   return;
131285bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho               }
13131b7d32f919554dda9c193b32188251337bc756f1Fredrik Roubert               snf = cur->snf;
13141b7d32f919554dda9c193b32188251337bc756f1Fredrik Roubert               overrideList = cur.orphan();
131585bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho           } else {
131685bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho               status = U_MEMORY_ALLOCATION_ERROR;
13171b7d32f919554dda9c193b32188251337bc756f1Fredrik Roubert               if (overrideList) {
13181b7d32f919554dda9c193b32188251337bc756f1Fredrik Roubert                   overrideList->free();
13191b7d32f919554dda9c193b32188251337bc756f1Fredrik Roubert               }
132085bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho               return;
132185bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho           }
132285bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho        }
132350294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho
132485bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho        // Now that we have an appropriate number formatter, fill in the appropriate spaces in the
132585bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho        // number formatters table.
132685bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho        if (ovrField.isBogus()) {
132785bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho            switch (type) {
132885bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho                case kOvrStrDate:
132985bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho                case kOvrStrBoth: {
133085bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho                    for ( int8_t i=0 ; i<kDateFieldsCount; i++ ) {
13311b7d32f919554dda9c193b32188251337bc756f1Fredrik Roubert                        SharedObject::copyPtr(snf, fSharedNumberFormatters[kDateFields[i]]);
133285bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho                    }
133385bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho                    if (type==kOvrStrDate) {
133485bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho                        break;
133585bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho                    }
133685bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho                }
133785bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho                case kOvrStrTime : {
133885bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho                    for ( int8_t i=0 ; i<kTimeFieldsCount; i++ ) {
13391b7d32f919554dda9c193b32188251337bc756f1Fredrik Roubert                        SharedObject::copyPtr(snf, fSharedNumberFormatters[kTimeFields[i]]);
134085bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho                    }
134185bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho                    break;
134285bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho                }
134385bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho            }
134485bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho        } else {
134585bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho           // if the pattern character is unrecognized, signal an error and bail out
134654dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius           UDateFormatField patternCharIndex =
134754dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius              DateFormatSymbols::getPatternCharIndex(ovrField.charAt(0));
134854dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius           if (patternCharIndex == UDAT_FIELD_COUNT) {
134985bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho               status = U_INVALID_FORMAT_ERROR;
13501b7d32f919554dda9c193b32188251337bc756f1Fredrik Roubert               if (overrideList) {
13511b7d32f919554dda9c193b32188251337bc756f1Fredrik Roubert                   overrideList->free();
13521b7d32f919554dda9c193b32188251337bc756f1Fredrik Roubert               }
135385bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho               return;
135485bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho           }
13551b7d32f919554dda9c193b32188251337bc756f1Fredrik Roubert           SharedObject::copyPtr(snf, fSharedNumberFormatters[patternCharIndex]);
135685bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho        }
135785bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho
135885bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho        start = delimiterPosition + 1;
135985bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    }
13601b7d32f919554dda9c193b32188251337bc756f1Fredrik Roubert    if (overrideList) {
13611b7d32f919554dda9c193b32188251337bc756f1Fredrik Roubert        overrideList->free();
13621b7d32f919554dda9c193b32188251337bc756f1Fredrik Roubert    }
136350294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho}
136454dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius
1365ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru//---------------------------------------------------------------------
1366ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queruvoid
1367ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste QueruSimpleDateFormat::subFormat(UnicodeString &appendTo,
1368ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                            UChar ch,
1369ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                            int32_t count,
137054dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius                            UDisplayContext capitalizationContext,
1371103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius                            int32_t fieldNum,
137250294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho                            FieldPositionHandler& handler,
1373ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                            Calendar& cal,
13741b7d32f919554dda9c193b32188251337bc756f1Fredrik Roubert                            SimpleDateFormatMutableNFs &mutableNFs,
1375ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                            UErrorCode& status) const
1376ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru{
1377ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    if (U_FAILURE(status)) {
1378ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        return;
1379ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    }
1380ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
1381ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    // this function gets called by format() to produce the appropriate substitution
1382ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    // text for an individual pattern symbol (e.g., "HH" or "yyyy")
1383ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
138454dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius    UDateFormatField patternCharIndex = DateFormatSymbols::getPatternCharIndex(ch);
1385ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    const int32_t maxIntCount = 10;
1386ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    int32_t beginOffset = appendTo.length();
138785bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    NumberFormat *currentNumberFormat;
1388103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius    DateFormatSymbols::ECapitalizationContextUsageType capContextUsageType = DateFormatSymbols::kCapContextUsageOther;
1389ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
1390103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius    UBool isHebrewCalendar = (uprv_strcmp(cal.getType(),"hebrew") == 0);
139159d709d503bab6e2b61931737e662dd293b40578ccornelius    UBool isChineseCalendar = (uprv_strcmp(cal.getType(),"chinese") == 0 || uprv_strcmp(cal.getType(),"dangi") == 0);
139250294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho
1393ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    // if the pattern character is unrecognized, signal an error and dump out
139454dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius    if (patternCharIndex == UDAT_FIELD_COUNT)
1395ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    {
1396103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius        if (ch != 0x6C) { // pattern char 'l' (SMALL LETTER L) just gets ignored
1397103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius            status = U_INVALID_FORMAT_ERROR;
1398103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius        }
1399ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        return;
1400ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    }
1401ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
1402ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    UCalendarDateFields field = fgPatternIndexToCalendarField[patternCharIndex];
14031b7d32f919554dda9c193b32188251337bc756f1Fredrik Roubert    int32_t value = 0;
14041b7d32f919554dda9c193b32188251337bc756f1Fredrik Roubert    // Don't get value unless it is useful
14051b7d32f919554dda9c193b32188251337bc756f1Fredrik Roubert    if (field < UCAL_FIELD_COUNT) {
14061b7d32f919554dda9c193b32188251337bc756f1Fredrik Roubert        value = (patternCharIndex != UDAT_RELATED_YEAR_FIELD)? cal.get(field, status): cal.getRelatedYear(status);
14071b7d32f919554dda9c193b32188251337bc756f1Fredrik Roubert    }
1408ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    if (U_FAILURE(status)) {
1409ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        return;
1410ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    }
1411ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
14121b7d32f919554dda9c193b32188251337bc756f1Fredrik Roubert    currentNumberFormat = mutableNFs.get(getNumberFormatByIndex(patternCharIndex));
14131b7d32f919554dda9c193b32188251337bc756f1Fredrik Roubert    if (currentNumberFormat == NULL) {
14141b7d32f919554dda9c193b32188251337bc756f1Fredrik Roubert        status = U_MEMORY_ALLOCATION_ERROR;
14151b7d32f919554dda9c193b32188251337bc756f1Fredrik Roubert        return;
14161b7d32f919554dda9c193b32188251337bc756f1Fredrik Roubert    }
141754dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius    UnicodeString hebr("hebr", 4, US_INV);
141854dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius
1419ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    switch (patternCharIndex) {
142050294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho
1421ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    // for any "G" symbol, write out the appropriate era string
142285bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    // "GGGG" is wide era name, "GGGGG" is narrow era name, anything else is abbreviated name
1423ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    case UDAT_ERA_FIELD:
1424103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius        if (isChineseCalendar) {
1425103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius            zeroPaddingNumber(currentNumberFormat,appendTo, value, 1, 9); // as in ICU4J
1426103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius        } else {
1427103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius            if (count == 5) {
1428103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius                _appendSymbol(appendTo, value, fSymbols->fNarrowEras, fSymbols->fNarrowErasCount);
1429103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius                capContextUsageType = DateFormatSymbols::kCapContextUsageEraNarrow;
1430103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius            } else if (count == 4) {
1431103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius                _appendSymbol(appendTo, value, fSymbols->fEraNames, fSymbols->fEraNamesCount);
1432103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius                capContextUsageType = DateFormatSymbols::kCapContextUsageEraWide;
1433103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius            } else {
1434103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius                _appendSymbol(appendTo, value, fSymbols->fEras, fSymbols->fErasCount);
1435103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius                capContextUsageType = DateFormatSymbols::kCapContextUsageEraAbbrev;
1436103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius            }
1437103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius        }
1438ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        break;
1439ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
1440103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius     case UDAT_YEAR_NAME_FIELD:
1441103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius        if (fSymbols->fShortYearNames != NULL && value <= fSymbols->fShortYearNamesCount) {
1442103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius            // the Calendar YEAR field runs 1 through 60 for cyclic years
1443103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius            _appendSymbol(appendTo, value - 1, fSymbols->fShortYearNames, fSymbols->fShortYearNamesCount);
1444103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius            break;
1445103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius        }
1446103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius        // else fall through to numeric year handling, do not break here
1447103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius
1448103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius   // OLD: for "yyyy", write out the whole year; for "yy", write out the last 2 digits
144985bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    // NEW: UTS#35:
1450b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho//Year         y     yy     yyy     yyyy     yyyyy
1451b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho//AD 1         1     01     001     0001     00001
1452b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho//AD 12       12     12     012     0012     00012
1453b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho//AD 123     123     23     123     0123     00123
1454b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho//AD 1234   1234     34    1234     1234     01234
1455b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho//AD 12345 12345     45   12345    12345     12345
1456ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    case UDAT_YEAR_FIELD:
1457ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    case UDAT_YEAR_WOY_FIELD:
145854dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius        if (fDateOverride.compare(hebr)==0 && value>HEBREW_CAL_CUR_MILLENIUM_START_YEAR && value<HEBREW_CAL_CUR_MILLENIUM_END_YEAR) {
145954dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius            value-=HEBREW_CAL_CUR_MILLENIUM_START_YEAR;
146054dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius        }
146185bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho        if(count == 2)
146250294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho            zeroPaddingNumber(currentNumberFormat, appendTo, value, 2, 2);
146350294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho        else
146450294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho            zeroPaddingNumber(currentNumberFormat, appendTo, value, count, maxIntCount);
146550294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho        break;
1466ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
1467103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius    // for "MMMM"/"LLLL", write out the whole month name, for "MMM"/"LLL", write out the month
1468103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius    // abbreviation, for "M"/"L" or "MM"/"LL", write out the month as a number with the
1469ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    // appropriate number of digits
1470103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius    // for "MMMMM"/"LLLLL", use the narrow form
1471ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    case UDAT_MONTH_FIELD:
1472103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius    case UDAT_STANDALONE_MONTH_FIELD:
147350294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho        if ( isHebrewCalendar ) {
147450294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho           HebrewCalendar *hc = (HebrewCalendar*)&cal;
147550294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho           if (hc->isLeapYear(hc->get(UCAL_YEAR,status)) && value == 6 && count >= 3 )
147650294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho               value = 13; // Show alternate form for Adar II in leap years in Hebrew calendar.
147750294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho           if (!hc->isLeapYear(hc->get(UCAL_YEAR,status)) && value >= 6 && count < 3 )
147850294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho               value--; // Adjust the month number down 1 in Hebrew non-leap years, i.e. Adar is 6, not 7.
147950294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho        }
1480103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius        {
1481103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius            int32_t isLeapMonth = (fSymbols->fLeapMonthPatterns != NULL && fSymbols->fLeapMonthPatternsCount >= DateFormatSymbols::kMonthPatternsCount)?
1482103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius                        cal.get(UCAL_IS_LEAP_MONTH, status): 0;
1483103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius            // should consolidate the next section by using arrays of pointers & counts for the right symbols...
1484103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius            if (count == 5) {
1485103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius                if (patternCharIndex == UDAT_MONTH_FIELD) {
1486103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius                    _appendSymbolWithMonthPattern(appendTo, value, fSymbols->fNarrowMonths, fSymbols->fNarrowMonthsCount,
1487103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius                            (isLeapMonth!=0)? &(fSymbols->fLeapMonthPatterns[DateFormatSymbols::kLeapMonthPatternFormatNarrow]): NULL, status);
1488103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius                } else {
1489103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius                    _appendSymbolWithMonthPattern(appendTo, value, fSymbols->fStandaloneNarrowMonths, fSymbols->fStandaloneNarrowMonthsCount,
1490103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius                            (isLeapMonth!=0)? &(fSymbols->fLeapMonthPatterns[DateFormatSymbols::kLeapMonthPatternStandaloneNarrow]): NULL, status);
1491103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius                }
1492103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius                capContextUsageType = DateFormatSymbols::kCapContextUsageMonthNarrow;
1493103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius            } else if (count == 4) {
1494103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius                if (patternCharIndex == UDAT_MONTH_FIELD) {
1495103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius                    _appendSymbolWithMonthPattern(appendTo, value, fSymbols->fMonths, fSymbols->fMonthsCount,
1496103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius                            (isLeapMonth!=0)? &(fSymbols->fLeapMonthPatterns[DateFormatSymbols::kLeapMonthPatternFormatWide]): NULL, status);
1497103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius                    capContextUsageType = DateFormatSymbols::kCapContextUsageMonthFormat;
1498103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius                } else {
1499103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius                    _appendSymbolWithMonthPattern(appendTo, value, fSymbols->fStandaloneMonths, fSymbols->fStandaloneMonthsCount,
1500103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius                            (isLeapMonth!=0)? &(fSymbols->fLeapMonthPatterns[DateFormatSymbols::kLeapMonthPatternStandaloneWide]): NULL, status);
1501103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius                    capContextUsageType = DateFormatSymbols::kCapContextUsageMonthStandalone;
1502103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius                }
1503103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius            } else if (count == 3) {
1504103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius                if (patternCharIndex == UDAT_MONTH_FIELD) {
1505103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius                    _appendSymbolWithMonthPattern(appendTo, value, fSymbols->fShortMonths, fSymbols->fShortMonthsCount,
1506103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius                            (isLeapMonth!=0)? &(fSymbols->fLeapMonthPatterns[DateFormatSymbols::kLeapMonthPatternFormatAbbrev]): NULL, status);
1507103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius                    capContextUsageType = DateFormatSymbols::kCapContextUsageMonthFormat;
1508103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius                } else {
1509103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius                    _appendSymbolWithMonthPattern(appendTo, value, fSymbols->fStandaloneShortMonths, fSymbols->fStandaloneShortMonthsCount,
1510103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius                            (isLeapMonth!=0)? &(fSymbols->fLeapMonthPatterns[DateFormatSymbols::kLeapMonthPatternStandaloneAbbrev]): NULL, status);
1511103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius                    capContextUsageType = DateFormatSymbols::kCapContextUsageMonthStandalone;
1512103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius                }
1513103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius            } else {
1514103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius                UnicodeString monthNumber;
1515103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius                zeroPaddingNumber(currentNumberFormat,monthNumber, value + 1, count, maxIntCount);
1516103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius                _appendSymbolWithMonthPattern(appendTo, 0, &monthNumber, 1,
1517103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius                        (isLeapMonth!=0)? &(fSymbols->fLeapMonthPatterns[DateFormatSymbols::kLeapMonthPatternNumeric]): NULL, status);
1518103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius            }
1519103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius        }
1520ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        break;
1521ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
1522ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    // for "k" and "kk", write out the hour, adjusting midnight to appear as "24"
1523ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    case UDAT_HOUR_OF_DAY1_FIELD:
152450294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho        if (value == 0)
152585bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho            zeroPaddingNumber(currentNumberFormat,appendTo, cal.getMaximum(UCAL_HOUR_OF_DAY) + 1, count, maxIntCount);
152650294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho        else
152785bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho            zeroPaddingNumber(currentNumberFormat,appendTo, value, count, maxIntCount);
1528ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        break;
1529ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
1530ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    case UDAT_FRACTIONAL_SECOND_FIELD:
1531ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        // Fractional seconds left-justify
1532ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        {
153385bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho            currentNumberFormat->setMinimumIntegerDigits((count > 3) ? 3 : count);
153485bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho            currentNumberFormat->setMaximumIntegerDigits(maxIntCount);
1535ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            if (count == 1) {
153627f654740f2a26ad62a5c155af9199af9e69b889claireho                value /= 100;
1537ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            } else if (count == 2) {
153827f654740f2a26ad62a5c155af9199af9e69b889claireho                value /= 10;
1539ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            }
1540ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            FieldPosition p(0);
154185bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho            currentNumberFormat->format(value, appendTo, p);
1542ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            if (count > 3) {
154385bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho                currentNumberFormat->setMinimumIntegerDigits(count - 3);
154485bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho                currentNumberFormat->format((int32_t)0, appendTo, p);
1545ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            }
1546ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        }
1547ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        break;
1548ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
154985bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    // for "ee" or "e", use local numeric day-of-the-week
15508393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius    // for "EEEEEE" or "eeeeee", write out the short day-of-the-week name
155185bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    // for "EEEEE" or "eeeee", write out the narrow day-of-the-week name
155285bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    // for "EEEE" or "eeee", write out the wide day-of-the-week name
155385bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    // for "EEE" or "EE" or "E" or "eee", write out the abbreviated day-of-the-week name
155485bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    case UDAT_DOW_LOCAL_FIELD:
155585bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho        if ( count < 3 ) {
155685bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho            zeroPaddingNumber(currentNumberFormat,appendTo, value, count, maxIntCount);
155785bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho            break;
155885bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho        }
155985bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho        // fall through to EEEEE-EEE handling, but for that we don't want local day-of-week,
156085bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho        // we want standard day-of-week, so first fix value to work for EEEEE-EEE.
156185bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho        value = cal.get(UCAL_DAY_OF_WEEK, status);
156285bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho        if (U_FAILURE(status)) {
156385bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho            return;
156485bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho        }
156585bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho        // fall through, do not break here
1566ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    case UDAT_DAY_OF_WEEK_FIELD:
1567103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius        if (count == 5) {
1568ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            _appendSymbol(appendTo, value, fSymbols->fNarrowWeekdays,
1569ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                          fSymbols->fNarrowWeekdaysCount);
1570103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius            capContextUsageType = DateFormatSymbols::kCapContextUsageDayNarrow;
1571103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius        } else if (count == 4) {
1572ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            _appendSymbol(appendTo, value, fSymbols->fWeekdays,
1573ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                          fSymbols->fWeekdaysCount);
1574103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius            capContextUsageType = DateFormatSymbols::kCapContextUsageDayFormat;
15758393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius        } else if (count == 6) {
15768393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius            _appendSymbol(appendTo, value, fSymbols->fShorterWeekdays,
15778393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius                          fSymbols->fShorterWeekdaysCount);
15788393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius            capContextUsageType = DateFormatSymbols::kCapContextUsageDayFormat;
1579103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius        } else {
1580ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            _appendSymbol(appendTo, value, fSymbols->fShortWeekdays,
1581ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                          fSymbols->fShortWeekdaysCount);
1582103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius            capContextUsageType = DateFormatSymbols::kCapContextUsageDayFormat;
1583103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius        }
1584ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        break;
1585ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
1586ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    // for "ccc", write out the abbreviated day-of-the-week name
1587ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    // for "cccc", write out the wide day-of-the-week name
1588ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    // for "ccccc", use the narrow day-of-the-week name
15898393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius    // for "ccccc", use the short day-of-the-week name
1590ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    case UDAT_STANDALONE_DAY_FIELD:
159185bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho        if ( count < 3 ) {
159285bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho            zeroPaddingNumber(currentNumberFormat,appendTo, value, 1, maxIntCount);
159385bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho            break;
159485bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho        }
159585bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho        // fall through to alpha DOW handling, but for that we don't want local day-of-week,
159685bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho        // we want standard day-of-week, so first fix value.
159785bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho        value = cal.get(UCAL_DAY_OF_WEEK, status);
159885bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho        if (U_FAILURE(status)) {
159985bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho            return;
160085bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho        }
1601103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius        if (count == 5) {
1602ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            _appendSymbol(appendTo, value, fSymbols->fStandaloneNarrowWeekdays,
1603ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                          fSymbols->fStandaloneNarrowWeekdaysCount);
1604103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius            capContextUsageType = DateFormatSymbols::kCapContextUsageDayNarrow;
1605103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius        } else if (count == 4) {
1606ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            _appendSymbol(appendTo, value, fSymbols->fStandaloneWeekdays,
1607ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                          fSymbols->fStandaloneWeekdaysCount);
1608103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius            capContextUsageType = DateFormatSymbols::kCapContextUsageDayStandalone;
16098393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius        } else if (count == 6) {
16108393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius            _appendSymbol(appendTo, value, fSymbols->fStandaloneShorterWeekdays,
16118393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius                          fSymbols->fStandaloneShorterWeekdaysCount);
16128393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius            capContextUsageType = DateFormatSymbols::kCapContextUsageDayStandalone;
1613103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius        } else { // count == 3
1614ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            _appendSymbol(appendTo, value, fSymbols->fStandaloneShortWeekdays,
1615ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                          fSymbols->fStandaloneShortWeekdaysCount);
1616103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius            capContextUsageType = DateFormatSymbols::kCapContextUsageDayStandalone;
1617103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius        }
1618ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        break;
1619ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
16201b7d32f919554dda9c193b32188251337bc756f1Fredrik Roubert    // for "a" symbol, write out the whole AM/PM string
1621ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    case UDAT_AM_PM_FIELD:
16221b7d32f919554dda9c193b32188251337bc756f1Fredrik Roubert        if (count < 5) {
16231b7d32f919554dda9c193b32188251337bc756f1Fredrik Roubert            _appendSymbol(appendTo, value, fSymbols->fAmPms,
16241b7d32f919554dda9c193b32188251337bc756f1Fredrik Roubert                          fSymbols->fAmPmsCount);
16251b7d32f919554dda9c193b32188251337bc756f1Fredrik Roubert        } else {
16261b7d32f919554dda9c193b32188251337bc756f1Fredrik Roubert            _appendSymbol(appendTo, value, fSymbols->fNarrowAmPms,
16271b7d32f919554dda9c193b32188251337bc756f1Fredrik Roubert                          fSymbols->fNarrowAmPmsCount);
16281b7d32f919554dda9c193b32188251337bc756f1Fredrik Roubert        }
16291b7d32f919554dda9c193b32188251337bc756f1Fredrik Roubert        break;
16301b7d32f919554dda9c193b32188251337bc756f1Fredrik Roubert
16311b7d32f919554dda9c193b32188251337bc756f1Fredrik Roubert    // for ":", write out the time separator string
16321b7d32f919554dda9c193b32188251337bc756f1Fredrik Roubert    case UDAT_TIME_SEPARATOR_FIELD:
16331b7d32f919554dda9c193b32188251337bc756f1Fredrik Roubert        {
16341b7d32f919554dda9c193b32188251337bc756f1Fredrik Roubert            UnicodeString separator;
16351b7d32f919554dda9c193b32188251337bc756f1Fredrik Roubert            appendTo += fSymbols->getTimeSeparatorString(separator);
16361b7d32f919554dda9c193b32188251337bc756f1Fredrik Roubert        }
1637ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        break;
1638ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
1639ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    // for "h" and "hh", write out the hour, adjusting noon and midnight to show up
1640ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    // as "12"
1641ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    case UDAT_HOUR1_FIELD:
164250294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho        if (value == 0)
164385bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho            zeroPaddingNumber(currentNumberFormat,appendTo, cal.getLeastMaximum(UCAL_HOUR) + 1, count, maxIntCount);
164450294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho        else
164585bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho            zeroPaddingNumber(currentNumberFormat,appendTo, value, count, maxIntCount);
1646ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        break;
1647ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
16488393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius    case UDAT_TIMEZONE_FIELD: // 'z'
16498393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius    case UDAT_TIMEZONE_RFC_FIELD: // 'Z'
16508393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius    case UDAT_TIMEZONE_GENERIC_FIELD: // 'v'
16518393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius    case UDAT_TIMEZONE_SPECIAL_FIELD: // 'V'
16528393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius    case UDAT_TIMEZONE_LOCALIZED_GMT_OFFSET_FIELD: // 'O'
16538393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius    case UDAT_TIMEZONE_ISO_FIELD: // 'X'
16548393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius    case UDAT_TIMEZONE_ISO_LOCAL_FIELD: // 'x'
1655b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        {
16561b7d32f919554dda9c193b32188251337bc756f1Fredrik Roubert            UChar zsbuf[64];
16571b7d32f919554dda9c193b32188251337bc756f1Fredrik Roubert            UnicodeString zoneString(zsbuf, 0, UPRV_LENGTHOF(zsbuf));
1658b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho            const TimeZone& tz = cal.getTimeZone();
1659b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho            UDate date = cal.getTime(status);
1660b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho            if (U_SUCCESS(status)) {
16618393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius                if (patternCharIndex == UDAT_TIMEZONE_FIELD) {
1662b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                    if (count < 4) {
1663b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                        // "z", "zz", "zzz"
1664103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius                        tzFormat()->format(UTZFMT_STYLE_SPECIFIC_SHORT, tz, date, zoneString);
1665103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius                        capContextUsageType = DateFormatSymbols::kCapContextUsageMetazoneShort;
1666b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                    } else {
16678393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius                        // "zzzz" or longer
1668b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho                        tzFormat()->format(UTZFMT_STYLE_SPECIFIC_LONG, tz, date, zoneString);
1669103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius                        capContextUsageType = DateFormatSymbols::kCapContextUsageMetazoneLong;
1670ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                    }
16718393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius                }
16728393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius                else if (patternCharIndex == UDAT_TIMEZONE_RFC_FIELD) {
16738393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius                    if (count < 4) {
16748393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius                        // "Z"
16758393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius                        tzFormat()->format(UTZFMT_STYLE_ISO_BASIC_LOCAL_FULL, tz, date, zoneString);
16768393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius                    } else if (count == 5) {
16778393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius                        // "ZZZZZ"
16788393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius                        tzFormat()->format(UTZFMT_STYLE_ISO_EXTENDED_FULL, tz, date, zoneString);
16798393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius                    } else {
16808393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius                        // "ZZ", "ZZZ", "ZZZZ"
16818393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius                        tzFormat()->format(UTZFMT_STYLE_LOCALIZED_GMT, tz, date, zoneString);
16828393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius                    }
16838393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius                }
16848393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius                else if (patternCharIndex == UDAT_TIMEZONE_GENERIC_FIELD) {
1685b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                    if (count == 1) {
1686b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                        // "v"
1687b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho                        tzFormat()->format(UTZFMT_STYLE_GENERIC_SHORT, tz, date, zoneString);
1688103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius                        capContextUsageType = DateFormatSymbols::kCapContextUsageMetazoneShort;
1689b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                    } else if (count == 4) {
1690b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                        // "vvvv"
1691b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho                        tzFormat()->format(UTZFMT_STYLE_GENERIC_LONG, tz, date, zoneString);
1692103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius                        capContextUsageType = DateFormatSymbols::kCapContextUsageMetazoneLong;
1693ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                    }
16948393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius                }
16958393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius                else if (patternCharIndex == UDAT_TIMEZONE_SPECIAL_FIELD) {
1696b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                    if (count == 1) {
1697b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                        // "V"
16988393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius                        tzFormat()->format(UTZFMT_STYLE_ZONE_ID_SHORT, tz, date, zoneString);
16998393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius                    } else if (count == 2) {
17008393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius                        // "VV"
17018393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius                        tzFormat()->format(UTZFMT_STYLE_ZONE_ID, tz, date, zoneString);
17028393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius                    } else if (count == 3) {
17038393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius                        // "VVV"
17048393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius                        tzFormat()->format(UTZFMT_STYLE_EXEMPLAR_LOCATION, tz, date, zoneString);
1705b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                    } else if (count == 4) {
1706b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                        // "VVVV"
1707103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius                        tzFormat()->format(UTZFMT_STYLE_GENERIC_LOCATION, tz, date, zoneString);
1708103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius                        capContextUsageType = DateFormatSymbols::kCapContextUsageZoneLong;
1709ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                    }
1710ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                }
17118393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius                else if (patternCharIndex == UDAT_TIMEZONE_LOCALIZED_GMT_OFFSET_FIELD) {
17128393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius                    if (count == 1) {
17138393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius                        // "O"
17148393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius                        tzFormat()->format(UTZFMT_STYLE_LOCALIZED_GMT_SHORT, tz, date, zoneString);
17158393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius                    } else if (count == 4) {
17168393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius                        // "OOOO"
17178393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius                        tzFormat()->format(UTZFMT_STYLE_LOCALIZED_GMT, tz, date, zoneString);
17188393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius                    }
17198393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius                }
17208393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius                else if (patternCharIndex == UDAT_TIMEZONE_ISO_FIELD) {
17218393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius                    if (count == 1) {
17228393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius                        // "X"
17238393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius                        tzFormat()->format(UTZFMT_STYLE_ISO_BASIC_SHORT, tz, date, zoneString);
17248393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius                    } else if (count == 2) {
17258393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius                        // "XX"
17268393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius                        tzFormat()->format(UTZFMT_STYLE_ISO_BASIC_FIXED, tz, date, zoneString);
17278393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius                    } else if (count == 3) {
17288393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius                        // "XXX"
17298393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius                        tzFormat()->format(UTZFMT_STYLE_ISO_EXTENDED_FIXED, tz, date, zoneString);
17308393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius                    } else if (count == 4) {
17318393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius                        // "XXXX"
17328393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius                        tzFormat()->format(UTZFMT_STYLE_ISO_BASIC_FULL, tz, date, zoneString);
17338393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius                    } else if (count == 5) {
17348393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius                        // "XXXXX"
17358393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius                        tzFormat()->format(UTZFMT_STYLE_ISO_EXTENDED_FULL, tz, date, zoneString);
17368393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius                    }
17378393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius                }
17388393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius                else if (patternCharIndex == UDAT_TIMEZONE_ISO_LOCAL_FIELD) {
17398393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius                    if (count == 1) {
17408393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius                        // "x"
17418393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius                        tzFormat()->format(UTZFMT_STYLE_ISO_BASIC_LOCAL_SHORT, tz, date, zoneString);
17428393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius                    } else if (count == 2) {
17438393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius                        // "xx"
17448393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius                        tzFormat()->format(UTZFMT_STYLE_ISO_BASIC_LOCAL_FIXED, tz, date, zoneString);
17458393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius                    } else if (count == 3) {
17468393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius                        // "xxx"
17478393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius                        tzFormat()->format(UTZFMT_STYLE_ISO_EXTENDED_LOCAL_FIXED, tz, date, zoneString);
17488393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius                    } else if (count == 4) {
17498393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius                        // "xxxx"
17508393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius                        tzFormat()->format(UTZFMT_STYLE_ISO_BASIC_LOCAL_FULL, tz, date, zoneString);
17518393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius                    } else if (count == 5) {
17528393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius                        // "xxxxx"
17538393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius                        tzFormat()->format(UTZFMT_STYLE_ISO_EXTENDED_LOCAL_FULL, tz, date, zoneString);
17548393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius                    }
17558393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius                }
17568393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius                else {
17578393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius                    U_ASSERT(FALSE);
17588393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius                }
1759ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            }
1760103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius            appendTo += zoneString;
1761ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        }
1762ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        break;
1763ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
1764ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    case UDAT_QUARTER_FIELD:
176550294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho        if (count >= 4)
1766ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            _appendSymbol(appendTo, value/3, fSymbols->fQuarters,
1767ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                          fSymbols->fQuartersCount);
176850294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho        else if (count == 3)
1769ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            _appendSymbol(appendTo, value/3, fSymbols->fShortQuarters,
1770ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                          fSymbols->fShortQuartersCount);
177150294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho        else
177285bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho            zeroPaddingNumber(currentNumberFormat,appendTo, (value/3) + 1, count, maxIntCount);
1773ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        break;
1774ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
1775ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    case UDAT_STANDALONE_QUARTER_FIELD:
177650294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho        if (count >= 4)
1777ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            _appendSymbol(appendTo, value/3, fSymbols->fStandaloneQuarters,
1778ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                          fSymbols->fStandaloneQuartersCount);
177950294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho        else if (count == 3)
1780ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            _appendSymbol(appendTo, value/3, fSymbols->fStandaloneShortQuarters,
1781ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                          fSymbols->fStandaloneShortQuartersCount);
178250294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho        else
178385bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho            zeroPaddingNumber(currentNumberFormat,appendTo, (value/3) + 1, count, maxIntCount);
1784ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        break;
1785ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
1786ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
1787ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    // all of the other pattern symbols can be formatted as simple numbers with
1788ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    // appropriate zero padding
1789ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    default:
179085bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho        zeroPaddingNumber(currentNumberFormat,appendTo, value, count, maxIntCount);
1791ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        break;
1792ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    }
1793103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius#if !UCONFIG_NO_BREAK_ITERATION
1794fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius    // if first field, check to see whether we need to and are able to titlecase it
1795fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius    if (fieldNum == 0 && u_islower(appendTo.char32At(beginOffset)) && fCapitalizationBrkIter != NULL) {
1796103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius        UBool titlecase = FALSE;
1797103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius        switch (capitalizationContext) {
179854dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius            case UDISPCTX_CAPITALIZATION_FOR_BEGINNING_OF_SENTENCE:
1799103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius                titlecase = TRUE;
1800103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius                break;
180154dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius            case UDISPCTX_CAPITALIZATION_FOR_UI_LIST_OR_MENU:
180254dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius                titlecase = fSymbols->fCapitalization[capContextUsageType][0];
180354dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius                break;
180454dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius            case UDISPCTX_CAPITALIZATION_FOR_STANDALONE:
180554dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius                titlecase = fSymbols->fCapitalization[capContextUsageType][1];
180654dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius                break;
1807103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius            default:
1808103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius                // titlecase = FALSE;
1809103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius                break;
1810103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius        }
1811103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius        if (titlecase) {
1812103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius            UnicodeString firstField(appendTo, beginOffset);
1813fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius            firstField.toTitle(fCapitalizationBrkIter, fLocale, U_TITLECASE_NO_LOWERCASE | U_TITLECASE_NO_BREAK_ADJUSTMENT);
1814103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius            appendTo.replaceBetween(beginOffset, appendTo.length(), firstField);
1815103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius        }
1816103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius    }
1817103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius#endif
1818ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
181950294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    handler.addAttribute(fgPatternIndexToDateFormatField[patternCharIndex], beginOffset, appendTo.length());
1820ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru}
182150294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho
182285bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho//----------------------------------------------------------------------
182385bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho
1824f9878a236aa0d9662d8e40cafdaf2e04cd615835ccorneliusvoid SimpleDateFormat::adoptNumberFormat(NumberFormat *formatToAdopt) {
18251b7d32f919554dda9c193b32188251337bc756f1Fredrik Roubert    fixNumberFormatForDates(*formatToAdopt);
18261b7d32f919554dda9c193b32188251337bc756f1Fredrik Roubert    delete fNumberFormat;
1827f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius    fNumberFormat = formatToAdopt;
1828f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius
18291b7d32f919554dda9c193b32188251337bc756f1Fredrik Roubert    // We successfully set the default number format. Now delete the overrides
18301b7d32f919554dda9c193b32188251337bc756f1Fredrik Roubert    // (can't fail).
18311b7d32f919554dda9c193b32188251337bc756f1Fredrik Roubert    if (fSharedNumberFormatters) {
18321b7d32f919554dda9c193b32188251337bc756f1Fredrik Roubert        freeSharedNumberFormatters(fSharedNumberFormatters);
18331b7d32f919554dda9c193b32188251337bc756f1Fredrik Roubert        fSharedNumberFormatters = NULL;
1834f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius    }
1835f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius}
1836f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius
1837f9878a236aa0d9662d8e40cafdaf2e04cd615835ccorneliusvoid SimpleDateFormat::adoptNumberFormat(const UnicodeString& fields, NumberFormat *formatToAdopt, UErrorCode &status){
18381b7d32f919554dda9c193b32188251337bc756f1Fredrik Roubert    fixNumberFormatForDates(*formatToAdopt);
18391b7d32f919554dda9c193b32188251337bc756f1Fredrik Roubert    LocalPointer<NumberFormat> fmt(formatToAdopt);
18401b7d32f919554dda9c193b32188251337bc756f1Fredrik Roubert    if (U_FAILURE(status)) {
18411b7d32f919554dda9c193b32188251337bc756f1Fredrik Roubert        return;
1842f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius    }
18431b7d32f919554dda9c193b32188251337bc756f1Fredrik Roubert
18441b7d32f919554dda9c193b32188251337bc756f1Fredrik Roubert    // We must ensure fSharedNumberFormatters is allocated.
18451b7d32f919554dda9c193b32188251337bc756f1Fredrik Roubert    if (fSharedNumberFormatters == NULL) {
18461b7d32f919554dda9c193b32188251337bc756f1Fredrik Roubert        fSharedNumberFormatters = allocSharedNumberFormatters();
18471b7d32f919554dda9c193b32188251337bc756f1Fredrik Roubert        if (fSharedNumberFormatters == NULL) {
1848f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius            status = U_MEMORY_ALLOCATION_ERROR;
1849f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius            return;
1850f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius        }
1851f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius    }
18521b7d32f919554dda9c193b32188251337bc756f1Fredrik Roubert    const SharedNumberFormat *newFormat = createSharedNumberFormat(fmt.orphan());
18531b7d32f919554dda9c193b32188251337bc756f1Fredrik Roubert    if (newFormat == NULL) {
18541b7d32f919554dda9c193b32188251337bc756f1Fredrik Roubert        status = U_MEMORY_ALLOCATION_ERROR;
18551b7d32f919554dda9c193b32188251337bc756f1Fredrik Roubert        return;
18561b7d32f919554dda9c193b32188251337bc756f1Fredrik Roubert    }
1857f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius    for (int i=0; i<fields.length(); i++) {
1858f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius        UChar field = fields.charAt(i);
1859f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius        // if the pattern character is unrecognized, signal an error and bail out
1860f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius        UDateFormatField patternCharIndex = DateFormatSymbols::getPatternCharIndex(field);
1861f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius        if (patternCharIndex == UDAT_FIELD_COUNT) {
1862f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius            status = U_INVALID_FORMAT_ERROR;
18631b7d32f919554dda9c193b32188251337bc756f1Fredrik Roubert            newFormat->deleteIfZeroRefCount();
1864f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius            return;
1865f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius        }
1866f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius
1867f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius        // Set the number formatter in the table
18681b7d32f919554dda9c193b32188251337bc756f1Fredrik Roubert        SharedObject::copyPtr(
18691b7d32f919554dda9c193b32188251337bc756f1Fredrik Roubert                newFormat, fSharedNumberFormatters[patternCharIndex]);
1870f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius    }
18711b7d32f919554dda9c193b32188251337bc756f1Fredrik Roubert    newFormat->deleteIfZeroRefCount();
1872f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius}
1873f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius
1874f9878a236aa0d9662d8e40cafdaf2e04cd615835ccorneliusconst NumberFormat *
1875f9878a236aa0d9662d8e40cafdaf2e04cd615835ccorneliusSimpleDateFormat::getNumberFormatForField(UChar field) const {
1876f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius    UDateFormatField index = DateFormatSymbols::getPatternCharIndex(field);
18771b7d32f919554dda9c193b32188251337bc756f1Fredrik Roubert    if (index == UDAT_FIELD_COUNT) {
18781b7d32f919554dda9c193b32188251337bc756f1Fredrik Roubert        return NULL;
187985bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    }
18801b7d32f919554dda9c193b32188251337bc756f1Fredrik Roubert    return getNumberFormatByIndex(index);
188185bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho}
1882ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
1883ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru//----------------------------------------------------------------------
1884ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queruvoid
18851b7d32f919554dda9c193b32188251337bc756f1Fredrik RoubertSimpleDateFormat::zeroPaddingNumber(
18861b7d32f919554dda9c193b32188251337bc756f1Fredrik Roubert        NumberFormat *currentNumberFormat,
18871b7d32f919554dda9c193b32188251337bc756f1Fredrik Roubert        UnicodeString &appendTo,
18881b7d32f919554dda9c193b32188251337bc756f1Fredrik Roubert        int32_t value, int32_t minDigits, int32_t maxDigits) const
1889ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru{
189085bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    if (currentNumberFormat!=NULL) {
189185bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho        FieldPosition pos(0);
1892ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
189385bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho        currentNumberFormat->setMinimumIntegerDigits(minDigits);
189485bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho        currentNumberFormat->setMaximumIntegerDigits(maxDigits);
189585bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho        currentNumberFormat->format(value, appendTo, pos);  // 3rd arg is there to speed up processing
189685bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    }
1897ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru}
1898ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
1899ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru//----------------------------------------------------------------------
1900ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
1901ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru/**
1902ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru * Return true if the given format character, occuring count
1903ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru * times, represents a numeric field.
1904ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru */
1905ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste QueruUBool SimpleDateFormat::isNumeric(UChar formatChar, int32_t count) {
190654dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius    return DateFormatSymbols::isNumericPatternChar(formatChar, count);
190754dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius}
190854dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius
190954dcd9b6a06071f647dac967e9e267abb9410720Craig CorneliusUBool
191054dcd9b6a06071f647dac967e9e267abb9410720Craig CorneliusSimpleDateFormat::isAtNumericField(const UnicodeString &pattern, int32_t patternOffset) {
191154dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius    if (patternOffset >= pattern.length()) {
191254dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius        // not at any field
191354dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius        return FALSE;
191454dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius    }
191554dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius    UChar ch = pattern.charAt(patternOffset);
191654dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius    UDateFormatField f = DateFormatSymbols::getPatternCharIndex(ch);
191754dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius    if (f == UDAT_FIELD_COUNT) {
191854dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius        // not at any field
191954dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius        return FALSE;
192054dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius    }
192154dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius    int32_t i = patternOffset;
192254dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius    while (pattern.charAt(++i) == ch) {}
192354dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius    return DateFormatSymbols::isNumericField(f, i - patternOffset);
192454dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius}
192554dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius
192654dcd9b6a06071f647dac967e9e267abb9410720Craig CorneliusUBool
192754dcd9b6a06071f647dac967e9e267abb9410720Craig CorneliusSimpleDateFormat::isAfterNonNumericField(const UnicodeString &pattern, int32_t patternOffset) {
192854dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius    if (patternOffset <= 0) {
192954dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius        // not after any field
193054dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius        return FALSE;
193154dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius    }
193254dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius    UChar ch = pattern.charAt(--patternOffset);
193354dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius    UDateFormatField f = DateFormatSymbols::getPatternCharIndex(ch);
193454dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius    if (f == UDAT_FIELD_COUNT) {
193554dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius        // not after any field
193654dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius        return FALSE;
193754dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius    }
193854dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius    int32_t i = patternOffset;
193954dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius    while (pattern.charAt(--i) == ch) {}
194054dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius    return !DateFormatSymbols::isNumericField(f, patternOffset - i);
1941ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru}
1942ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
1943ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queruvoid
1944ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste QueruSimpleDateFormat::parse(const UnicodeString& text, Calendar& cal, ParsePosition& parsePos) const
1945ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru{
194685bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    UErrorCode status = U_ZERO_ERROR;
1947ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    int32_t pos = parsePos.getIndex();
1948f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius    if(parsePos.getIndex() < 0) {
1949f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius        parsePos.setErrorIndex(0);
1950f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius        return;
1951f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius    }
1952ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    int32_t start = pos;
195385bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho
1954f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius
1955ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    UBool ambiguousYear[] = { FALSE };
195650294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    int32_t saveHebrewMonth = -1;
1957ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    int32_t count = 0;
1958fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius    UTimeZoneFormatTimeType tzTimeType = UTZFMT_TIME_TYPE_UNKNOWN;
19591b7d32f919554dda9c193b32188251337bc756f1Fredrik Roubert    SimpleDateFormatMutableNFs mutableNFs;
1960ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
1961ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    // For parsing abutting numeric fields. 'abutPat' is the
1962ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    // offset into 'pattern' of the first of 2 or more abutting
1963ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    // numeric fields.  'abutStart' is the offset into 'text'
1964ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    // where parsing the fields begins. 'abutPass' starts off as 0
1965ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    // and increments each time we try to parse the fields.
1966ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    int32_t abutPat = -1; // If >=0, we are in a run of abutting numeric fields
1967ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    int32_t abutStart = 0;
1968ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    int32_t abutPass = 0;
1969ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    UBool inQuote = FALSE;
1970ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
1971103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius    MessageFormat * numericLeapMonthFormatter = NULL;
1972ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
1973103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius    Calendar* calClone = NULL;
197485bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    Calendar *workCal = &cal;
197585bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    if (&cal != fCalendar && uprv_strcmp(cal.getType(), fCalendar->getType()) != 0) {
197685bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho        // Different calendar type
197785bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho        // We use the time/zone from the input calendar, but
197885bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho        // do not use the input calendar for field calculation.
1979103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius        calClone = fCalendar->clone();
1980103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius        if (calClone != NULL) {
1981103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius            calClone->setTime(cal.getTime(status),status);
1982103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius            if (U_FAILURE(status)) {
1983103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius                goto ExitParse;
1984103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius            }
1985103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius            calClone->setTimeZone(cal.getTimeZone());
1986103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius            workCal = calClone;
1987103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius        } else {
1988103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius            status = U_MEMORY_ALLOCATION_ERROR;
198985bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho            goto ExitParse;
199085bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho        }
1991103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius    }
1992103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius
1993103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius    if (fSymbols->fLeapMonthPatterns != NULL && fSymbols->fLeapMonthPatternsCount >= DateFormatSymbols::kMonthPatternsCount) {
1994103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius        numericLeapMonthFormatter = new MessageFormat(fSymbols->fLeapMonthPatterns[DateFormatSymbols::kLeapMonthPatternNumeric], fLocale, status);
1995103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius        if (numericLeapMonthFormatter == NULL) {
1996103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius             status = U_MEMORY_ALLOCATION_ERROR;
1997103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius             goto ExitParse;
1998103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius        } else if (U_FAILURE(status)) {
1999103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius             goto ExitParse; // this will delete numericLeapMonthFormatter
2000103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius        }
200185bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    }
200285bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho
2003ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    for (int32_t i=0; i<fPattern.length(); ++i) {
2004ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        UChar ch = fPattern.charAt(i);
2005ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
2006ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        // Handle alphabetic field characters.
20071b7d32f919554dda9c193b32188251337bc756f1Fredrik Roubert        if (!inQuote && isSyntaxChar(ch)) {
2008ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            int32_t fieldPat = i;
2009ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
2010ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            // Count the length of this field specifier
2011ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            count = 1;
2012ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            while ((i+1)<fPattern.length() &&
2013ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                   fPattern.charAt(i+1) == ch) {
2014ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                ++count;
2015ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                ++i;
2016ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            }
2017ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
2018ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            if (isNumeric(ch, count)) {
2019ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                if (abutPat < 0) {
202054dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius                    // Determine if there is an abutting numeric field.
202154dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius                    // Record the start of a set of abutting numeric fields.
202254dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius                    if (isAtNumericField(fPattern, i + 1)) {
202354dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius                        abutPat = fieldPat;
202454dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius                        abutStart = pos;
202554dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius                        abutPass = 0;
2026ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                    }
2027ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                }
2028ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            } else {
2029ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                abutPat = -1; // End of any abutting fields
2030ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            }
2031ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
2032ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            // Handle fields within a run of abutting numeric fields.  Take
2033ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            // the pattern "HHmmss" as an example. We will try to parse
2034ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            // 2/2/2 characters of the input text, then if that fails,
2035ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            // 1/2/2.  We only adjust the width of the leftmost field; the
2036ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            // others remain fixed.  This allows "123456" => 12:34:56, but
2037ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            // "12345" => 1:23:45.  Likewise, for the pattern "yyyyMMdd" we
2038ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            // try 4/2/2, 3/2/2, 2/2/2, and finally 1/2/2.
2039ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            if (abutPat >= 0) {
2040ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                // If we are at the start of a run of abutting fields, then
2041ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                // shorten this field in each pass.  If we can't shorten
2042ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                // this field any more, then the parse of this set of
2043ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                // abutting numeric fields has failed.
2044ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                if (fieldPat == abutPat) {
2045ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                    count -= abutPass++;
2046ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                    if (count == 0) {
204785bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho                        status = U_PARSE_ERROR;
204885bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho                        goto ExitParse;
2049ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                    }
2050ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                }
2051ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
2052ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                pos = subParse(text, pos, ch, count,
20531b7d32f919554dda9c193b32188251337bc756f1Fredrik Roubert                               TRUE, FALSE, ambiguousYear, saveHebrewMonth, *workCal, i, numericLeapMonthFormatter, &tzTimeType, mutableNFs);
2054ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
2055ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                // If the parse fails anywhere in the run, back up to the
2056ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                // start of the run and retry.
2057ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                if (pos < 0) {
2058ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                    i = abutPat - 1;
2059ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                    pos = abutStart;
2060ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                    continue;
2061ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                }
2062ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            }
2063ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
2064ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            // Handle non-numeric fields and non-abutting numeric
2065ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            // fields.
2066103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius            else if (ch != 0x6C) { // pattern char 'l' (SMALL LETTER L) just gets ignored
206785bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho                int32_t s = subParse(text, pos, ch, count,
20681b7d32f919554dda9c193b32188251337bc756f1Fredrik Roubert                               FALSE, TRUE, ambiguousYear, saveHebrewMonth, *workCal, i, numericLeapMonthFormatter, &tzTimeType, mutableNFs);
2069ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
207027f654740f2a26ad62a5c155af9199af9e69b889claireho                if (s == -pos-1) {
207127f654740f2a26ad62a5c155af9199af9e69b889claireho                    // era not present, in special cases allow this to continue
207254dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius                    // from the position where the era was expected
207354dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius                    s = pos;
207427f654740f2a26ad62a5c155af9199af9e69b889claireho
207527f654740f2a26ad62a5c155af9199af9e69b889claireho                    if (i+1 < fPattern.length()) {
207627f654740f2a26ad62a5c155af9199af9e69b889claireho                        // move to next pattern character
207727f654740f2a26ad62a5c155af9199af9e69b889claireho                        UChar ch = fPattern.charAt(i+1);
207827f654740f2a26ad62a5c155af9199af9e69b889claireho
207927f654740f2a26ad62a5c155af9199af9e69b889claireho                        // check for whitespace
2080b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho                        if (PatternProps::isWhiteSpace(ch)) {
208127f654740f2a26ad62a5c155af9199af9e69b889claireho                            i++;
208227f654740f2a26ad62a5c155af9199af9e69b889claireho                            // Advance over run in pattern
208327f654740f2a26ad62a5c155af9199af9e69b889claireho                            while ((i+1)<fPattern.length() &&
2084b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho                                   PatternProps::isWhiteSpace(fPattern.charAt(i+1))) {
208527f654740f2a26ad62a5c155af9199af9e69b889claireho                                ++i;
208627f654740f2a26ad62a5c155af9199af9e69b889claireho                            }
208727f654740f2a26ad62a5c155af9199af9e69b889claireho                        }
208827f654740f2a26ad62a5c155af9199af9e69b889claireho                    }
208927f654740f2a26ad62a5c155af9199af9e69b889claireho                }
2090b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho                else if (s <= 0) {
209185bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho                    status = U_PARSE_ERROR;
209285bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho                    goto ExitParse;
2093ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                }
209485bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho                pos = s;
2095ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            }
2096ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        }
2097ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
2098ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        // Handle literal pattern characters.  These are any
2099ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        // quoted characters and non-alphabetic unquoted
2100ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        // characters.
2101ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        else {
210250294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho
2103ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            abutPat = -1; // End of any abutting fields
2104b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho
2105f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius            if (! matchLiterals(fPattern, i, text, pos, getBooleanAttribute(UDAT_PARSE_ALLOW_WHITESPACE, status), getBooleanAttribute(UDAT_PARSE_PARTIAL_MATCH, status), isLenient())) {
2106b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho                status = U_PARSE_ERROR;
2107b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho                goto ExitParse;
2108ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            }
2109ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        }
2110ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    }
2111ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
211254dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius    // Special hack for trailing "." after non-numeric field.
211359d709d503bab6e2b61931737e662dd293b40578ccornelius    if (text.charAt(pos) == 0x2e && getBooleanAttribute(UDAT_PARSE_ALLOW_WHITESPACE, status)) {
211454dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius        // only do if the last field is not numeric
211554dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius        if (isAfterNonNumericField(fPattern, fPattern.length())) {
211654dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius            pos++; // skip the extra "."
211754dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius        }
211854dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius    }
211954dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius
2120ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    // At this point the fields of Calendar have been set.  Calendar
2121ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    // will fill in default values for missing fields when the time
2122ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    // is computed.
2123ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
2124ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    parsePos.setIndex(pos);
2125ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
2126ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    // This part is a problem:  When we call parsedDate.after, we compute the time.
2127ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    // Take the date April 3 2004 at 2:30 am.  When this is first set up, the year
2128ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    // will be wrong if we're parsing a 2-digit year pattern.  It will be 1904.
2129ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    // April 3 1904 is a Sunday (unlike 2004) so it is the DST onset day.  2:30 am
2130ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    // is therefore an "impossible" time, since the time goes from 1:59 to 3:00 am
2131ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    // on that day.  It is therefore parsed out to fields as 3:30 am.  Then we
2132ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    // add 100 years, and get April 3 2004 at 3:30 am.  Note that April 3 2004 is
2133ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    // a Saturday, so it can have a 2:30 am -- and it should. [LIU]
2134ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    /*
2135ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        UDate parsedDate = calendar.getTime();
2136ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        if( ambiguousYear[0] && !parsedDate.after(fDefaultCenturyStart) ) {
2137ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            calendar.add(Calendar.YEAR, 100);
2138ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            parsedDate = calendar.getTime();
2139ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        }
2140ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    */
2141ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    // Because of the above condition, save off the fields in case we need to readjust.
2142ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    // The procedure we use here is not particularly efficient, but there is no other
2143ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    // way to do this given the API restrictions present in Calendar.  We minimize
2144ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    // inefficiency by only performing this computation when it might apply, that is,
2145ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    // when the two-digit year is equal to the start year, and thus might fall at the
2146ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    // front or the back of the default century.  This only works because we adjust
2147ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    // the year correctly to start with in other cases -- see subParse().
2148fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius    if (ambiguousYear[0] || tzTimeType != UTZFMT_TIME_TYPE_UNKNOWN) // If this is true then the two-digit year == the default start year
2149ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    {
2150ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        // We need a copy of the fields, and we need to avoid triggering a call to
2151ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        // complete(), which will recalculate the fields.  Since we can't access
2152ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        // the fields[] array in Calendar, we clone the entire object.  This will
2153ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        // stop working if Calendar.clone() is ever rewritten to call complete().
2154b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        Calendar *copy;
2155ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        if (ambiguousYear[0]) {
2156b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru            copy = cal.clone();
215785bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho            // Check for failed cloning.
215885bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho            if (copy == NULL) {
2159b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho                status = U_MEMORY_ALLOCATION_ERROR;
2160b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho                goto ExitParse;
216185bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho            }
2162ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            UDate parsedDate = copy->getTime(status);
2163ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            // {sfb} check internalGetDefaultCenturyStart
2164ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            if (fHaveDefaultCentury && (parsedDate < fDefaultCenturyStart)) {
2165ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                // We can't use add here because that does a complete() first.
2166ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                cal.set(UCAL_YEAR, fDefaultCenturyStartYear + 100);
2167ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            }
2168b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru            delete copy;
2169ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        }
2170ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
2171fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius        if (tzTimeType != UTZFMT_TIME_TYPE_UNKNOWN) {
2172b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru            copy = cal.clone();
217385bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho            // Check for failed cloning.
217485bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho            if (copy == NULL) {
2175b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho                status = U_MEMORY_ALLOCATION_ERROR;
2176b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho                goto ExitParse;
217785bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho            }
2178b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru            const TimeZone & tz = cal.getTimeZone();
2179b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru            BasicTimeZone *btz = NULL;
2180ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
218127f654740f2a26ad62a5c155af9199af9e69b889claireho            if (dynamic_cast<const OlsonTimeZone *>(&tz) != NULL
218227f654740f2a26ad62a5c155af9199af9e69b889claireho                || dynamic_cast<const SimpleTimeZone *>(&tz) != NULL
218327f654740f2a26ad62a5c155af9199af9e69b889claireho                || dynamic_cast<const RuleBasedTimeZone *>(&tz) != NULL
218427f654740f2a26ad62a5c155af9199af9e69b889claireho                || dynamic_cast<const VTimeZone *>(&tz) != NULL) {
2185b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                btz = (BasicTimeZone*)&tz;
2186ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            }
2187ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
2188b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru            // Get local millis
2189b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru            copy->set(UCAL_ZONE_OFFSET, 0);
2190b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru            copy->set(UCAL_DST_OFFSET, 0);
2191b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru            UDate localMillis = copy->getTime(status);
2192b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
2193b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru            // Make sure parsed time zone type (Standard or Daylight)
2194b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru            // matches the rule used by the parsed time zone.
2195b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru            int32_t raw, dst;
2196b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru            if (btz != NULL) {
2197fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius                if (tzTimeType == UTZFMT_TIME_TYPE_STANDARD) {
2198b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                    btz->getOffsetFromLocal(localMillis,
2199b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                        BasicTimeZone::kStandard, BasicTimeZone::kStandard, raw, dst, status);
2200b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                } else {
2201b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                    btz->getOffsetFromLocal(localMillis,
2202b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                        BasicTimeZone::kDaylight, BasicTimeZone::kDaylight, raw, dst, status);
2203b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                }
2204b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru            } else {
2205b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                // No good way to resolve ambiguous time at transition,
2206b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                // but following code work in most case.
2207b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                tz.getOffset(localMillis, TRUE, raw, dst, status);
2208b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru            }
2209b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
2210b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru            // Now, compare the results with parsed type, either standard or daylight saving time
2211b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru            int32_t resolvedSavings = dst;
2212fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius            if (tzTimeType == UTZFMT_TIME_TYPE_STANDARD) {
2213b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                if (dst != 0) {
2214b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                    // Override DST_OFFSET = 0 in the result calendar
2215b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                    resolvedSavings = 0;
2216b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                }
2217b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru            } else { // tztype == TZTYPE_DST
2218b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                if (dst == 0) {
2219b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                    if (btz != NULL) {
2220b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                        UDate time = localMillis + raw;
2221b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                        // We use the nearest daylight saving time rule.
2222b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                        TimeZoneTransition beforeTrs, afterTrs;
2223b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                        UDate beforeT = time, afterT = time;
2224b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                        int32_t beforeSav = 0, afterSav = 0;
2225b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                        UBool beforeTrsAvail, afterTrsAvail;
2226b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
2227b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                        // Search for DST rule before or on the time
2228b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                        while (TRUE) {
2229b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                            beforeTrsAvail = btz->getPreviousTransition(beforeT, TRUE, beforeTrs);
2230b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                            if (!beforeTrsAvail) {
2231b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                                break;
2232b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                            }
2233b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                            beforeT = beforeTrs.getTime() - 1;
2234b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                            beforeSav = beforeTrs.getFrom()->getDSTSavings();
2235b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                            if (beforeSav != 0) {
2236b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                                break;
2237b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                            }
2238b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                        }
2239b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
2240b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                        // Search for DST rule after the time
2241b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                        while (TRUE) {
2242b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                            afterTrsAvail = btz->getNextTransition(afterT, FALSE, afterTrs);
2243b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                            if (!afterTrsAvail) {
2244b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                                break;
2245b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                            }
2246b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                            afterT = afterTrs.getTime();
2247b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                            afterSav = afterTrs.getTo()->getDSTSavings();
2248b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                            if (afterSav != 0) {
2249b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                                break;
2250b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                            }
2251b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                        }
2252b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
2253b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                        if (beforeTrsAvail && afterTrsAvail) {
2254b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                            if (time - beforeT > afterT - time) {
2255b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                                resolvedSavings = afterSav;
2256b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                            } else {
2257b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                                resolvedSavings = beforeSav;
2258b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                            }
2259b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                        } else if (beforeTrsAvail && beforeSav != 0) {
2260b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                            resolvedSavings = beforeSav;
2261b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                        } else if (afterTrsAvail && afterSav != 0) {
2262b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                            resolvedSavings = afterSav;
2263b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                        } else {
2264b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                            resolvedSavings = btz->getDSTSavings();
2265b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                        }
2266b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                    } else {
2267b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                        resolvedSavings = tz.getDSTSavings();
2268b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                    }
2269b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                    if (resolvedSavings == 0) {
2270b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                        // final fallback
2271b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                        resolvedSavings = U_MILLIS_PER_HOUR;
2272b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                    }
2273b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                }
2274b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru            }
2275b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru            cal.set(UCAL_ZONE_OFFSET, raw);
2276b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru            cal.set(UCAL_DST_OFFSET, resolvedSavings);
2277b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru            delete copy;
2278b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        }
2279ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    }
228085bf2e2fbc60a9f938064abc8127d61da7d19882Claire HoExitParse:
228185bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    // Set the parsed result if local calendar is used
228285bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    // instead of the input calendar
228385bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    if (U_SUCCESS(status) && workCal != &cal) {
228485bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho        cal.setTimeZone(workCal->getTimeZone());
228585bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho        cal.setTime(workCal->getTime(status), status);
228685bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    }
228785bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho
2288103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius    if (numericLeapMonthFormatter != NULL) {
2289103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius        delete numericLeapMonthFormatter;
2290103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius    }
2291103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius    if (calClone != NULL) {
2292103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius        delete calClone;
229385bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    }
2294ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
2295ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    // If any Calendar calls failed, we pretend that we
2296ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    // couldn't parse the string, when in reality this isn't quite accurate--
2297ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    // we did parse it; the Calendar calls just failed.
229850294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    if (U_FAILURE(status)) {
2299ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        parsePos.setErrorIndex(pos);
230085bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho        parsePos.setIndex(start);
2301ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    }
2302ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru}
2303ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
2304ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru//----------------------------------------------------------------------
2305ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
23061b7d32f919554dda9c193b32188251337bc756f1Fredrik Roubertstatic int32_t
23071b7d32f919554dda9c193b32188251337bc756f1Fredrik RoubertmatchStringWithOptionalDot(const UnicodeString &text,
23081b7d32f919554dda9c193b32188251337bc756f1Fredrik Roubert                            int32_t index,
23091b7d32f919554dda9c193b32188251337bc756f1Fredrik Roubert                            const UnicodeString &data);
231054dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius
2311ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queruint32_t SimpleDateFormat::matchQuarterString(const UnicodeString& text,
2312ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                              int32_t start,
2313ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                              UCalendarDateFields field,
2314ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                              const UnicodeString* data,
2315ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                              int32_t dataCount,
2316ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                              Calendar& cal) const
2317ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru{
2318ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    int32_t i = 0;
2319ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    int32_t count = dataCount;
2320ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
2321ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    // There may be multiple strings in the data[] array which begin with
2322ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    // the same prefix (e.g., Cerven and Cervenec (June and July) in Czech).
2323ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    // We keep track of the longest match, and return that.  Note that this
2324ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    // unfortunately requires us to test all array elements.
2325ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    int32_t bestMatchLength = 0, bestMatch = -1;
232654dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius    UnicodeString bestMatchName;
2327ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
23281b7d32f919554dda9c193b32188251337bc756f1Fredrik Roubert    for (; i < count; ++i) {
23291b7d32f919554dda9c193b32188251337bc756f1Fredrik Roubert        int32_t matchLength = 0;
23301b7d32f919554dda9c193b32188251337bc756f1Fredrik Roubert        if ((matchLength = matchStringWithOptionalDot(text, start, data[i])) > bestMatchLength) {
23311b7d32f919554dda9c193b32188251337bc756f1Fredrik Roubert            bestMatchLength = matchLength;
2332ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            bestMatch = i;
2333ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        }
2334ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    }
2335ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
23361b7d32f919554dda9c193b32188251337bc756f1Fredrik Roubert    if (bestMatch >= 0) {
23371b7d32f919554dda9c193b32188251337bc756f1Fredrik Roubert        cal.set(field, bestMatch * 3);
23381b7d32f919554dda9c193b32188251337bc756f1Fredrik Roubert        return start + bestMatchLength;
2339ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    }
234050294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho
2341ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    return -start;
2342ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru}
2343ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
2344ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru//----------------------------------------------------------------------
2345b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2clairehoUBool SimpleDateFormat::matchLiterals(const UnicodeString &pattern,
2346b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho                                      int32_t &patternOffset,
2347b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho                                      const UnicodeString &text,
2348b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho                                      int32_t &textOffset,
2349fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius                                      UBool whitespaceLenient,
2350f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius                                      UBool partialMatchLenient,
2351f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius                                      UBool oldLeniency)
2352b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho{
2353b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho    UBool inQuote = FALSE;
2354f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius    UnicodeString literal;
2355b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho    int32_t i = patternOffset;
23561b7d32f919554dda9c193b32188251337bc756f1Fredrik Roubert
2357b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho    // scan pattern looking for contiguous literal characters
2358b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho    for ( ; i < pattern.length(); i += 1) {
2359b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho        UChar ch = pattern.charAt(i);
2360b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho
23611b7d32f919554dda9c193b32188251337bc756f1Fredrik Roubert        if (!inQuote && isSyntaxChar(ch)) {
2362b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho            break;
2363b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho        }
2364b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho
2365b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho        if (ch == QUOTE) {
2366b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho            // Match a quote literal ('') inside OR outside of quotes
2367b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho            if ((i + 1) < pattern.length() && pattern.charAt(i + 1) == QUOTE) {
2368b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho                i += 1;
2369b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho            } else {
2370b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho                inQuote = !inQuote;
2371b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho                continue;
2372b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho            }
2373b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho        }
2374b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho
2375b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho        literal += ch;
2376b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho    }
2377b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho
2378b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho    // at this point, literal contains the literal text
2379b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho    // and i is the index of the next non-literal pattern character.
2380b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho    int32_t p;
2381b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho    int32_t t = textOffset;
2382b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho
2383fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius    if (whitespaceLenient) {
2384b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho        // trim leading, trailing whitespace from
2385b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho        // the literal text
2386b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho        literal.trim();
2387b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho
2388b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho        // ignore any leading whitespace in the text
2389b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho        while (t < text.length() && u_isWhitespace(text.charAt(t))) {
2390b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho            t += 1;
2391b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho        }
2392b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho    }
2393b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho
239454dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius    for (p = 0; p < literal.length() && t < text.length();) {
2395b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho        UBool needWhitespace = FALSE;
2396b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho
2397b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho        while (p < literal.length() && PatternProps::isWhiteSpace(literal.charAt(p))) {
2398b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho            needWhitespace = TRUE;
2399b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho            p += 1;
2400b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho        }
2401b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho
2402b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho        if (needWhitespace) {
2403b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho            int32_t tStart = t;
2404b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho
2405b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho            while (t < text.length()) {
2406b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho                UChar tch = text.charAt(t);
2407b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho
2408b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho                if (!u_isUWhiteSpace(tch) && !PatternProps::isWhiteSpace(tch)) {
2409b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho                    break;
2410b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho                }
2411b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho
2412b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho                t += 1;
2413b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho            }
2414b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho
2415b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho            // TODO: should we require internal spaces
2416b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho            // in lenient mode? (There won't be any
2417b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho            // leading or trailing spaces)
2418fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius            if (!whitespaceLenient && t == tStart) {
2419b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho                // didn't find matching whitespace:
2420b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho                // an error in strict mode
2421b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho                return FALSE;
2422b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho            }
2423b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho
2424b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho            // In strict mode, this run of whitespace
2425b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho            // may have been at the end.
2426b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho            if (p >= literal.length()) {
2427b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho                break;
2428b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho            }
2429b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho        }
2430b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho        if (t >= text.length() || literal.charAt(p) != text.charAt(t)) {
2431b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho            // Ran out of text, or found a non-matching character:
2432b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho            // OK in lenient mode, an error in strict mode.
2433fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius            if (whitespaceLenient) {
243454dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius                if (t == textOffset && text.charAt(t) == 0x2e &&
243554dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius                        isAfterNonNumericField(pattern, patternOffset)) {
243654dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius                    // Lenient mode and the literal input text begins with a "." and
243754dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius                    // we are after a non-numeric field: We skip the "."
243854dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius                    ++t;
243954dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius                    continue;  // Do not update p.
244054dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius                }
2441f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius                // if it is actual whitespace and we're whitespace lenient it's OK
2442f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius
2443fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius                UChar wsc = text.charAt(t);
2444f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius                if(PatternProps::isWhiteSpace(wsc)) {
2445f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius                    // Lenient mode and it's just whitespace we skip it
2446f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius                    ++t;
2447f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius                    continue;  // Do not update p.
2448f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius                }
2449fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius            }
2450f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius            // hack around oldleniency being a bit of a catch-all bucket and we're just adding support specifically for paritial matches
2451f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius            if(partialMatchLenient && oldLeniency) {
2452b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho                break;
2453b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho            }
2454f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius
2455b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho            return FALSE;
2456b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho        }
245754dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius        ++p;
245854dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius        ++t;
2459b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho    }
2460b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho
2461b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho    // At this point if we're in strict mode we have a complete match.
2462b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho    // If we're in lenient mode we may have a partial match, or no
2463b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho    // match at all.
2464b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho    if (p <= 0) {
2465b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho        // no match. Pretend it matched a run of whitespace
2466b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho        // and ignorables in the text.
2467b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho        const  UnicodeSet *ignorables = NULL;
246854dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius        UDateFormatField patternCharIndex = DateFormatSymbols::getPatternCharIndex(pattern.charAt(i));
246954dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius        if (patternCharIndex != UDAT_FIELD_COUNT) {
2470b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho            ignorables = SimpleDateFormatStaticSets::getIgnorables(patternCharIndex);
2471b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho        }
2472b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho
2473b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho        for (t = textOffset; t < text.length(); t += 1) {
2474b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho            UChar ch = text.charAt(t);
2475b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho
2476b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho            if (ignorables == NULL || !ignorables->contains(ch)) {
2477b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho                break;
2478b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho            }
2479b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho        }
2480b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho    }
2481b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho
2482b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho    // if we get here, we've got a complete match.
2483b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho    patternOffset = i - 1;
2484b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho    textOffset = t;
2485b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho
2486b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho    return TRUE;
2487b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho}
2488b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho
2489b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho//----------------------------------------------------------------------
2490ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
2491ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queruint32_t SimpleDateFormat::matchString(const UnicodeString& text,
2492ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                              int32_t start,
2493ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                              UCalendarDateFields field,
2494ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                              const UnicodeString* data,
2495ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                              int32_t dataCount,
2496103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius                              const UnicodeString* monthPattern,
2497ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                              Calendar& cal) const
2498ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru{
2499ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    int32_t i = 0;
2500ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    int32_t count = dataCount;
2501ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
2502ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    if (field == UCAL_DAY_OF_WEEK) i = 1;
2503ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
2504ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    // There may be multiple strings in the data[] array which begin with
2505ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    // the same prefix (e.g., Cerven and Cervenec (June and July) in Czech).
2506ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    // We keep track of the longest match, and return that.  Note that this
2507ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    // unfortunately requires us to test all array elements.
2508ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    int32_t bestMatchLength = 0, bestMatch = -1;
2509103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius    UnicodeString bestMatchName;
2510103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius    int32_t isLeapMonth = 0;
2511ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
25121b7d32f919554dda9c193b32188251337bc756f1Fredrik Roubert    for (; i < count; ++i) {
25131b7d32f919554dda9c193b32188251337bc756f1Fredrik Roubert        int32_t matchLen = 0;
25141b7d32f919554dda9c193b32188251337bc756f1Fredrik Roubert        if ((matchLen = matchStringWithOptionalDot(text, start, data[i])) > bestMatchLength) {
2515ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            bestMatch = i;
25161b7d32f919554dda9c193b32188251337bc756f1Fredrik Roubert            bestMatchLength = matchLen;
2517103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius        }
2518103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius
2519103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius        if (monthPattern != NULL) {
2520103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius            UErrorCode status = U_ZERO_ERROR;
2521103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius            UnicodeString leapMonthName;
2522103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius            Formattable monthName((const UnicodeString&)(data[i]));
2523103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius            MessageFormat::format(*monthPattern, &monthName, 1, leapMonthName, status);
2524103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius            if (U_SUCCESS(status)) {
25251b7d32f919554dda9c193b32188251337bc756f1Fredrik Roubert                if ((matchLen = matchStringWithOptionalDot(text, start, leapMonthName)) > bestMatchLength) {
2526103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius                    bestMatch = i;
25271b7d32f919554dda9c193b32188251337bc756f1Fredrik Roubert                    bestMatchLength = matchLen;
2528103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius                    isLeapMonth = 1;
2529103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius                }
2530103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius            }
2531ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        }
2532ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    }
2533ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
25341b7d32f919554dda9c193b32188251337bc756f1Fredrik Roubert    if (bestMatch >= 0) {
25351b7d32f919554dda9c193b32188251337bc756f1Fredrik Roubert        if (field < UCAL_FIELD_COUNT) {
25361b7d32f919554dda9c193b32188251337bc756f1Fredrik Roubert            // Adjustment for Hebrew Calendar month Adar II
25371b7d32f919554dda9c193b32188251337bc756f1Fredrik Roubert            if (!strcmp(cal.getType(),"hebrew") && field==UCAL_MONTH && bestMatch==13) {
25381b7d32f919554dda9c193b32188251337bc756f1Fredrik Roubert                cal.set(field,6);
25391b7d32f919554dda9c193b32188251337bc756f1Fredrik Roubert            } else {
25401b7d32f919554dda9c193b32188251337bc756f1Fredrik Roubert                if (field == UCAL_YEAR) {
25411b7d32f919554dda9c193b32188251337bc756f1Fredrik Roubert                    bestMatch++; // only get here for cyclic year names, which match 1-based years 1-60
25421b7d32f919554dda9c193b32188251337bc756f1Fredrik Roubert                }
25431b7d32f919554dda9c193b32188251337bc756f1Fredrik Roubert                cal.set(field, bestMatch);
2544ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            }
25451b7d32f919554dda9c193b32188251337bc756f1Fredrik Roubert            if (monthPattern != NULL) {
25461b7d32f919554dda9c193b32188251337bc756f1Fredrik Roubert                cal.set(UCAL_IS_LEAP_MONTH, isLeapMonth);
2547ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            }
2548ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        }
25491b7d32f919554dda9c193b32188251337bc756f1Fredrik Roubert
25501b7d32f919554dda9c193b32188251337bc756f1Fredrik Roubert        return start + bestMatchLength;
2551ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    }
255250294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho
2553ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    return -start;
2554ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru}
2555ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
25561b7d32f919554dda9c193b32188251337bc756f1Fredrik Roubertstatic int32_t
25571b7d32f919554dda9c193b32188251337bc756f1Fredrik RoubertmatchStringWithOptionalDot(const UnicodeString &text,
25581b7d32f919554dda9c193b32188251337bc756f1Fredrik Roubert                            int32_t index,
25591b7d32f919554dda9c193b32188251337bc756f1Fredrik Roubert                            const UnicodeString &data) {
25601b7d32f919554dda9c193b32188251337bc756f1Fredrik Roubert    UErrorCode sts = U_ZERO_ERROR;
25611b7d32f919554dda9c193b32188251337bc756f1Fredrik Roubert    int32_t matchLenText = 0;
25621b7d32f919554dda9c193b32188251337bc756f1Fredrik Roubert    int32_t matchLenData = 0;
256354dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius
25641b7d32f919554dda9c193b32188251337bc756f1Fredrik Roubert    u_caseInsensitivePrefixMatch(text.getBuffer() + index, text.length() - index,
25651b7d32f919554dda9c193b32188251337bc756f1Fredrik Roubert                                 data.getBuffer(), data.length(),
25661b7d32f919554dda9c193b32188251337bc756f1Fredrik Roubert                                 0 /* default case option */,
25671b7d32f919554dda9c193b32188251337bc756f1Fredrik Roubert                                 &matchLenText, &matchLenData,
25681b7d32f919554dda9c193b32188251337bc756f1Fredrik Roubert                                 &sts);
25691b7d32f919554dda9c193b32188251337bc756f1Fredrik Roubert    U_ASSERT (U_SUCCESS(sts));
25701b7d32f919554dda9c193b32188251337bc756f1Fredrik Roubert
25711b7d32f919554dda9c193b32188251337bc756f1Fredrik Roubert    if (matchLenData == data.length() /* normal match */
25721b7d32f919554dda9c193b32188251337bc756f1Fredrik Roubert        || (data.charAt(data.length() - 1) == 0x2e
25731b7d32f919554dda9c193b32188251337bc756f1Fredrik Roubert            && matchLenData == data.length() - 1 /* match without trailing dot */)) {
25741b7d32f919554dda9c193b32188251337bc756f1Fredrik Roubert        return matchLenText;
257554dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius    }
25761b7d32f919554dda9c193b32188251337bc756f1Fredrik Roubert
25771b7d32f919554dda9c193b32188251337bc756f1Fredrik Roubert    return 0;
257854dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius}
257954dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius
2580ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru//----------------------------------------------------------------------
2581ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
2582ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queruvoid
2583ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste QueruSimpleDateFormat::set2DigitYearStart(UDate d, UErrorCode& status)
2584ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru{
2585ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    parseAmbiguousDatesAsAfter(d, status);
2586ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru}
2587ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
2588ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru/**
2589ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru * Private member function that converts the parsed date strings into
2590ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru * timeFields. Returns -start (for ParsePosition) if failed.
2591ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru */
2592ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queruint32_t SimpleDateFormat::subParse(const UnicodeString& text, int32_t& start, UChar ch, int32_t count,
259350294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho                           UBool obeyCount, UBool allowNegative, UBool ambiguousYear[], int32_t& saveHebrewMonth, Calendar& cal,
25941b7d32f919554dda9c193b32188251337bc756f1Fredrik Roubert                           int32_t patLoc, MessageFormat * numericLeapMonthFormatter, UTimeZoneFormatTimeType *tzTimeType, SimpleDateFormatMutableNFs &mutableNFs) const
2595ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru{
2596ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    Formattable number;
2597ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    int32_t value = 0;
2598ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    int32_t i;
259927f654740f2a26ad62a5c155af9199af9e69b889claireho    int32_t ps = 0;
260059d709d503bab6e2b61931737e662dd293b40578ccornelius    UErrorCode status = U_ZERO_ERROR;
2601ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    ParsePosition pos(0);
260254dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius    UDateFormatField patternCharIndex = DateFormatSymbols::getPatternCharIndex(ch);
260385bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    NumberFormat *currentNumberFormat;
2604ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    UnicodeString temp;
2605b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho    UBool gotNumber = FALSE;
2606ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
2607ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru#if defined (U_DEBUG_CAL)
2608ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    //fprintf(stderr, "%s:%d - [%c]  st=%d \n", __FILE__, __LINE__, (char) ch, start);
2609ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru#endif
2610ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
261154dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius    if (patternCharIndex == UDAT_FIELD_COUNT) {
2612ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        return -start;
2613ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    }
2614ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
26151b7d32f919554dda9c193b32188251337bc756f1Fredrik Roubert    currentNumberFormat = mutableNFs.get(getNumberFormatByIndex(patternCharIndex));
26161b7d32f919554dda9c193b32188251337bc756f1Fredrik Roubert    if (currentNumberFormat == NULL) {
26171b7d32f919554dda9c193b32188251337bc756f1Fredrik Roubert        return -start;
26181b7d32f919554dda9c193b32188251337bc756f1Fredrik Roubert    }
26191b7d32f919554dda9c193b32188251337bc756f1Fredrik Roubert    UCalendarDateFields field = fgPatternIndexToCalendarField[patternCharIndex]; // UCAL_FIELD_COUNT if irrelevant
262054dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius    UnicodeString hebr("hebr", 4, US_INV);
2621ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
2622103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius    if (numericLeapMonthFormatter != NULL) {
2623103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius        numericLeapMonthFormatter->setFormats((const Format **)&currentNumberFormat, 1);
2624103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius    }
262559d709d503bab6e2b61931737e662dd293b40578ccornelius    UBool isChineseCalendar = (uprv_strcmp(cal.getType(),"chinese") == 0 || uprv_strcmp(cal.getType(),"dangi") == 0);
2626103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius
2627ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    // If there are any spaces here, skip over them.  If we hit the end
2628ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    // of the string, then fail.
2629ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    for (;;) {
2630ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        if (start >= text.length()) {
2631ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            return -start;
2632ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        }
2633ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        UChar32 c = text.char32At(start);
2634b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho        if (!u_isUWhiteSpace(c) /*||*/ && !PatternProps::isWhiteSpace(c)) {
2635ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            break;
2636ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        }
2637103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius        start += U16_LENGTH(c);
2638ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    }
2639ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    pos.setIndex(start);
2640ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
2641ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    // We handle a few special cases here where we need to parse
2642ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    // a number value.  We handle further, more generic cases below.  We need
2643ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    // to handle some of them here because some fields require extra processing on
2644ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    // the parsed value.
2645b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho    if (patternCharIndex == UDAT_HOUR_OF_DAY1_FIELD ||                       // k
2646b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho        patternCharIndex == UDAT_HOUR_OF_DAY0_FIELD ||                       // H
2647b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho        patternCharIndex == UDAT_HOUR1_FIELD ||                              // h
2648b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho        patternCharIndex == UDAT_HOUR0_FIELD ||                              // K
2649b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho        (patternCharIndex == UDAT_DOW_LOCAL_FIELD && count <= 2) ||          // e
2650b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho        (patternCharIndex == UDAT_STANDALONE_DAY_FIELD && count <= 2) ||     // c
2651b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho        (patternCharIndex == UDAT_MONTH_FIELD && count <= 2) ||              // M
2652b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho        (patternCharIndex == UDAT_STANDALONE_MONTH_FIELD && count <= 2) ||   // L
2653b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho        (patternCharIndex == UDAT_QUARTER_FIELD && count <= 2) ||            // Q
2654b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho        (patternCharIndex == UDAT_STANDALONE_QUARTER_FIELD && count <= 2) || // q
2655b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho        patternCharIndex == UDAT_YEAR_FIELD ||                               // y
2656b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho        patternCharIndex == UDAT_YEAR_WOY_FIELD ||                           // Y
2657103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius        patternCharIndex == UDAT_YEAR_NAME_FIELD ||                          // U (falls back to numeric)
2658103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius        (patternCharIndex == UDAT_ERA_FIELD && isChineseCalendar) ||         // G
2659b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho        patternCharIndex == UDAT_FRACTIONAL_SECOND_FIELD)                    // S
2660ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    {
2661ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        int32_t parseStart = pos.getIndex();
2662ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        // It would be good to unify this with the obeyCount logic below,
2663ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        // but that's going to be difficult.
2664ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        const UnicodeString* src;
2665ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
2666103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius        UBool parsedNumericLeapMonth = FALSE;
2667103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius        if (numericLeapMonthFormatter != NULL && (patternCharIndex == UDAT_MONTH_FIELD || patternCharIndex == UDAT_STANDALONE_MONTH_FIELD)) {
2668103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius            int32_t argCount;
2669103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius            Formattable * args = numericLeapMonthFormatter->parse(text, pos, argCount);
2670103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius            if (args != NULL && argCount == 1 && pos.getIndex() > parseStart && args[0].isNumeric()) {
2671103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius                parsedNumericLeapMonth = TRUE;
2672103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius                number.setLong(args[0].getLong());
2673103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius                cal.set(UCAL_IS_LEAP_MONTH, 1);
2674103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius                delete[] args;
2675103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius            } else {
2676103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius                pos.setIndex(parseStart);
2677103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius                cal.set(UCAL_IS_LEAP_MONTH, 0);
2678ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            }
2679ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        }
2680ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
2681103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius        if (!parsedNumericLeapMonth) {
2682103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius            if (obeyCount) {
2683103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius                if ((start+count) > text.length()) {
2684103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius                    return -start;
2685103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius                }
2686103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius
2687103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius                text.extractBetween(0, start + count, temp);
2688103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius                src = &temp;
2689103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius            } else {
2690103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius                src = &text;
2691103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius            }
2692103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius
2693103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius            parseInt(*src, number, pos, allowNegative,currentNumberFormat);
2694103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius        }
2695ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
269685bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho        int32_t txtLoc = pos.getIndex();
2697b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho
2698b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho        if (txtLoc > parseStart) {
2699b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho            value = number.getLong();
2700b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho            gotNumber = TRUE;
2701b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho
2702b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho            // suffix processing
2703b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho            if (value < 0 ) {
2704b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho                txtLoc = checkIntSuffix(text, txtLoc, patLoc+1, TRUE);
2705b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho                if (txtLoc != pos.getIndex()) {
2706b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho                    value *= -1;
2707b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho                }
2708b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho            }
2709b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho            else {
2710b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho                txtLoc = checkIntSuffix(text, txtLoc, patLoc+1, FALSE);
271185bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho            }
271285bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho
271359d709d503bab6e2b61931737e662dd293b40578ccornelius            if (!getBooleanAttribute(UDAT_PARSE_ALLOW_WHITESPACE, status)) {
2714b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho                // Check the range of the value
2715b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho                int32_t bias = gFieldRangeBias[patternCharIndex];
2716b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho                if (bias >= 0 && (value > cal.getMaximum(field) + bias || value < cal.getMinimum(field) + bias)) {
2717b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho                    return -start;
2718b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho                }
2719b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho            }
2720b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho
2721b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho            pos.setIndex(txtLoc);
2722b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho        }
2723b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho    }
2724b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho
2725b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho    // Make sure that we got a number if
2726b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho    // we want one, and didn't get one
2727b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho    // if we don't want one.
2728b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho    switch (patternCharIndex) {
2729b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho        case UDAT_HOUR_OF_DAY1_FIELD:
2730b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho        case UDAT_HOUR_OF_DAY0_FIELD:
2731b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho        case UDAT_HOUR1_FIELD:
2732b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho        case UDAT_HOUR0_FIELD:
2733b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho            // special range check for hours:
2734b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho            if (value < 0 || value > 24) {
2735b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho                return -start;
2736b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho            }
2737b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho
2738b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho            // fall through to gotNumber check
2739b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho
2740b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho        case UDAT_YEAR_FIELD:
2741b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho        case UDAT_YEAR_WOY_FIELD:
2742b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho        case UDAT_FRACTIONAL_SECOND_FIELD:
2743b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho            // these must be a number
2744b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho            if (! gotNumber) {
2745b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho                return -start;
2746b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho            }
2747b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho
2748b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho            break;
2749b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho
2750b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho        default:
2751b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho            // we check the rest of the fields below.
2752b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho            break;
2753ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    }
2754ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
2755ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    switch (patternCharIndex) {
2756ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    case UDAT_ERA_FIELD:
2757103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius        if (isChineseCalendar) {
2758103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius            if (!gotNumber) {
2759103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius                return -start;
2760103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius            }
2761103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius            cal.set(UCAL_ERA, value);
2762103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius            return pos.getIndex();
2763103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius        }
276485bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho        if (count == 5) {
2765103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius            ps = matchString(text, start, UCAL_ERA, fSymbols->fNarrowEras, fSymbols->fNarrowErasCount, NULL, cal);
2766b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho        } else if (count == 4) {
2767103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius            ps = matchString(text, start, UCAL_ERA, fSymbols->fEraNames, fSymbols->fEraNamesCount, NULL, cal);
2768b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho        } else {
2769103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius            ps = matchString(text, start, UCAL_ERA, fSymbols->fEras, fSymbols->fErasCount, NULL, cal);
277027f654740f2a26ad62a5c155af9199af9e69b889claireho        }
277127f654740f2a26ad62a5c155af9199af9e69b889claireho
277227f654740f2a26ad62a5c155af9199af9e69b889claireho        // check return position, if it equals -start, then matchString error
277327f654740f2a26ad62a5c155af9199af9e69b889claireho        // special case the return code so we don't necessarily fail out until we
277427f654740f2a26ad62a5c155af9199af9e69b889claireho        // verify no year information also
277527f654740f2a26ad62a5c155af9199af9e69b889claireho        if (ps == -start)
277627f654740f2a26ad62a5c155af9199af9e69b889claireho            ps--;
2777ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
277827f654740f2a26ad62a5c155af9199af9e69b889claireho        return ps;
2779ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
2780ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    case UDAT_YEAR_FIELD:
2781ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        // If there are 3 or more YEAR pattern characters, this indicates
2782ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        // that the year value is to be treated literally, without any
2783ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        // two-digit year adjustments (e.g., from "01" to 2001).  Otherwise
2784ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        // we made adjustments to place the 2-digit year in the proper
2785ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        // century, for parsed strings from "00" to "99".  Any other string
2786ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        // is treated literally:  "2250", "-1", "1", "002".
278754dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius        if (fDateOverride.compare(hebr)==0 && value < 1000) {
278854dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius            value += HEBREW_CAL_CUR_MILLENIUM_START_YEAR;
278954dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius        } else if ((pos.getIndex() - start) == 2 && !isChineseCalendar
2790ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            && u_isdigit(text.charAt(start))
2791ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            && u_isdigit(text.charAt(start+1)))
2792ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        {
2793fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius            // only adjust year for patterns less than 3.
2794fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius            if(count < 3) {
2795fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius                // Assume for example that the defaultCenturyStart is 6/18/1903.
2796fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius                // This means that two-digit years will be forced into the range
2797fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius                // 6/18/1903 to 6/17/2003.  As a result, years 00, 01, and 02
2798fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius                // correspond to 2000, 2001, and 2002.  Years 04, 05, etc. correspond
2799fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius                // to 1904, 1905, etc.  If the year is 03, then it is 2003 if the
2800fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius                // other fields specify a date before 6/18, or 1903 if they specify a
2801fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius                // date afterwards.  As a result, 03 is an ambiguous year.  All other
2802fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius                // two-digit years are unambiguous.
2803fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius                if(fHaveDefaultCentury) { // check if this formatter even has a pivot year
2804fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius                    int32_t ambiguousTwoDigitYear = fDefaultCenturyStartYear % 100;
2805fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius                    ambiguousYear[0] = (value == ambiguousTwoDigitYear);
2806fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius                    value += (fDefaultCenturyStartYear/100)*100 +
2807fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius                            (value < ambiguousTwoDigitYear ? 100 : 0);
2808fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius                }
2809ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            }
2810ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        }
2811ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        cal.set(UCAL_YEAR, value);
281250294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho
281350294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho        // Delayed checking for adjustment of Hebrew month numbers in non-leap years.
281450294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho        if (saveHebrewMonth >= 0) {
281550294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho            HebrewCalendar *hc = (HebrewCalendar*)&cal;
281650294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho            if (!hc->isLeapYear(value) && saveHebrewMonth >= 6) {
281750294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho               cal.set(UCAL_MONTH,saveHebrewMonth);
281850294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho            } else {
281950294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho               cal.set(UCAL_MONTH,saveHebrewMonth-1);
282050294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho            }
282150294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho            saveHebrewMonth = -1;
282250294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho        }
2823ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        return pos.getIndex();
2824ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
2825ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    case UDAT_YEAR_WOY_FIELD:
2826ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        // Comment is the same as for UDAT_Year_FIELDs - look above
282754dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius        if (fDateOverride.compare(hebr)==0 && value < 1000) {
282854dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius            value += HEBREW_CAL_CUR_MILLENIUM_START_YEAR;
282954dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius        } else if ((pos.getIndex() - start) == 2
2830ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            && u_isdigit(text.charAt(start))
2831ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            && u_isdigit(text.charAt(start+1))
2832ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            && fHaveDefaultCentury )
2833ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        {
2834ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            int32_t ambiguousTwoDigitYear = fDefaultCenturyStartYear % 100;
2835ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            ambiguousYear[0] = (value == ambiguousTwoDigitYear);
2836ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            value += (fDefaultCenturyStartYear/100)*100 +
2837ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                (value < ambiguousTwoDigitYear ? 100 : 0);
2838ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        }
2839ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        cal.set(UCAL_YEAR_WOY, value);
2840ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        return pos.getIndex();
2841ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
2842103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius    case UDAT_YEAR_NAME_FIELD:
2843103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius        if (fSymbols->fShortYearNames != NULL) {
2844103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius            int32_t newStart = matchString(text, start, UCAL_YEAR, fSymbols->fShortYearNames, fSymbols->fShortYearNamesCount, NULL, cal);
2845103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius            if (newStart > 0) {
2846103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius                return newStart;
2847103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius            }
2848103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius        }
284959d709d503bab6e2b61931737e662dd293b40578ccornelius        if (gotNumber && (getBooleanAttribute(UDAT_PARSE_ALLOW_NUMERIC,status) || value > fSymbols->fShortYearNamesCount)) {
2850103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius            cal.set(UCAL_YEAR, value);
2851103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius            return pos.getIndex();
2852103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius        }
2853103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius        return -start;
2854103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius
2855ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    case UDAT_MONTH_FIELD:
2856103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius    case UDAT_STANDALONE_MONTH_FIELD:
2857b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho        if (gotNumber) // i.e., M or MM.
2858ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        {
285950294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho            // When parsing month numbers from the Hebrew Calendar, we might need to adjust the month depending on whether
286050294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho            // or not it was a leap year.  We may or may not yet know what year it is, so might have to delay checking until
286150294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho            // the year is parsed.
286250294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho            if (!strcmp(cal.getType(),"hebrew")) {
286350294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho                HebrewCalendar *hc = (HebrewCalendar*)&cal;
286450294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho                if (cal.isSet(UCAL_YEAR)) {
286550294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho                   UErrorCode status = U_ZERO_ERROR;
286650294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho                   if (!hc->isLeapYear(hc->get(UCAL_YEAR,status)) && value >= 6) {
286750294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho                       cal.set(UCAL_MONTH, value);
286850294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho                   } else {
286950294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho                       cal.set(UCAL_MONTH, value - 1);
287050294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho                   }
287150294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho                } else {
287250294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho                    saveHebrewMonth = value;
287350294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho                }
287450294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho            } else {
287550294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho                // Don't want to parse the month if it is a string
2876103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius                // while pattern uses numeric style: M/MM, L/LL
287750294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho                // [We computed 'value' above.]
287850294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho                cal.set(UCAL_MONTH, value - 1);
287950294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho            }
2880ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            return pos.getIndex();
2881ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        } else {
2882103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius            // count >= 3 // i.e., MMM/MMMM, LLL/LLLL
2883ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            // Want to be able to parse both short and long forms.
2884ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            // Try count == 4 first:
2885103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius            UnicodeString * wideMonthPat = NULL;
2886103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius            UnicodeString * shortMonthPat = NULL;
2887103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius            if (fSymbols->fLeapMonthPatterns != NULL && fSymbols->fLeapMonthPatternsCount >= DateFormatSymbols::kMonthPatternsCount) {
2888103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius                if (patternCharIndex==UDAT_MONTH_FIELD) {
2889103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius                    wideMonthPat = &fSymbols->fLeapMonthPatterns[DateFormatSymbols::kLeapMonthPatternFormatWide];
2890103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius                    shortMonthPat = &fSymbols->fLeapMonthPatterns[DateFormatSymbols::kLeapMonthPatternFormatAbbrev];
2891103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius                } else {
2892103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius                    wideMonthPat = &fSymbols->fLeapMonthPatterns[DateFormatSymbols::kLeapMonthPatternStandaloneWide];
2893103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius                    shortMonthPat = &fSymbols->fLeapMonthPatterns[DateFormatSymbols::kLeapMonthPatternStandaloneAbbrev];
2894103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius                }
2895103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius            }
2896ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            int32_t newStart = 0;
2897103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius            if (patternCharIndex==UDAT_MONTH_FIELD) {
2898fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius                if(getBooleanAttribute(UDAT_PARSE_MULTIPLE_PATTERNS_FOR_MATCH, status) || count == 4) {
2899fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius                    newStart = matchString(text, start, UCAL_MONTH, fSymbols->fMonths, fSymbols->fMonthsCount, wideMonthPat, cal); // try MMMM
2900fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius                    if (newStart > 0) {
2901fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius                        return newStart;
2902fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius                    }
2903fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius                }
2904fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius                if(getBooleanAttribute(UDAT_PARSE_MULTIPLE_PATTERNS_FOR_MATCH, status) || count == 3) {
2905fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius                    newStart = matchString(text, start, UCAL_MONTH, fSymbols->fShortMonths, fSymbols->fShortMonthsCount, shortMonthPat, cal); // try MMM
2906103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius                }
2907103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius            } else {
2908fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius                if(getBooleanAttribute(UDAT_PARSE_MULTIPLE_PATTERNS_FOR_MATCH, status) || count == 4) {
2909fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius                    newStart = matchString(text, start, UCAL_MONTH, fSymbols->fStandaloneMonths, fSymbols->fStandaloneMonthsCount, wideMonthPat, cal); // try LLLL
2910fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius                    if (newStart > 0) {
2911fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius                        return newStart;
2912fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius                    }
2913fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius                }
2914fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius                if(getBooleanAttribute(UDAT_PARSE_MULTIPLE_PATTERNS_FOR_MATCH, status) || count == 3) {
2915fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius                    newStart = matchString(text, start, UCAL_MONTH, fSymbols->fStandaloneShortMonths, fSymbols->fStandaloneShortMonthsCount, shortMonthPat, cal); // try LLL
2916103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius                }
2917103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius            }
291859d709d503bab6e2b61931737e662dd293b40578ccornelius            if (newStart > 0 || !getBooleanAttribute(UDAT_PARSE_ALLOW_NUMERIC, status))  // currently we do not try to parse MMMMM/LLLLL: #8860
2919b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho                return newStart;
2920b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho            // else we allowing parsing as number, below
2921ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        }
2922b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho        break;
2923ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
2924ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    case UDAT_HOUR_OF_DAY1_FIELD:
2925ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        // [We computed 'value' above.]
292650294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho        if (value == cal.getMaximum(UCAL_HOUR_OF_DAY) + 1)
2927ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            value = 0;
2928b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho
2929b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho        // fall through to set field
2930b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho
2931b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho    case UDAT_HOUR_OF_DAY0_FIELD:
2932ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        cal.set(UCAL_HOUR_OF_DAY, value);
2933ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        return pos.getIndex();
2934ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
2935ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    case UDAT_FRACTIONAL_SECOND_FIELD:
2936ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        // Fractional seconds left-justify
2937ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        i = pos.getIndex() - start;
2938ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        if (i < 3) {
2939ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            while (i < 3) {
2940ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                value *= 10;
2941ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                i++;
2942ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            }
2943ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        } else {
2944ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            int32_t a = 1;
2945ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            while (i > 3) {
2946ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                a *= 10;
2947ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                i--;
2948ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            }
29498393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius            value /= a;
2950ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        }
2951ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        cal.set(UCAL_MILLISECOND, value);
2952ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        return pos.getIndex();
2953ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
295485bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    case UDAT_DOW_LOCAL_FIELD:
2955b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho        if (gotNumber) // i.e., e or ee
295685bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho        {
295785bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho            // [We computed 'value' above.]
295885bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho            cal.set(UCAL_DOW_LOCAL, value);
295985bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho            return pos.getIndex();
296085bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho        }
296185bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho        // else for eee-eeeee fall through to handling of EEE-EEEEE
296285bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho        // fall through, do not break here
2963ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    case UDAT_DAY_OF_WEEK_FIELD:
2964ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        {
2965ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            // Want to be able to parse both short and long forms.
29668393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius            // Try count == 4 (EEEE) wide first:
2967ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            int32_t newStart = 0;
2968fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius            if(getBooleanAttribute(UDAT_PARSE_MULTIPLE_PATTERNS_FOR_MATCH, status) || count == 4) {
2969fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius                if ((newStart = matchString(text, start, UCAL_DAY_OF_WEEK,
2970fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius                                          fSymbols->fWeekdays, fSymbols->fWeekdaysCount, NULL, cal)) > 0)
2971fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius                    return newStart;
2972fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius            }
29738393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius            // EEEE wide failed, now try EEE abbreviated
2974fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius            if(getBooleanAttribute(UDAT_PARSE_MULTIPLE_PATTERNS_FOR_MATCH, status) || count == 3) {
2975fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius                if ((newStart = matchString(text, start, UCAL_DAY_OF_WEEK,
2976fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius                                       fSymbols->fShortWeekdays, fSymbols->fShortWeekdaysCount, NULL, cal)) > 0)
2977fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius                    return newStart;
2978fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius            }
29798393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius            // EEE abbreviated failed, now try EEEEEE short
2980fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius            if(getBooleanAttribute(UDAT_PARSE_MULTIPLE_PATTERNS_FOR_MATCH, status) || count == 6) {
2981fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius                if ((newStart = matchString(text, start, UCAL_DAY_OF_WEEK,
2982fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius                                       fSymbols->fShorterWeekdays, fSymbols->fShorterWeekdaysCount, NULL, cal)) > 0)
2983fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius                    return newStart;
2984fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius            }
29858393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius            // EEEEEE short failed, now try EEEEE narrow
2986fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius            if(getBooleanAttribute(UDAT_PARSE_MULTIPLE_PATTERNS_FOR_MATCH, status) || count == 5) {
2987fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius                if ((newStart = matchString(text, start, UCAL_DAY_OF_WEEK,
2988fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius                                       fSymbols->fNarrowWeekdays, fSymbols->fNarrowWeekdaysCount, NULL, cal)) > 0)
2989fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius                    return newStart;
2990fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius            }
2991fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius            if (!getBooleanAttribute(UDAT_PARSE_ALLOW_NUMERIC, status) || patternCharIndex == UDAT_DAY_OF_WEEK_FIELD)
2992b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho                return newStart;
2993b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho            // else we allowing parsing as number, below
2994ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        }
2995b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho        break;
2996ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
2997ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    case UDAT_STANDALONE_DAY_FIELD:
2998ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        {
2999b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho            if (gotNumber) // c or cc
300085bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho            {
300185bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho                // [We computed 'value' above.]
300285bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho                cal.set(UCAL_DOW_LOCAL, value);
300385bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho                return pos.getIndex();
300485bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho            }
3005ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            // Want to be able to parse both short and long forms.
300685bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho            // Try count == 4 (cccc) first:
3007ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            int32_t newStart = 0;
3008fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius            if(getBooleanAttribute(UDAT_PARSE_MULTIPLE_PATTERNS_FOR_MATCH, status) || count == 4) {
3009fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius                if ((newStart = matchString(text, start, UCAL_DAY_OF_WEEK,
3010103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius                                      fSymbols->fStandaloneWeekdays, fSymbols->fStandaloneWeekdaysCount, NULL, cal)) > 0)
3011fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius                    return newStart;
3012fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius            }
3013fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius            if(getBooleanAttribute(UDAT_PARSE_MULTIPLE_PATTERNS_FOR_MATCH, status) || count == 3) {
3014fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius                if ((newStart = matchString(text, start, UCAL_DAY_OF_WEEK,
3015103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius                                          fSymbols->fStandaloneShortWeekdays, fSymbols->fStandaloneShortWeekdaysCount, NULL, cal)) > 0)
3016fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius                    return newStart;
3017fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius            }
3018fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius            if(getBooleanAttribute(UDAT_PARSE_MULTIPLE_PATTERNS_FOR_MATCH, status) || count == 6) {
3019fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius                if ((newStart = matchString(text, start, UCAL_DAY_OF_WEEK,
30208393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius                                          fSymbols->fStandaloneShorterWeekdays, fSymbols->fStandaloneShorterWeekdaysCount, NULL, cal)) > 0)
3021fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius                    return newStart;
3022fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius            }
3023fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius            if (!getBooleanAttribute(UDAT_PARSE_ALLOW_NUMERIC, status))
3024b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho                return newStart;
3025b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho            // else we allowing parsing as number, below
3026ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        }
3027b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho        break;
3028ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
3029ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    case UDAT_AM_PM_FIELD:
30301b7d32f919554dda9c193b32188251337bc756f1Fredrik Roubert        {
30311b7d32f919554dda9c193b32188251337bc756f1Fredrik Roubert            // optionally try both wide/abbrev and narrow forms
30321b7d32f919554dda9c193b32188251337bc756f1Fredrik Roubert            int32_t newStart = 0;
30331b7d32f919554dda9c193b32188251337bc756f1Fredrik Roubert            // try wide/abbrev
30341b7d32f919554dda9c193b32188251337bc756f1Fredrik Roubert            if( getBooleanAttribute(UDAT_PARSE_MULTIPLE_PATTERNS_FOR_MATCH, status) || count < 5 ) {
30351b7d32f919554dda9c193b32188251337bc756f1Fredrik Roubert                if ((newStart = matchString(text, start, UCAL_AM_PM, fSymbols->fAmPms, fSymbols->fAmPmsCount, NULL, cal)) > 0) {
30361b7d32f919554dda9c193b32188251337bc756f1Fredrik Roubert                    return newStart;
30371b7d32f919554dda9c193b32188251337bc756f1Fredrik Roubert                }
30381b7d32f919554dda9c193b32188251337bc756f1Fredrik Roubert            }
30391b7d32f919554dda9c193b32188251337bc756f1Fredrik Roubert            // try narrow
30401b7d32f919554dda9c193b32188251337bc756f1Fredrik Roubert            if( getBooleanAttribute(UDAT_PARSE_MULTIPLE_PATTERNS_FOR_MATCH, status) || count >= 5 ) {
30411b7d32f919554dda9c193b32188251337bc756f1Fredrik Roubert                if ((newStart = matchString(text, start, UCAL_AM_PM, fSymbols->fNarrowAmPms, fSymbols->fNarrowAmPmsCount, NULL, cal)) > 0) {
30421b7d32f919554dda9c193b32188251337bc756f1Fredrik Roubert                    return newStart;
30431b7d32f919554dda9c193b32188251337bc756f1Fredrik Roubert                }
30441b7d32f919554dda9c193b32188251337bc756f1Fredrik Roubert            }
30451b7d32f919554dda9c193b32188251337bc756f1Fredrik Roubert            // no matches for given options
30461b7d32f919554dda9c193b32188251337bc756f1Fredrik Roubert            return -start;
30471b7d32f919554dda9c193b32188251337bc756f1Fredrik Roubert        }
3048ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
3049ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    case UDAT_HOUR1_FIELD:
3050ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        // [We computed 'value' above.]
305150294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho        if (value == cal.getLeastMaximum(UCAL_HOUR)+1)
3052ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            value = 0;
3053b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho
3054b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho        // fall through to set field
3055b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho
3056b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho    case UDAT_HOUR0_FIELD:
3057ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        cal.set(UCAL_HOUR, value);
3058ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        return pos.getIndex();
3059ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
3060ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    case UDAT_QUARTER_FIELD:
3061b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho        if (gotNumber) // i.e., Q or QQ.
3062ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        {
3063ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            // Don't want to parse the month if it is a string
3064ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            // while pattern uses numeric style: Q or QQ.
3065ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            // [We computed 'value' above.]
3066ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            cal.set(UCAL_MONTH, (value - 1) * 3);
3067ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            return pos.getIndex();
3068ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        } else {
3069ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            // count >= 3 // i.e., QQQ or QQQQ
3070ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            // Want to be able to parse both short and long forms.
3071ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            // Try count == 4 first:
3072ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            int32_t newStart = 0;
3073ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
3074fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius            if(getBooleanAttribute(UDAT_PARSE_MULTIPLE_PATTERNS_FOR_MATCH, status) || count == 4) {
3075fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius                if ((newStart = matchQuarterString(text, start, UCAL_MONTH,
3076ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                                      fSymbols->fQuarters, fSymbols->fQuartersCount, cal)) > 0)
3077fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius                    return newStart;
3078fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius            }
3079fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius            if(getBooleanAttribute(UDAT_PARSE_MULTIPLE_PATTERNS_FOR_MATCH, status) || count == 3) {
3080fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius                if ((newStart = matchQuarterString(text, start, UCAL_MONTH,
3081b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho                                          fSymbols->fShortQuarters, fSymbols->fShortQuartersCount, cal)) > 0)
3082fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius                    return newStart;
3083fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius            }
3084fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius            if (!getBooleanAttribute(UDAT_PARSE_ALLOW_NUMERIC, status))
3085b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho                return newStart;
3086b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho            // else we allowing parsing as number, below
3087fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius            if(!getBooleanAttribute(UDAT_PARSE_MULTIPLE_PATTERNS_FOR_MATCH, status))
3088fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius                return -start;
3089ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        }
3090b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho        break;
3091ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
3092ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    case UDAT_STANDALONE_QUARTER_FIELD:
3093b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho        if (gotNumber) // i.e., q or qq.
3094ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        {
3095ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            // Don't want to parse the month if it is a string
3096ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            // while pattern uses numeric style: q or q.
3097ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            // [We computed 'value' above.]
3098ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            cal.set(UCAL_MONTH, (value - 1) * 3);
3099ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            return pos.getIndex();
3100ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        } else {
3101ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            // count >= 3 // i.e., qqq or qqqq
3102ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            // Want to be able to parse both short and long forms.
3103ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            // Try count == 4 first:
3104ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            int32_t newStart = 0;
3105ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
3106fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius            if(getBooleanAttribute(UDAT_PARSE_MULTIPLE_PATTERNS_FOR_MATCH, status) || count == 4) {
3107fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius                if ((newStart = matchQuarterString(text, start, UCAL_MONTH,
3108ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                                      fSymbols->fStandaloneQuarters, fSymbols->fStandaloneQuartersCount, cal)) > 0)
3109fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius                    return newStart;
3110fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius            }
3111fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius            if(getBooleanAttribute(UDAT_PARSE_MULTIPLE_PATTERNS_FOR_MATCH, status) || count == 3) {
3112fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius                if ((newStart = matchQuarterString(text, start, UCAL_MONTH,
3113b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho                                          fSymbols->fStandaloneShortQuarters, fSymbols->fStandaloneShortQuartersCount, cal)) > 0)
3114fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius                    return newStart;
3115fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius            }
3116fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius            if (!getBooleanAttribute(UDAT_PARSE_ALLOW_NUMERIC, status))
3117b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho                return newStart;
3118b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho            // else we allowing parsing as number, below
3119fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius            if(!getBooleanAttribute(UDAT_PARSE_MULTIPLE_PATTERNS_FOR_MATCH, status))
3120fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius                return -start;
3121ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        }
3122b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho        break;
3123ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
31248393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius    case UDAT_TIMEZONE_FIELD: // 'z'
3125ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        {
3126103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius            UTimeZoneFormatStyle style = (count < 4) ? UTZFMT_STYLE_SPECIFIC_SHORT : UTZFMT_STYLE_SPECIFIC_LONG;
3127fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius            TimeZone *tz  = tzFormat()->parse(style, text, pos, tzTimeType);
3128103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius            if (tz != NULL) {
3129103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius                cal.adoptTimeZone(tz);
3130b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                return pos.getIndex();
3131ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            }
3132103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius        }
3133103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius        break;
31348393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius    case UDAT_TIMEZONE_RFC_FIELD: // 'Z'
3135103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius        {
31368393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius            UTimeZoneFormatStyle style = (count < 4) ?
31378393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius                UTZFMT_STYLE_ISO_BASIC_LOCAL_FULL : ((count == 5) ? UTZFMT_STYLE_ISO_EXTENDED_FULL: UTZFMT_STYLE_LOCALIZED_GMT);
3138fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius            TimeZone *tz  = tzFormat()->parse(style, text, pos, tzTimeType);
3139103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius            if (tz != NULL) {
3140b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho                cal.adoptTimeZone(tz);
3141103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius                return pos.getIndex();
3142b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho            }
3143103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius            return -start;
3144103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius        }
31458393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius    case UDAT_TIMEZONE_GENERIC_FIELD: // 'v'
3146103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius        {
3147103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius            UTimeZoneFormatStyle style = (count < 4) ? UTZFMT_STYLE_GENERIC_SHORT : UTZFMT_STYLE_GENERIC_LONG;
3148fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius            TimeZone *tz  = tzFormat()->parse(style, text, pos, tzTimeType);
3149103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius            if (tz != NULL) {
3150103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius                cal.adoptTimeZone(tz);
3151103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius                return pos.getIndex();
3152ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            }
3153103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius            return -start;
3154103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius        }
31558393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius    case UDAT_TIMEZONE_SPECIAL_FIELD: // 'V'
31568393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius        {
31578393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius            UTimeZoneFormatStyle style;
31588393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius            switch (count) {
31598393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius            case 1:
31608393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius                style = UTZFMT_STYLE_ZONE_ID_SHORT;
31618393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius                break;
31628393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius            case 2:
31638393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius                style = UTZFMT_STYLE_ZONE_ID;
31648393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius                break;
31658393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius            case 3:
31668393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius                style = UTZFMT_STYLE_EXEMPLAR_LOCATION;
31678393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius                break;
31688393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius            default:
31698393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius                style = UTZFMT_STYLE_GENERIC_LOCATION;
31708393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius                break;
31718393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius            }
3172fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius            TimeZone *tz  = tzFormat()->parse(style, text, pos, tzTimeType);
31738393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius            if (tz != NULL) {
31748393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius                cal.adoptTimeZone(tz);
31758393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius                return pos.getIndex();
31768393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius            }
31778393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius            return -start;
31788393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius        }
31798393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius    case UDAT_TIMEZONE_LOCALIZED_GMT_OFFSET_FIELD: // 'O'
31808393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius        {
31818393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius            UTimeZoneFormatStyle style = (count < 4) ? UTZFMT_STYLE_LOCALIZED_GMT_SHORT : UTZFMT_STYLE_LOCALIZED_GMT;
3182fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius            TimeZone *tz  = tzFormat()->parse(style, text, pos, tzTimeType);
31838393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius            if (tz != NULL) {
31848393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius                cal.adoptTimeZone(tz);
31858393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius                return pos.getIndex();
31868393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius            }
31878393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius            return -start;
31888393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius        }
31898393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius    case UDAT_TIMEZONE_ISO_FIELD: // 'X'
3190103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius        {
31918393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius            UTimeZoneFormatStyle style;
31928393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius            switch (count) {
31938393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius            case 1:
31948393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius                style = UTZFMT_STYLE_ISO_BASIC_SHORT;
31958393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius                break;
31968393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius            case 2:
31978393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius                style = UTZFMT_STYLE_ISO_BASIC_FIXED;
31988393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius                break;
31998393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius            case 3:
32008393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius                style = UTZFMT_STYLE_ISO_EXTENDED_FIXED;
32018393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius                break;
32028393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius            case 4:
32038393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius                style = UTZFMT_STYLE_ISO_BASIC_FULL;
32048393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius                break;
32058393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius            default:
32068393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius                style = UTZFMT_STYLE_ISO_EXTENDED_FULL;
32078393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius                break;
32088393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius            }
3209fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius            TimeZone *tz  = tzFormat()->parse(style, text, pos, tzTimeType);
32108393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius            if (tz != NULL) {
32118393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius                cal.adoptTimeZone(tz);
32128393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius                return pos.getIndex();
32138393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius            }
32148393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius            return -start;
32158393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius        }
32168393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius    case UDAT_TIMEZONE_ISO_LOCAL_FIELD: // 'x'
32178393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius        {
32188393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius            UTimeZoneFormatStyle style;
32198393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius            switch (count) {
32208393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius            case 1:
32218393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius                style = UTZFMT_STYLE_ISO_BASIC_LOCAL_SHORT;
32228393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius                break;
32238393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius            case 2:
32248393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius                style = UTZFMT_STYLE_ISO_BASIC_LOCAL_FIXED;
32258393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius                break;
32268393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius            case 3:
32278393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius                style = UTZFMT_STYLE_ISO_EXTENDED_LOCAL_FIXED;
32288393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius                break;
32298393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius            case 4:
32308393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius                style = UTZFMT_STYLE_ISO_BASIC_LOCAL_FULL;
32318393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius                break;
32328393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius            default:
32338393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius                style = UTZFMT_STYLE_ISO_EXTENDED_LOCAL_FULL;
32348393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius                break;
32358393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius            }
3236fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius            TimeZone *tz  = tzFormat()->parse(style, text, pos, tzTimeType);
3237103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius            if (tz != NULL) {
323885bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho                cal.adoptTimeZone(tz);
3239103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius                return pos.getIndex();
324085bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho            }
3241b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru            return -start;
3242ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        }
32431b7d32f919554dda9c193b32188251337bc756f1Fredrik Roubert    case UDAT_TIME_SEPARATOR_FIELD: // ':'
32441b7d32f919554dda9c193b32188251337bc756f1Fredrik Roubert        {
32451b7d32f919554dda9c193b32188251337bc756f1Fredrik Roubert            static const UChar def_sep = DateFormatSymbols::DEFAULT_TIME_SEPARATOR;
32461b7d32f919554dda9c193b32188251337bc756f1Fredrik Roubert            static const UChar alt_sep = DateFormatSymbols::ALTERNATE_TIME_SEPARATOR;
32471b7d32f919554dda9c193b32188251337bc756f1Fredrik Roubert
32481b7d32f919554dda9c193b32188251337bc756f1Fredrik Roubert            // Try matching a time separator.
32491b7d32f919554dda9c193b32188251337bc756f1Fredrik Roubert            int32_t count = 1;
32501b7d32f919554dda9c193b32188251337bc756f1Fredrik Roubert            UnicodeString data[3];
32511b7d32f919554dda9c193b32188251337bc756f1Fredrik Roubert            fSymbols->getTimeSeparatorString(data[0]);
32521b7d32f919554dda9c193b32188251337bc756f1Fredrik Roubert
32531b7d32f919554dda9c193b32188251337bc756f1Fredrik Roubert            // Add the default, if different from the locale.
32541b7d32f919554dda9c193b32188251337bc756f1Fredrik Roubert            if (data[0].compare(&def_sep, 1) != 0) {
32551b7d32f919554dda9c193b32188251337bc756f1Fredrik Roubert                data[count++].setTo(def_sep);
32561b7d32f919554dda9c193b32188251337bc756f1Fredrik Roubert            }
32571b7d32f919554dda9c193b32188251337bc756f1Fredrik Roubert
32581b7d32f919554dda9c193b32188251337bc756f1Fredrik Roubert            // If lenient, add also the alternate, if different from the locale.
32591b7d32f919554dda9c193b32188251337bc756f1Fredrik Roubert            if (isLenient() && data[0].compare(&alt_sep, 1) != 0) {
32601b7d32f919554dda9c193b32188251337bc756f1Fredrik Roubert                data[count++].setTo(alt_sep);
32611b7d32f919554dda9c193b32188251337bc756f1Fredrik Roubert            }
32621b7d32f919554dda9c193b32188251337bc756f1Fredrik Roubert
32631b7d32f919554dda9c193b32188251337bc756f1Fredrik Roubert            return matchString(text, start, UCAL_FIELD_COUNT /* => nothing to set */, data, count, NULL, cal);
32641b7d32f919554dda9c193b32188251337bc756f1Fredrik Roubert        }
3265ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
3266ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    default:
3267ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        // Handle "generic" fields
3268b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho        // this is now handled below, outside the switch block
3269b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho        break;
3270b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho    }
3271b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho    // Handle "generic" fields:
3272b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho    // switch default case now handled here (outside switch block) to allow
3273b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho    // parsing of some string fields as digits for lenient case
3274b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho
3275b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho    int32_t parseStart = pos.getIndex();
3276b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho    const UnicodeString* src;
3277b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho    if (obeyCount) {
3278b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho        if ((start+count) > text.length()) {
3279b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho            return -start;
3280b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho        }
3281b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho        text.extractBetween(0, start + count, temp);
3282b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho        src = &temp;
3283b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho    } else {
3284b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho        src = &text;
3285b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho    }
3286b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho    parseInt(*src, number, pos, allowNegative,currentNumberFormat);
3287b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho    if (pos.getIndex() != parseStart) {
3288b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho        int32_t value = number.getLong();
3289b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho
3290b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho        // Don't need suffix processing here (as in number processing at the beginning of the function);
3291b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho        // the new fields being handled as numeric values (month, weekdays, quarters) should not have suffixes.
3292b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho
329359d709d503bab6e2b61931737e662dd293b40578ccornelius        if (!getBooleanAttribute(UDAT_PARSE_ALLOW_NUMERIC, status)) {
3294b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho            // Check the range of the value
3295b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho            int32_t bias = gFieldRangeBias[patternCharIndex];
3296b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho            if (bias >= 0 && (value > cal.getMaximum(field) + bias || value < cal.getMinimum(field) + bias)) {
3297ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                return -start;
3298ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            }
3299ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        }
3300b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho
3301b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho        // For the following, need to repeat some of the "if (gotNumber)" code above:
3302b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho        // UDAT_[STANDALONE_]MONTH_FIELD, UDAT_DOW_LOCAL_FIELD, UDAT_STANDALONE_DAY_FIELD,
3303b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho        // UDAT_[STANDALONE_]QUARTER_FIELD
3304b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho        switch (patternCharIndex) {
3305b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho        case UDAT_MONTH_FIELD:
3306b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho            // See notes under UDAT_MONTH_FIELD case above
3307b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho            if (!strcmp(cal.getType(),"hebrew")) {
3308b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho                HebrewCalendar *hc = (HebrewCalendar*)&cal;
3309b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho                if (cal.isSet(UCAL_YEAR)) {
3310b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho                   UErrorCode status = U_ZERO_ERROR;
3311b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho                   if (!hc->isLeapYear(hc->get(UCAL_YEAR,status)) && value >= 6) {
3312b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho                       cal.set(UCAL_MONTH, value);
3313b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho                   } else {
3314b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho                       cal.set(UCAL_MONTH, value - 1);
3315b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho                   }
3316b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho                } else {
3317b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho                    saveHebrewMonth = value;
3318b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho                }
3319b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho            } else {
3320b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho                cal.set(UCAL_MONTH, value - 1);
3321b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho            }
3322b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho            break;
3323b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho        case UDAT_STANDALONE_MONTH_FIELD:
3324b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho            cal.set(UCAL_MONTH, value - 1);
3325b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho            break;
3326b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho        case UDAT_DOW_LOCAL_FIELD:
3327b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho        case UDAT_STANDALONE_DAY_FIELD:
3328b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho            cal.set(UCAL_DOW_LOCAL, value);
3329b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho            break;
3330b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho        case UDAT_QUARTER_FIELD:
3331b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho        case UDAT_STANDALONE_QUARTER_FIELD:
3332b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho             cal.set(UCAL_MONTH, (value - 1) * 3);
3333b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho             break;
3334fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius        case UDAT_RELATED_YEAR_FIELD:
3335fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius            cal.setRelatedYear(value);
3336fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius            break;
3337b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho        default:
3338b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho            cal.set(field, value);
3339b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho            break;
3340ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        }
3341b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho        return pos.getIndex();
3342ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    }
3343b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho    return -start;
3344ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru}
3345ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
3346ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru/**
3347ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru * Parse an integer using fNumberFormat.  This method is semantically
3348ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru * const, but actually may modify fNumberFormat.
3349ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru */
3350ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queruvoid SimpleDateFormat::parseInt(const UnicodeString& text,
3351ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                                Formattable& number,
3352ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                                ParsePosition& pos,
335385bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho                                UBool allowNegative,
335485bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho                                NumberFormat *fmt) const {
335585bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    parseInt(text, number, -1, pos, allowNegative,fmt);
3356b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru}
3357b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
3358b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru/**
3359b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * Parse an integer using fNumberFormat up to maxDigits.
3360b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru */
3361b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queruvoid SimpleDateFormat::parseInt(const UnicodeString& text,
3362b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                                Formattable& number,
3363b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                                int32_t maxDigits,
3364b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                                ParsePosition& pos,
336585bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho                                UBool allowNegative,
336685bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho                                NumberFormat *fmt) const {
3367ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    UnicodeString oldPrefix;
3368ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    DecimalFormat* df = NULL;
336927f654740f2a26ad62a5c155af9199af9e69b889claireho    if (!allowNegative && (df = dynamic_cast<DecimalFormat*>(fmt)) != NULL) {
3370ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        df->getNegativePrefix(oldPrefix);
3371b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho        df->setNegativePrefix(UnicodeString(TRUE, SUPPRESS_NEGATIVE_PREFIX, -1));
3372ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    }
3373b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    int32_t oldPos = pos.getIndex();
337485bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    fmt->parse(text, number, pos);
3375ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    if (df != NULL) {
3376ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        df->setNegativePrefix(oldPrefix);
3377ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    }
3378b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
3379b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    if (maxDigits > 0) {
3380b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        // adjust the result to fit into
3381b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        // the maxDigits and move the position back
3382b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        int32_t nDigits = pos.getIndex() - oldPos;
3383b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        if (nDigits > maxDigits) {
3384b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru            int32_t val = number.getLong();
3385b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru            nDigits -= maxDigits;
3386b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru            while (nDigits > 0) {
3387b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                val /= 10;
3388b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                nDigits--;
3389b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru            }
3390b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru            pos.setIndex(oldPos + maxDigits);
3391b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru            number.setLong(val);
3392b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        }
3393b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    }
3394ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru}
3395ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
3396ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru//----------------------------------------------------------------------
3397ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
3398ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queruvoid SimpleDateFormat::translatePattern(const UnicodeString& originalPattern,
3399ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                                        UnicodeString& translatedPattern,
3400ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                                        const UnicodeString& from,
3401ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                                        const UnicodeString& to,
3402ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                                        UErrorCode& status)
3403ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru{
34041b7d32f919554dda9c193b32188251337bc756f1Fredrik Roubert    // run through the pattern and convert any pattern symbols from the version
34051b7d32f919554dda9c193b32188251337bc756f1Fredrik Roubert    // in "from" to the corresponding character ion "to".  This code takes
34061b7d32f919554dda9c193b32188251337bc756f1Fredrik Roubert    // quoted strings into account (it doesn't try to translate them), and it signals
34071b7d32f919554dda9c193b32188251337bc756f1Fredrik Roubert    // an error if a particular "pattern character" doesn't appear in "from".
34081b7d32f919554dda9c193b32188251337bc756f1Fredrik Roubert    // Depending on the values of "from" and "to" this can convert from generic
34091b7d32f919554dda9c193b32188251337bc756f1Fredrik Roubert    // to localized patterns or localized to generic.
34101b7d32f919554dda9c193b32188251337bc756f1Fredrik Roubert    if (U_FAILURE(status)) {
34111b7d32f919554dda9c193b32188251337bc756f1Fredrik Roubert        return;
3412ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    }
34131b7d32f919554dda9c193b32188251337bc756f1Fredrik Roubert
34141b7d32f919554dda9c193b32188251337bc756f1Fredrik Roubert    translatedPattern.remove();
34151b7d32f919554dda9c193b32188251337bc756f1Fredrik Roubert    UBool inQuote = FALSE;
34161b7d32f919554dda9c193b32188251337bc756f1Fredrik Roubert    for (int32_t i = 0; i < originalPattern.length(); ++i) {
34171b7d32f919554dda9c193b32188251337bc756f1Fredrik Roubert        UChar c = originalPattern[i];
34181b7d32f919554dda9c193b32188251337bc756f1Fredrik Roubert        if (inQuote) {
34191b7d32f919554dda9c193b32188251337bc756f1Fredrik Roubert            if (c == QUOTE) {
34201b7d32f919554dda9c193b32188251337bc756f1Fredrik Roubert                inQuote = FALSE;
34211b7d32f919554dda9c193b32188251337bc756f1Fredrik Roubert            }
34221b7d32f919554dda9c193b32188251337bc756f1Fredrik Roubert        } else {
34231b7d32f919554dda9c193b32188251337bc756f1Fredrik Roubert            if (c == QUOTE) {
34241b7d32f919554dda9c193b32188251337bc756f1Fredrik Roubert                inQuote = TRUE;
34251b7d32f919554dda9c193b32188251337bc756f1Fredrik Roubert            } else if (isSyntaxChar(c)) {
34261b7d32f919554dda9c193b32188251337bc756f1Fredrik Roubert                int32_t ci = from.indexOf(c);
34271b7d32f919554dda9c193b32188251337bc756f1Fredrik Roubert                if (ci == -1) {
34281b7d32f919554dda9c193b32188251337bc756f1Fredrik Roubert                    status = U_INVALID_FORMAT_ERROR;
34291b7d32f919554dda9c193b32188251337bc756f1Fredrik Roubert                    return;
34301b7d32f919554dda9c193b32188251337bc756f1Fredrik Roubert                }
34311b7d32f919554dda9c193b32188251337bc756f1Fredrik Roubert                c = to[ci];
34321b7d32f919554dda9c193b32188251337bc756f1Fredrik Roubert            }
34331b7d32f919554dda9c193b32188251337bc756f1Fredrik Roubert        }
34341b7d32f919554dda9c193b32188251337bc756f1Fredrik Roubert        translatedPattern += c;
34351b7d32f919554dda9c193b32188251337bc756f1Fredrik Roubert    }
34361b7d32f919554dda9c193b32188251337bc756f1Fredrik Roubert    if (inQuote) {
34371b7d32f919554dda9c193b32188251337bc756f1Fredrik Roubert        status = U_INVALID_FORMAT_ERROR;
34381b7d32f919554dda9c193b32188251337bc756f1Fredrik Roubert        return;
3439ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    }
3440ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru}
3441ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
3442ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru//----------------------------------------------------------------------
3443ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
3444ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste QueruUnicodeString&
3445ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste QueruSimpleDateFormat::toPattern(UnicodeString& result) const
3446ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru{
3447ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    result = fPattern;
3448ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    return result;
3449ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru}
3450ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
3451ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru//----------------------------------------------------------------------
3452ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
3453ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste QueruUnicodeString&
3454ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste QueruSimpleDateFormat::toLocalizedPattern(UnicodeString& result,
3455ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                                     UErrorCode& status) const
3456ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru{
3457b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho    translatePattern(fPattern, result,
3458b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho                     UnicodeString(DateFormatSymbols::getPatternUChars()),
3459b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho                     fSymbols->fLocalPatternChars, status);
3460ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    return result;
3461ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru}
3462ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
3463ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru//----------------------------------------------------------------------
3464ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
3465ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queruvoid
3466ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste QueruSimpleDateFormat::applyPattern(const UnicodeString& pattern)
3467ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru{
3468ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    fPattern = pattern;
3469ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru}
3470ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
3471ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru//----------------------------------------------------------------------
3472ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
3473ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queruvoid
3474ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste QueruSimpleDateFormat::applyLocalizedPattern(const UnicodeString& pattern,
3475ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                                        UErrorCode &status)
3476ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru{
3477b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho    translatePattern(pattern, fPattern,
3478b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho                     fSymbols->fLocalPatternChars,
3479b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho                     UnicodeString(DateFormatSymbols::getPatternUChars()), status);
3480ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru}
3481ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
3482ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru//----------------------------------------------------------------------
3483ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
3484ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queruconst DateFormatSymbols*
3485ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste QueruSimpleDateFormat::getDateFormatSymbols() const
3486ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru{
3487ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    return fSymbols;
3488ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru}
3489ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
3490ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru//----------------------------------------------------------------------
3491ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
3492ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queruvoid
3493ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste QueruSimpleDateFormat::adoptDateFormatSymbols(DateFormatSymbols* newFormatSymbols)
3494ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru{
3495ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    delete fSymbols;
3496ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    fSymbols = newFormatSymbols;
3497ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru}
3498ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
3499ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru//----------------------------------------------------------------------
3500ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queruvoid
3501ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste QueruSimpleDateFormat::setDateFormatSymbols(const DateFormatSymbols& newFormatSymbols)
3502ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru{
3503ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    delete fSymbols;
3504ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    fSymbols = new DateFormatSymbols(newFormatSymbols);
3505ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru}
3506ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
3507103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius//----------------------------------------------------------------------
3508103e9ffba2cba345d0078eb8b8db33249f81840aCraig Corneliusconst TimeZoneFormat*
3509103e9ffba2cba345d0078eb8b8db33249f81840aCraig CorneliusSimpleDateFormat::getTimeZoneFormat(void) const {
3510103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius    return (const TimeZoneFormat*)tzFormat();
3511103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius}
3512103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius
3513103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius//----------------------------------------------------------------------
3514103e9ffba2cba345d0078eb8b8db33249f81840aCraig Corneliusvoid
3515103e9ffba2cba345d0078eb8b8db33249f81840aCraig CorneliusSimpleDateFormat::adoptTimeZoneFormat(TimeZoneFormat* timeZoneFormatToAdopt)
3516103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius{
3517103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius    delete fTimeZoneFormat;
3518103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius    fTimeZoneFormat = timeZoneFormatToAdopt;
3519103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius}
3520103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius
3521103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius//----------------------------------------------------------------------
3522103e9ffba2cba345d0078eb8b8db33249f81840aCraig Corneliusvoid
3523103e9ffba2cba345d0078eb8b8db33249f81840aCraig CorneliusSimpleDateFormat::setTimeZoneFormat(const TimeZoneFormat& newTimeZoneFormat)
3524103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius{
3525103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius    delete fTimeZoneFormat;
3526103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius    fTimeZoneFormat = new TimeZoneFormat(newTimeZoneFormat);
3527103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius}
3528ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
3529ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru//----------------------------------------------------------------------
3530ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
3531ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
3532ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queruvoid SimpleDateFormat::adoptCalendar(Calendar* calendarToAdopt)
3533ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru{
3534ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru  UErrorCode status = U_ZERO_ERROR;
35351b7d32f919554dda9c193b32188251337bc756f1Fredrik Roubert  Locale calLocale(fLocale);
35361b7d32f919554dda9c193b32188251337bc756f1Fredrik Roubert  calLocale.setKeywordValue("calendar", calendarToAdopt->getType(), status);
35371b7d32f919554dda9c193b32188251337bc756f1Fredrik Roubert  DateFormatSymbols *newSymbols =
35381b7d32f919554dda9c193b32188251337bc756f1Fredrik Roubert          DateFormatSymbols::createForLocale(calLocale, status);
35391b7d32f919554dda9c193b32188251337bc756f1Fredrik Roubert  if (U_FAILURE(status)) {
35401b7d32f919554dda9c193b32188251337bc756f1Fredrik Roubert      return;
35411b7d32f919554dda9c193b32188251337bc756f1Fredrik Roubert  }
3542ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru  DateFormat::adoptCalendar(calendarToAdopt);
354350294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho  delete fSymbols;
35441b7d32f919554dda9c193b32188251337bc756f1Fredrik Roubert  fSymbols = newSymbols;
3545ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru  initializeDefaultCentury();  // we need a new century (possibly)
3546ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru}
3547ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
354885bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho
354985bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho//----------------------------------------------------------------------
355085bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho
355185bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho
3552fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius// override the DateFormat implementation in order to
3553fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius// lazily initialize fCapitalizationBrkIter
3554fceb39872958b9fa2505e63f8b8699a9e0f882f4ccorneliusvoid
3555fceb39872958b9fa2505e63f8b8699a9e0f882f4ccorneliusSimpleDateFormat::setContext(UDisplayContext value, UErrorCode& status)
3556103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius{
3557fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius    DateFormat::setContext(value, status);
3558fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius#if !UCONFIG_NO_BREAK_ITERATION
3559fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius    if (U_SUCCESS(status)) {
3560fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius        if ( fCapitalizationBrkIter == NULL && (value==UDISPCTX_CAPITALIZATION_FOR_BEGINNING_OF_SENTENCE ||
3561fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius                value==UDISPCTX_CAPITALIZATION_FOR_UI_LIST_OR_MENU || value==UDISPCTX_CAPITALIZATION_FOR_STANDALONE) ) {
3562fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius            UErrorCode status = U_ZERO_ERROR;
3563fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius            fCapitalizationBrkIter = BreakIterator::createSentenceInstance(fLocale, status);
3564fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius            if (U_FAILURE(status)) {
3565fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius                delete fCapitalizationBrkIter;
3566fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius                fCapitalizationBrkIter = NULL;
3567fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius            }
3568fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius        }
3569103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius    }
3570fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius#endif
3571103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius}
3572103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius
3573103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius
3574103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius//----------------------------------------------------------------------
3575103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius
3576103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius
357785bf2e2fbc60a9f938064abc8127d61da7d19882Claire HoUBool
357885bf2e2fbc60a9f938064abc8127d61da7d19882Claire HoSimpleDateFormat::isFieldUnitIgnored(UCalendarDateFields field) const {
357985bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    return isFieldUnitIgnored(fPattern, field);
358085bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho}
358185bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho
358285bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho
358385bf2e2fbc60a9f938064abc8127d61da7d19882Claire HoUBool
358450294ead5e5d23f5bbfed76e00e6b510bd41eee1clairehoSimpleDateFormat::isFieldUnitIgnored(const UnicodeString& pattern,
358585bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho                                     UCalendarDateFields field) {
358685bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    int32_t fieldLevel = fgCalendarFieldToLevel[field];
358785bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    int32_t level;
358885bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    UChar ch;
358985bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    UBool inQuote = FALSE;
359085bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    UChar prevCh = 0;
359185bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    int32_t count = 0;
359285bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho
359385bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    for (int32_t i = 0; i < pattern.length(); ++i) {
359485bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho        ch = pattern[i];
359585bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho        if (ch != prevCh && count > 0) {
35961b7d32f919554dda9c193b32188251337bc756f1Fredrik Roubert            level = getLevelFromChar(prevCh);
359785bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho            // the larger the level, the smaller the field unit.
35981b7d32f919554dda9c193b32188251337bc756f1Fredrik Roubert            if (fieldLevel <= level) {
359985bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho                return FALSE;
360085bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho            }
360185bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho            count = 0;
360285bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho        }
360385bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho        if (ch == QUOTE) {
360485bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho            if ((i+1) < pattern.length() && pattern[i+1] == QUOTE) {
360585bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho                ++i;
360685bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho            } else {
360785bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho                inQuote = ! inQuote;
360885bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho            }
360950294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho        }
36101b7d32f919554dda9c193b32188251337bc756f1Fredrik Roubert        else if (!inQuote && isSyntaxChar(ch)) {
361185bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho            prevCh = ch;
361285bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho            ++count;
361385bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho        }
361485bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    }
36151b7d32f919554dda9c193b32188251337bc756f1Fredrik Roubert    if (count > 0) {
361685bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho        // last item
36171b7d32f919554dda9c193b32188251337bc756f1Fredrik Roubert        level = getLevelFromChar(prevCh);
36181b7d32f919554dda9c193b32188251337bc756f1Fredrik Roubert        if (fieldLevel <= level) {
36191b7d32f919554dda9c193b32188251337bc756f1Fredrik Roubert            return FALSE;
36201b7d32f919554dda9c193b32188251337bc756f1Fredrik Roubert        }
362185bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    }
362285bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    return TRUE;
362385bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho}
362485bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho
362585bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho//----------------------------------------------------------------------
362685bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho
362785bf2e2fbc60a9f938064abc8127d61da7d19882Claire Hoconst Locale&
362885bf2e2fbc60a9f938064abc8127d61da7d19882Claire HoSimpleDateFormat::getSmpFmtLocale(void) const {
362985bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    return fLocale;
363085bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho}
363185bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho
363285bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho//----------------------------------------------------------------------
363385bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho
363450294ead5e5d23f5bbfed76e00e6b510bd41eee1clairehoint32_t
363585bf2e2fbc60a9f938064abc8127d61da7d19882Claire HoSimpleDateFormat::checkIntSuffix(const UnicodeString& text, int32_t start,
363685bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho                                 int32_t patLoc, UBool isNegative) const {
363785bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    // local variables
363885bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    UnicodeString suf;
363985bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    int32_t patternMatch;
364085bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    int32_t textPreMatch;
364185bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    int32_t textPostMatch;
364285bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho
364385bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    // check that we are still in range
364485bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    if ( (start > text.length()) ||
364585bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho         (start < 0) ||
364685bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho         (patLoc < 0) ||
364785bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho         (patLoc > fPattern.length())) {
364885bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho        // out of range, don't advance location in text
364985bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho        return start;
365085bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    }
365185bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho
365285bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    // get the suffix
365327f654740f2a26ad62a5c155af9199af9e69b889claireho    DecimalFormat* decfmt = dynamic_cast<DecimalFormat*>(fNumberFormat);
365427f654740f2a26ad62a5c155af9199af9e69b889claireho    if (decfmt != NULL) {
365585bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho        if (isNegative) {
365627f654740f2a26ad62a5c155af9199af9e69b889claireho            suf = decfmt->getNegativeSuffix(suf);
365785bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho        }
365885bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho        else {
365927f654740f2a26ad62a5c155af9199af9e69b889claireho            suf = decfmt->getPositiveSuffix(suf);
366085bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho        }
366185bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    }
366250294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho
366385bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    // check for suffix
366485bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    if (suf.length() <= 0) {
366585bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho        return start;
366685bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    }
366785bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho
366885bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    // check suffix will be encountered in the pattern
366985bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    patternMatch = compareSimpleAffix(suf,fPattern,patLoc);
367085bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho
367185bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    // check if a suffix will be encountered in the text
367285bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    textPreMatch = compareSimpleAffix(suf,text,start);
367385bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho
367485bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    // check if a suffix was encountered in the text
367585bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    textPostMatch = compareSimpleAffix(suf,text,start-suf.length());
367685bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho
367785bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    // check for suffix match
367885bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    if ((textPreMatch >= 0) && (patternMatch >= 0) && (textPreMatch == patternMatch)) {
367985bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho        return start;
368085bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    }
368185bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    else if ((textPostMatch >= 0) && (patternMatch >= 0) && (textPostMatch == patternMatch)) {
368285bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho        return  start - suf.length();
368385bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    }
368485bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho
368585bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    // should not get here
368685bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    return start;
368785bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho}
368885bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho
368985bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho//----------------------------------------------------------------------
369085bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho
369185bf2e2fbc60a9f938064abc8127d61da7d19882Claire Hoint32_t
369250294ead5e5d23f5bbfed76e00e6b510bd41eee1clairehoSimpleDateFormat::compareSimpleAffix(const UnicodeString& affix,
369350294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho                   const UnicodeString& input,
369485bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho                   int32_t pos) const {
369585bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    int32_t start = pos;
369685bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    for (int32_t i=0; i<affix.length(); ) {
369785bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho        UChar32 c = affix.char32At(i);
369885bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho        int32_t len = U16_LENGTH(c);
3699b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho        if (PatternProps::isWhiteSpace(c)) {
370085bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho            // We may have a pattern like: \u200F \u0020
370185bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho            //        and input text like: \u200F \u0020
3702b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho            // Note that U+200F and U+0020 are Pattern_White_Space but only
370385bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho            // U+0020 is UWhiteSpace.  So we have to first do a direct
3704b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho            // match of the run of Pattern_White_Space in the pattern,
370585bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho            // then match any extra characters.
370685bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho            UBool literalMatch = FALSE;
370785bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho            while (pos < input.length() &&
370885bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho                   input.char32At(pos) == c) {
370985bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho                literalMatch = TRUE;
371085bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho                i += len;
371185bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho                pos += len;
371285bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho                if (i == affix.length()) {
371385bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho                    break;
371485bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho                }
371585bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho                c = affix.char32At(i);
371685bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho                len = U16_LENGTH(c);
3717b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho                if (!PatternProps::isWhiteSpace(c)) {
371885bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho                    break;
371985bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho                }
372085bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho            }
372185bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho
372285bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho            // Advance over run in pattern
3723b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho            i = skipPatternWhiteSpace(affix, i);
372485bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho
372585bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho            // Advance over run in input text
372685bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho            // Must see at least one white space char in input,
372785bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho            // unless we've already matched some characters literally.
372885bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho            int32_t s = pos;
372985bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho            pos = skipUWhiteSpace(input, pos);
373085bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho            if (pos == s && !literalMatch) {
373185bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho                return -1;
373285bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho            }
373385bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho
373485bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho            // If we skip UWhiteSpace in the input text, we need to skip it in the pattern.
373585bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho            // Otherwise, the previous lines may have skipped over text (such as U+00A0) that
373685bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho            // is also in the affix.
373785bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho            i = skipUWhiteSpace(affix, i);
373885bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho        } else {
373985bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho            if (pos < input.length() &&
374085bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho                input.char32At(pos) == c) {
374185bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho                i += len;
374285bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho                pos += len;
374385bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho            } else {
374485bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho                return -1;
374585bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho            }
374685bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho        }
374785bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    }
374885bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    return pos - start;
374985bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho}
375085bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho
375185bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho//----------------------------------------------------------------------
375285bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho
375350294ead5e5d23f5bbfed76e00e6b510bd41eee1clairehoint32_t
3754b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2clairehoSimpleDateFormat::skipPatternWhiteSpace(const UnicodeString& text, int32_t pos) const {
3755b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho    const UChar* s = text.getBuffer();
3756b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho    return (int32_t)(PatternProps::skipWhiteSpace(s + pos, text.length() - pos) - s);
375785bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho}
375885bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho
375985bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho//----------------------------------------------------------------------
376085bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho
376150294ead5e5d23f5bbfed76e00e6b510bd41eee1clairehoint32_t
376285bf2e2fbc60a9f938064abc8127d61da7d19882Claire HoSimpleDateFormat::skipUWhiteSpace(const UnicodeString& text, int32_t pos) const {
376385bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    while (pos < text.length()) {
376485bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho        UChar32 c = text.char32At(pos);
376585bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho        if (!u_isUWhiteSpace(c)) {
376685bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho            break;
376785bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho        }
376885bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho        pos += U16_LENGTH(c);
376985bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    }
377085bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    return pos;
377185bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho}
377285bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho
3773b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho//----------------------------------------------------------------------
3774b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho
3775b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho// Lazy TimeZoneFormat instantiation, semantically const.
3776b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2clairehoTimeZoneFormat *
3777b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2clairehoSimpleDateFormat::tzFormat() const {
3778b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho    if (fTimeZoneFormat == NULL) {
3779b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho        umtx_lock(&LOCK);
3780b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho        {
3781b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho            if (fTimeZoneFormat == NULL) {
3782b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho                UErrorCode status = U_ZERO_ERROR;
3783b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho                TimeZoneFormat *tzfmt = TimeZoneFormat::createInstance(fLocale, status);
3784103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius                if (U_FAILURE(status)) {
3785103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius                    return NULL;
3786103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius                }
3787b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho
3788b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho                const_cast<SimpleDateFormat *>(this)->fTimeZoneFormat = tzfmt;
3789b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho            }
3790b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho        }
3791b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho        umtx_unlock(&LOCK);
3792b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho    }
3793b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho    return fTimeZoneFormat;
3794b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho}
3795103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius
3796ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste QueruU_NAMESPACE_END
3797ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
3798ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru#endif /* #if !UCONFIG_NO_FORMATTING */
3799ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
3800ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru//eof
3801