1ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru/*
2ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru*******************************************************************************
3fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius* Copyright (C) 1997-2014, 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
33ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru#include "unicode/smpdtfmt.h"
34ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru#include "unicode/dtfmtsym.h"
35ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru#include "unicode/ures.h"
36ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru#include "unicode/msgfmt.h"
37ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru#include "unicode/calendar.h"
38ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru#include "unicode/gregocal.h"
39ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru#include "unicode/timezone.h"
40ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru#include "unicode/decimfmt.h"
41ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru#include "unicode/dcfmtsym.h"
42ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru#include "unicode/uchar.h"
43b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho#include "unicode/uniset.h"
44ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru#include "unicode/ustring.h"
45b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#include "unicode/basictz.h"
46b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#include "unicode/simpletz.h"
47b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#include "unicode/rbtz.h"
48103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius#include "unicode/tzfmt.h"
49103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius#include "unicode/utf16.h"
50b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#include "unicode/vtzone.h"
5154dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius#include "unicode/udisplaycontext.h"
52fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius#include "unicode/brkiter.h"
53b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#include "olsontz.h"
54b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho#include "patternprops.h"
5550294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho#include "fphdlimp.h"
5650294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho#include "gregoimp.h"
5750294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho#include "hebrwcal.h"
58ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru#include "cstring.h"
59ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru#include "uassert.h"
60b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#include "cmemory.h"
61b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#include "umutex.h"
62ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru#include <float.h>
63b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho#include "smpdtfst.h"
64ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
65ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru#if defined( U_DEBUG_CALSVC ) || defined (U_DEBUG_CAL)
66ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru#include <stdio.h>
67ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru#endif
68ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
69ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru// *****************************************************************************
70ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru// class SimpleDateFormat
71ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru// *****************************************************************************
72ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
73ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste QueruU_NAMESPACE_BEGIN
74ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
7585bf2e2fbc60a9f938064abc8127d61da7d19882Claire Hostatic const UChar PATTERN_CHAR_BASE = 0x40;
7685bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho
77ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru/**
78ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru * Last-resort string to use for "GMT" when constructing time zone strings.
79ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru */
80ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru// For time zones that have no names, use strings GMT+minutes and
81ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru// GMT-minutes. For instance, in France the time zone is GMT+60.
82ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru// Also accepted are GMT+H:MM or GMT-H:MM.
8354dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius// Currently not being used
8454dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius//static const UChar gGmt[]      = {0x0047, 0x004D, 0x0054, 0x0000};         // "GMT"
8554dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius//static const UChar gGmtPlus[]  = {0x0047, 0x004D, 0x0054, 0x002B, 0x0000}; // "GMT+"
8654dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius//static const UChar gGmtMinus[] = {0x0047, 0x004D, 0x0054, 0x002D, 0x0000}; // "GMT-"
8754dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius//static const UChar gDefGmtPat[]       = {0x0047, 0x004D, 0x0054, 0x007B, 0x0030, 0x007D, 0x0000}; /* GMT{0} */
8854dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius//static const UChar gDefGmtNegHmsPat[] = {0x002D, 0x0048, 0x0048, 0x003A, 0x006D, 0x006D, 0x003A, 0x0073, 0x0073, 0x0000}; /* -HH:mm:ss */
8954dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius//static const UChar gDefGmtNegHmPat[]  = {0x002D, 0x0048, 0x0048, 0x003A, 0x006D, 0x006D, 0x0000}; /* -HH:mm */
9054dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius//static const UChar gDefGmtPosHmsPat[] = {0x002B, 0x0048, 0x0048, 0x003A, 0x006D, 0x006D, 0x003A, 0x0073, 0x0073, 0x0000}; /* +HH:mm:ss */
9154dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius//static const UChar gDefGmtPosHmPat[]  = {0x002B, 0x0048, 0x0048, 0x003A, 0x006D, 0x006D, 0x0000}; /* +HH:mm */
9254dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius//static const UChar gUt[]       = {0x0055, 0x0054, 0x0000};  // "UT"
9354dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius//static const UChar gUtc[]      = {0x0055, 0x0054, 0x0043, 0x0000};  // "UT"
9485bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho
95b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Querutypedef enum GmtPatSize {
96b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    kGmtLen = 3,
97b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    kGmtPatLen = 6,
98b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    kNegHmsLen = 9,
99b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    kNegHmLen = 6,
100b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    kPosHmsLen = 9,
10185bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    kPosHmLen = 6,
10285bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    kUtLen = 2,
10385bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    kUtcLen = 3
104b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru} GmtPatSize;
105ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
10685bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho// Stuff needed for numbering system overrides
10785bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho
10885bf2e2fbc60a9f938064abc8127d61da7d19882Claire Hotypedef enum OvrStrType {
10985bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    kOvrStrDate = 0,
11085bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    kOvrStrTime = 1,
11185bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    kOvrStrBoth = 2
11285bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho} OvrStrType;
11385bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho
11485bf2e2fbc60a9f938064abc8127d61da7d19882Claire Hostatic const UDateFormatField kDateFields[] = {
11585bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    UDAT_YEAR_FIELD,
11685bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    UDAT_MONTH_FIELD,
11785bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    UDAT_DATE_FIELD,
11885bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    UDAT_DAY_OF_YEAR_FIELD,
11985bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    UDAT_DAY_OF_WEEK_IN_MONTH_FIELD,
12085bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    UDAT_WEEK_OF_YEAR_FIELD,
12185bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    UDAT_WEEK_OF_MONTH_FIELD,
12285bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    UDAT_YEAR_WOY_FIELD,
12385bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    UDAT_EXTENDED_YEAR_FIELD,
12485bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    UDAT_JULIAN_DAY_FIELD,
12585bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    UDAT_STANDALONE_DAY_FIELD,
12685bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    UDAT_STANDALONE_MONTH_FIELD,
12785bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    UDAT_QUARTER_FIELD,
128103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius    UDAT_STANDALONE_QUARTER_FIELD,
129fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius    UDAT_YEAR_NAME_FIELD,
130fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius    UDAT_RELATED_YEAR_FIELD };
131fceb39872958b9fa2505e63f8b8699a9e0f882f4ccorneliusstatic const int8_t kDateFieldsCount = 16;
13285bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho
13385bf2e2fbc60a9f938064abc8127d61da7d19882Claire Hostatic const UDateFormatField kTimeFields[] = {
13485bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    UDAT_HOUR_OF_DAY1_FIELD,
13527f654740f2a26ad62a5c155af9199af9e69b889claireho    UDAT_HOUR_OF_DAY0_FIELD,
13685bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    UDAT_MINUTE_FIELD,
13785bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    UDAT_SECOND_FIELD,
13885bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    UDAT_FRACTIONAL_SECOND_FIELD,
13985bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    UDAT_HOUR1_FIELD,
14085bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    UDAT_HOUR0_FIELD,
14185bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    UDAT_MILLISECONDS_IN_DAY_FIELD,
1428393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius    UDAT_TIMEZONE_RFC_FIELD,
1438393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius    UDAT_TIMEZONE_LOCALIZED_GMT_OFFSET_FIELD };
1448393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Corneliusstatic const int8_t kTimeFieldsCount = 10;
14585bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho
14685bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho
147ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru// This is a pattern-of-last-resort used when we can't load a usable pattern out
148ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru// of a resource.
149ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Querustatic const UChar gDefaultPattern[] =
150ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru{
151ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    0x79, 0x79, 0x79, 0x79, 0x4D, 0x4D, 0x64, 0x64, 0x20, 0x68, 0x68, 0x3A, 0x6D, 0x6D, 0x20, 0x61, 0
152ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru};  /* "yyyyMMdd hh:mm a" */
153ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
154ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru// This prefix is designed to NEVER MATCH real text, in order to
155ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru// suppress the parsing of negative numbers.  Adjust as needed (if
156ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru// this becomes valid Unicode).
157ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Querustatic const UChar SUPPRESS_NEGATIVE_PREFIX[] = {0xAB00, 0};
158ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
159ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru/**
160ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru * These are the tags we expect to see in normal resource bundle files associated
161ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru * with a locale.
162ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru */
163ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Querustatic const char gDateTimePatternsTag[]="DateTimePatterns";
164ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
16554dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius//static const UChar gEtcUTC[] = {0x45, 0x74, 0x63, 0x2F, 0x55, 0x54, 0x43, 0x00}; // "Etc/UTC"
166ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Querustatic const UChar QUOTE = 0x27; // Single quote
167b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
168b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho/*
169b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho * The field range check bias for each UDateFormatField.
170b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho * The bias is added to the minimum and maximum values
171b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho * before they are compared to the parsed number.
172b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho * For example, the calendar stores zero-based month numbers
173b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho * but the parsed month numbers start at 1, so the bias is 1.
174b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho *
175b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho * A value of -1 means that the value is not checked.
176b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho */
177b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2clairehostatic const int32_t gFieldRangeBias[] = {
178b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho    -1,  // 'G' - UDAT_ERA_FIELD
179b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho    -1,  // 'y' - UDAT_YEAR_FIELD
180b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho     1,  // 'M' - UDAT_MONTH_FIELD
181b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho     0,  // 'd' - UDAT_DATE_FIELD
182b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho    -1,  // 'k' - UDAT_HOUR_OF_DAY1_FIELD
183b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho    -1,  // 'H' - UDAT_HOUR_OF_DAY0_FIELD
184b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho     0,  // 'm' - UDAT_MINUTE_FIELD
185b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho     0,  // 's' - UDAT_SEOND_FIELD
186b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho    -1,  // 'S' - UDAT_FRACTIONAL_SECOND_FIELD (0-999?)
187b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho    -1,  // 'E' - UDAT_DAY_OF_WEEK_FIELD (1-7?)
188b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho    -1,  // 'D' - UDAT_DAY_OF_YEAR_FIELD (1 - 366?)
189b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho    -1,  // 'F' - UDAT_DAY_OF_WEEK_IN_MONTH_FIELD (1-5?)
190b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho    -1,  // 'w' - UDAT_WEEK_OF_YEAR_FIELD (1-52?)
191b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho    -1,  // 'W' - UDAT_WEEK_OF_MONTH_FIELD (1-5?)
192b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho    -1,  // 'a' - UDAT_AM_PM_FIELD
193b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho    -1,  // 'h' - UDAT_HOUR1_FIELD
194b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho    -1,  // 'K' - UDAT_HOUR0_FIELD
195b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho    -1,  // 'z' - UDAT_TIMEZONE_FIELD
196b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho    -1,  // 'Y' - UDAT_YEAR_WOY_FIELD
197b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho    -1,  // 'e' - UDAT_DOW_LOCAL_FIELD
198b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho    -1,  // 'u' - UDAT_EXTENDED_YEAR_FIELD
199b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho    -1,  // 'g' - UDAT_JULIAN_DAY_FIELD
200b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho    -1,  // 'A' - UDAT_MILLISECONDS_IN_DAY_FIELD
201b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho    -1,  // 'Z' - UDAT_TIMEZONE_RFC_FIELD
202b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho    -1,  // 'v' - UDAT_TIMEZONE_GENERIC_FIELD
203b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho     0,  // 'c' - UDAT_STANDALONE_DAY_FIELD
204b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho     1,  // 'L' - UDAT_STANDALONE_MONTH_FIELD
205b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho    -1,  // 'Q' - UDAT_QUARTER_FIELD (1-4?)
206b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho    -1,  // 'q' - UDAT_STANDALONE_QUARTER_FIELD
207fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius    -1,  // 'V' - UDAT_TIMEZONE_SPECIAL_FIELD
208103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius    -1,  // 'U' - UDAT_YEAR_NAME_FIELD
2098393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius    -1,  // 'O' - UDAT_TIMEZONE_LOCALIZED_GMT_OFFSET_FIELD
2108393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius    -1,  // 'X' - UDAT_TIMEZONE_ISO_FIELD
2118393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius    -1,  // 'x' - UDAT_TIMEZONE_ISO_LOCAL_FIELD
212fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius    -1,  // 'r' - UDAT_RELATED_YEAR_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
224ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru//----------------------------------------------------------------------
225ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
226ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste QueruSimpleDateFormat::~SimpleDateFormat()
227ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru{
228ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    delete fSymbols;
22985bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    if (fNumberFormatters) {
23085bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho        uprv_free(fNumberFormatters);
23185bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    }
232b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho    if (fTimeZoneFormat) {
233b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho        delete fTimeZoneFormat;
234b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho    }
23585bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho
23685bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    while (fOverrideList) {
23785bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho        NSOverride *cur = fOverrideList;
23885bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho        fOverrideList = cur->next;
23985bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho        delete cur->nf;
24085bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho        uprv_free(cur);
241b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    }
242fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius
243fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius#if !UCONFIG_NO_BREAK_ITERATION
244fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius    delete fCapitalizationBrkIter;
245fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius#endif
246ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru}
247ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
248ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru//----------------------------------------------------------------------
249ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
250ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste QueruSimpleDateFormat::SimpleDateFormat(UErrorCode& status)
251ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru  :   fLocale(Locale::getDefault()),
252ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru      fSymbols(NULL),
253b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho      fTimeZoneFormat(NULL),
25485bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho      fNumberFormatters(NULL),
255103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius      fOverrideList(NULL),
256fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius      fCapitalizationBrkIter(NULL)
257ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru{
258fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius    initializeBooleanAttributes();
259ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    construct(kShort, (EStyle) (kShort + kDateOffset), fLocale, status);
260ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    initializeDefaultCentury();
261ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru}
262ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
263ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru//----------------------------------------------------------------------
264ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
265ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste QueruSimpleDateFormat::SimpleDateFormat(const UnicodeString& pattern,
266ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                                   UErrorCode &status)
267ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru:   fPattern(pattern),
268ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    fLocale(Locale::getDefault()),
269ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    fSymbols(NULL),
270b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho    fTimeZoneFormat(NULL),
27185bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    fNumberFormatters(NULL),
272103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius    fOverrideList(NULL),
273fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius    fCapitalizationBrkIter(NULL)
274ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru{
27585bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    fDateOverride.setToBogus();
27685bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    fTimeOverride.setToBogus();
277fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius    initializeBooleanAttributes();
278ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    initializeSymbols(fLocale, initializeCalendar(NULL,fLocale,status), status);
279ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    initialize(fLocale, status);
280ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    initializeDefaultCentury();
28185bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho
28285bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho}
28385bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho//----------------------------------------------------------------------
28485bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho
28585bf2e2fbc60a9f938064abc8127d61da7d19882Claire HoSimpleDateFormat::SimpleDateFormat(const UnicodeString& pattern,
28685bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho                                   const UnicodeString& override,
28785bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho                                   UErrorCode &status)
28885bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho:   fPattern(pattern),
28985bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    fLocale(Locale::getDefault()),
29085bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    fSymbols(NULL),
291b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho    fTimeZoneFormat(NULL),
29285bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    fNumberFormatters(NULL),
293103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius    fOverrideList(NULL),
294fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius    fCapitalizationBrkIter(NULL)
29585bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho{
29685bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    fDateOverride.setTo(override);
29785bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    fTimeOverride.setToBogus();
298fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius    initializeBooleanAttributes();
29985bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    initializeSymbols(fLocale, initializeCalendar(NULL,fLocale,status), status);
30085bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    initialize(fLocale, status);
30185bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    initializeDefaultCentury();
30285bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho
30385bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    processOverrideString(fLocale,override,kOvrStrBoth,status);
30485bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho
305ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru}
306ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
307ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru//----------------------------------------------------------------------
308ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
309ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste QueruSimpleDateFormat::SimpleDateFormat(const UnicodeString& pattern,
310ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                                   const Locale& locale,
311ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                                   UErrorCode& status)
312ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru:   fPattern(pattern),
313ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    fLocale(locale),
314b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho    fTimeZoneFormat(NULL),
31585bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    fNumberFormatters(NULL),
316103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius    fOverrideList(NULL),
317fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius    fCapitalizationBrkIter(NULL)
318ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru{
31985bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho
32085bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    fDateOverride.setToBogus();
32185bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    fTimeOverride.setToBogus();
322fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius    initializeBooleanAttributes();
32385bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho
324ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    initializeSymbols(fLocale, initializeCalendar(NULL,fLocale,status), status);
325ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    initialize(fLocale, status);
326ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    initializeDefaultCentury();
327ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru}
328ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
329ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru//----------------------------------------------------------------------
330ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
331ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste QueruSimpleDateFormat::SimpleDateFormat(const UnicodeString& pattern,
33285bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho                                   const UnicodeString& override,
33385bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho                                   const Locale& locale,
33485bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho                                   UErrorCode& status)
33585bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho:   fPattern(pattern),
33685bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    fLocale(locale),
337b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho    fTimeZoneFormat(NULL),
33885bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    fNumberFormatters(NULL),
339103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius    fOverrideList(NULL),
340fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius    fCapitalizationBrkIter(NULL)
34185bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho{
34285bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho
34385bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    fDateOverride.setTo(override);
34485bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    fTimeOverride.setToBogus();
345fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius    initializeBooleanAttributes();
34685bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho
34785bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    initializeSymbols(fLocale, initializeCalendar(NULL,fLocale,status), status);
34885bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    initialize(fLocale, status);
34985bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    initializeDefaultCentury();
35085bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho
35185bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    processOverrideString(locale,override,kOvrStrBoth,status);
35285bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho
35385bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho}
35485bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho
35585bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho//----------------------------------------------------------------------
35685bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho
35785bf2e2fbc60a9f938064abc8127d61da7d19882Claire HoSimpleDateFormat::SimpleDateFormat(const UnicodeString& pattern,
358ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                                   DateFormatSymbols* symbolsToAdopt,
359ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                                   UErrorCode& status)
360ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru:   fPattern(pattern),
361ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    fLocale(Locale::getDefault()),
362ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    fSymbols(symbolsToAdopt),
363b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho    fTimeZoneFormat(NULL),
36485bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    fNumberFormatters(NULL),
365103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius    fOverrideList(NULL),
366fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius    fCapitalizationBrkIter(NULL)
367ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru{
36885bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho
36985bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    fDateOverride.setToBogus();
37085bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    fTimeOverride.setToBogus();
371fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius    initializeBooleanAttributes();
37285bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho
373ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    initializeCalendar(NULL,fLocale,status);
374ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    initialize(fLocale, status);
375ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    initializeDefaultCentury();
376ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru}
377ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
378ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru//----------------------------------------------------------------------
379ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
380ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste QueruSimpleDateFormat::SimpleDateFormat(const UnicodeString& pattern,
381ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                                   const DateFormatSymbols& symbols,
382ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                                   UErrorCode& status)
383ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru:   fPattern(pattern),
384ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    fLocale(Locale::getDefault()),
385ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    fSymbols(new DateFormatSymbols(symbols)),
386b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho    fTimeZoneFormat(NULL),
38785bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    fNumberFormatters(NULL),
388103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius    fOverrideList(NULL),
389fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius    fCapitalizationBrkIter(NULL)
390ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru{
39185bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho
39285bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    fDateOverride.setToBogus();
39385bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    fTimeOverride.setToBogus();
394fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius    initializeBooleanAttributes();
39585bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho
396ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    initializeCalendar(NULL, fLocale, status);
397ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    initialize(fLocale, status);
398ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    initializeDefaultCentury();
399ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru}
400ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
401ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru//----------------------------------------------------------------------
402ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
403ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru// Not for public consumption; used by DateFormat
404ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste QueruSimpleDateFormat::SimpleDateFormat(EStyle timeStyle,
405ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                                   EStyle dateStyle,
406ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                                   const Locale& locale,
407ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                                   UErrorCode& status)
408ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru:   fLocale(locale),
409ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    fSymbols(NULL),
410b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho    fTimeZoneFormat(NULL),
41185bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    fNumberFormatters(NULL),
412103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius    fOverrideList(NULL),
413fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius    fCapitalizationBrkIter(NULL)
414ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru{
415fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius    initializeBooleanAttributes();
416ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    construct(timeStyle, dateStyle, fLocale, status);
417ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    if(U_SUCCESS(status)) {
418ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru      initializeDefaultCentury();
419ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    }
420ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru}
421ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
422ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru//----------------------------------------------------------------------
423ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
424ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru/**
425ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru * Not for public consumption; used by DateFormat.  This constructor
426ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru * never fails.  If the resource data is not available, it uses the
427ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru * the last resort symbols.
428ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru */
429ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste QueruSimpleDateFormat::SimpleDateFormat(const Locale& locale,
430ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                                   UErrorCode& status)
431ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru:   fPattern(gDefaultPattern),
432ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    fLocale(locale),
433ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    fSymbols(NULL),
434b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho    fTimeZoneFormat(NULL),
43585bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    fNumberFormatters(NULL),
436103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius    fOverrideList(NULL),
437fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius    fCapitalizationBrkIter(NULL)
438ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru{
439ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    if (U_FAILURE(status)) return;
440fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius    initializeBooleanAttributes();
441ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    initializeSymbols(fLocale, initializeCalendar(NULL, fLocale, status),status);
442ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    if (U_FAILURE(status))
443ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    {
444ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        status = U_ZERO_ERROR;
445ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        delete fSymbols;
446ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        // This constructor doesn't fail; it uses last resort data
447ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        fSymbols = new DateFormatSymbols(status);
448ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        /* test for NULL */
449ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        if (fSymbols == 0) {
450ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            status = U_MEMORY_ALLOCATION_ERROR;
451ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            return;
452ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        }
453ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    }
454ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
45585bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    fDateOverride.setToBogus();
45685bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    fTimeOverride.setToBogus();
45785bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho
458ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    initialize(fLocale, status);
459ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    if(U_SUCCESS(status)) {
460ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru      initializeDefaultCentury();
461ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    }
462ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru}
463ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
464ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru//----------------------------------------------------------------------
465ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
466ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste QueruSimpleDateFormat::SimpleDateFormat(const SimpleDateFormat& other)
467ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru:   DateFormat(other),
468103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius    fLocale(other.fLocale),
469ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    fSymbols(NULL),
470b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho    fTimeZoneFormat(NULL),
47185bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    fNumberFormatters(NULL),
472103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius    fOverrideList(NULL),
473fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius    fCapitalizationBrkIter(NULL)
474ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru{
475fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius    initializeBooleanAttributes();
476ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    *this = other;
477ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru}
478ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
479ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru//----------------------------------------------------------------------
480ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
481ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste QueruSimpleDateFormat& SimpleDateFormat::operator=(const SimpleDateFormat& other)
482ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru{
483ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    if (this == &other) {
484ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        return *this;
485ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    }
486ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    DateFormat::operator=(other);
487ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
488ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    delete fSymbols;
489ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    fSymbols = NULL;
490ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
491ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    if (other.fSymbols)
492ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        fSymbols = new DateFormatSymbols(*other.fSymbols);
493ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
494ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    fDefaultCenturyStart         = other.fDefaultCenturyStart;
495ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    fDefaultCenturyStartYear     = other.fDefaultCenturyStartYear;
496ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    fHaveDefaultCentury          = other.fHaveDefaultCentury;
497ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
498ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    fPattern = other.fPattern;
499ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
500b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho    // TimeZoneFormat in ICU4C only depends on a locale for now
501b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho    if (fLocale != other.fLocale) {
502b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho        delete fTimeZoneFormat;
503103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius        fTimeZoneFormat = NULL; // forces lazy instantiation with the other locale
504103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius        fLocale = other.fLocale;
505b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho    }
506b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho
507fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius#if !UCONFIG_NO_BREAK_ITERATION
508fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius    if (other.fCapitalizationBrkIter != NULL) {
509fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius        fCapitalizationBrkIter = (other.fCapitalizationBrkIter)->clone();
510fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius    }
511fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius#endif
512103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius
513ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    return *this;
514ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru}
515ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
516ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru//----------------------------------------------------------------------
517ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
518ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste QueruFormat*
519ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste QueruSimpleDateFormat::clone() const
520ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru{
521ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    return new SimpleDateFormat(*this);
522ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru}
523ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
524ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru//----------------------------------------------------------------------
525ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
526ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste QueruUBool
527ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste QueruSimpleDateFormat::operator==(const Format& other) const
528ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru{
529ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    if (DateFormat::operator==(other)) {
530fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius        // The DateFormat::operator== check for fCapitalizationContext equality above
531fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius        //   is sufficient to check equality of all derived context-related data.
532ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        // DateFormat::operator== guarantees following cast is safe
533ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        SimpleDateFormat* that = (SimpleDateFormat*)&other;
534ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        return (fPattern             == that->fPattern &&
535ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                fSymbols             != NULL && // Check for pathological object
536ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                that->fSymbols       != NULL && // Check for pathological object
537ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                *fSymbols            == *that->fSymbols &&
538ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                fHaveDefaultCentury  == that->fHaveDefaultCentury &&
539fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius                fDefaultCenturyStart == that->fDefaultCenturyStart);
540ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    }
541ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    return FALSE;
542ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru}
543ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
544ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru//----------------------------------------------------------------------
545ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
546ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queruvoid SimpleDateFormat::construct(EStyle timeStyle,
547ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                                 EStyle dateStyle,
548ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                                 const Locale& locale,
549ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                                 UErrorCode& status)
550ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru{
551ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    // called by several constructors to load pattern data from the resources
552ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    if (U_FAILURE(status)) return;
553ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
554ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    // We will need the calendar to know what type of symbols to load.
555ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    initializeCalendar(NULL, locale, status);
556ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    if (U_FAILURE(status)) return;
557ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
558ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    CalendarData calData(locale, fCalendar?fCalendar->getType():NULL, status);
559ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    UResourceBundle *dateTimePatterns = calData.getByKey(gDateTimePatternsTag, status);
56085bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    UResourceBundle *currentBundle;
56185bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho
562ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    if (U_FAILURE(status)) return;
563ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
564ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    if (ures_getSize(dateTimePatterns) <= kDateTime)
565ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    {
566ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        status = U_INVALID_FORMAT_ERROR;
567ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        return;
568ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    }
569ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
570ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    setLocaleIDs(ures_getLocaleByType(dateTimePatterns, ULOC_VALID_LOCALE, &status),
571ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                 ures_getLocaleByType(dateTimePatterns, ULOC_ACTUAL_LOCALE, &status));
572ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
573ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    // create a symbols object from the locale
574ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    initializeSymbols(locale,fCalendar, status);
575ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    if (U_FAILURE(status)) return;
576ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    /* test for NULL */
577ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    if (fSymbols == 0) {
578ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        status = U_MEMORY_ALLOCATION_ERROR;
579ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        return;
580ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    }
581ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
58285bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    const UChar *resStr,*ovrStr;
58385bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    int32_t resStrLen,ovrStrLen = 0;
58485bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    fDateOverride.setToBogus();
58585bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    fTimeOverride.setToBogus();
586ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
587ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    // if the pattern should include both date and time information, use the date/time
588ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    // pattern string as a guide to tell use how to glue together the appropriate date
589ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    // and time pattern strings.  The actual gluing-together is handled by a convenience
590ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    // method on MessageFormat.
591ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    if ((timeStyle != kNone) && (dateStyle != kNone))
592ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    {
593ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        Formattable timeDateArray[2];
594ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
595ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        // use Formattable::adoptString() so that we can use fastCopyFrom()
596ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        // instead of Formattable::setString()'s unaware, safe, deep string clone
597ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        // see Jitterbug 2296
59850294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho
59985bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho        currentBundle = ures_getByIndex(dateTimePatterns, (int32_t)timeStyle, NULL, &status);
60085bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho        if (U_FAILURE(status)) {
60185bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho           status = U_INVALID_FORMAT_ERROR;
60285bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho           return;
60385bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho        }
60485bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho        switch (ures_getType(currentBundle)) {
60585bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho            case URES_STRING: {
60685bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho               resStr = ures_getString(currentBundle, &resStrLen, &status);
60785bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho               break;
60885bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho            }
60985bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho            case URES_ARRAY: {
61085bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho               resStr = ures_getStringByIndex(currentBundle, 0, &resStrLen, &status);
61185bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho               ovrStr = ures_getStringByIndex(currentBundle, 1, &ovrStrLen, &status);
61285bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho               fTimeOverride.setTo(TRUE, ovrStr, ovrStrLen);
61385bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho               break;
61485bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho            }
61585bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho            default: {
61685bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho               status = U_INVALID_FORMAT_ERROR;
61785bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho               ures_close(currentBundle);
61885bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho               return;
61985bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho            }
62050294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho        }
62185bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho        ures_close(currentBundle);
62250294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho
62385bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho        UnicodeString *tempus1 = new UnicodeString(TRUE, resStr, resStrLen);
62485bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho        // NULL pointer check
62585bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho        if (tempus1 == NULL) {
62685bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho            status = U_MEMORY_ALLOCATION_ERROR;
62785bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho            return;
62885bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho        }
62985bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho        timeDateArray[0].adoptString(tempus1);
63050294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho
63185bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho        currentBundle = ures_getByIndex(dateTimePatterns, (int32_t)dateStyle, NULL, &status);
63285bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho        if (U_FAILURE(status)) {
63385bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho           status = U_INVALID_FORMAT_ERROR;
63485bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho           return;
63585bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho        }
63685bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho        switch (ures_getType(currentBundle)) {
63785bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho            case URES_STRING: {
63885bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho               resStr = ures_getString(currentBundle, &resStrLen, &status);
63950294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho               break;
64085bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho            }
64185bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho            case URES_ARRAY: {
64285bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho               resStr = ures_getStringByIndex(currentBundle, 0, &resStrLen, &status);
64385bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho               ovrStr = ures_getStringByIndex(currentBundle, 1, &ovrStrLen, &status);
64485bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho               fDateOverride.setTo(TRUE, ovrStr, ovrStrLen);
64550294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho               break;
64685bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho            }
64785bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho            default: {
64885bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho               status = U_INVALID_FORMAT_ERROR;
64985bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho               ures_close(currentBundle);
65085bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho               return;
65185bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho            }
65250294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho        }
65385bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho        ures_close(currentBundle);
65485bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho
65585bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho        UnicodeString *tempus2 = new UnicodeString(TRUE, resStr, resStrLen);
65685bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho        // Null pointer check
65785bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho        if (tempus2 == NULL) {
65885bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho            status = U_MEMORY_ALLOCATION_ERROR;
65985bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho            return;
66085bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho        }
66185bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho        timeDateArray[1].adoptString(tempus2);
662ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
66385bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho        int32_t glueIndex = kDateTime;
66485bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho        int32_t patternsSize = ures_getSize(dateTimePatterns);
66585bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho        if (patternsSize >= (kDateTimeOffset + kShort + 1)) {
66685bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho            // Get proper date time format
66785bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho            glueIndex = (int32_t)(kDateTimeOffset + (dateStyle - kDateOffset));
66885bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho        }
66985bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho
67085bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho        resStr = ures_getStringByIndex(dateTimePatterns, glueIndex, &resStrLen, &status);
671ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        MessageFormat::format(UnicodeString(TRUE, resStr, resStrLen), timeDateArray, 2, fPattern, status);
672ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    }
673ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    // if the pattern includes just time data or just date date, load the appropriate
674ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    // pattern string from the resources
675ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    // setTo() - see DateFormatSymbols::assignArray comments
676ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    else if (timeStyle != kNone) {
67785bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho        currentBundle = ures_getByIndex(dateTimePatterns, (int32_t)timeStyle, NULL, &status);
67885bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho        if (U_FAILURE(status)) {
67985bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho           status = U_INVALID_FORMAT_ERROR;
68085bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho           return;
68185bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho        }
68285bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho        switch (ures_getType(currentBundle)) {
68385bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho            case URES_STRING: {
68485bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho               resStr = ures_getString(currentBundle, &resStrLen, &status);
68550294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho               break;
68685bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho            }
68785bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho            case URES_ARRAY: {
68885bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho               resStr = ures_getStringByIndex(currentBundle, 0, &resStrLen, &status);
68985bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho               ovrStr = ures_getStringByIndex(currentBundle, 1, &ovrStrLen, &status);
69085bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho               fDateOverride.setTo(TRUE, ovrStr, ovrStrLen);
69150294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho               break;
69285bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho            }
69385bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho            default: {
69485bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho               status = U_INVALID_FORMAT_ERROR;
69585bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho                ures_close(currentBundle);
69685bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho               return;
69785bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho            }
69850294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho        }
699ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        fPattern.setTo(TRUE, resStr, resStrLen);
70085bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho        ures_close(currentBundle);
701ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    }
702ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    else if (dateStyle != kNone) {
70385bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho        currentBundle = ures_getByIndex(dateTimePatterns, (int32_t)dateStyle, NULL, &status);
70485bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho        if (U_FAILURE(status)) {
70585bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho           status = U_INVALID_FORMAT_ERROR;
70685bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho           return;
70785bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho        }
70885bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho        switch (ures_getType(currentBundle)) {
70985bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho            case URES_STRING: {
71085bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho               resStr = ures_getString(currentBundle, &resStrLen, &status);
71150294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho               break;
71285bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho            }
71385bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho            case URES_ARRAY: {
71485bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho               resStr = ures_getStringByIndex(currentBundle, 0, &resStrLen, &status);
71585bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho               ovrStr = ures_getStringByIndex(currentBundle, 1, &ovrStrLen, &status);
71685bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho               fDateOverride.setTo(TRUE, ovrStr, ovrStrLen);
71750294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho               break;
71885bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho            }
71985bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho            default: {
72085bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho               status = U_INVALID_FORMAT_ERROR;
72185bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho               ures_close(currentBundle);
72285bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho               return;
72385bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho            }
72450294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho        }
725ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        fPattern.setTo(TRUE, resStr, resStrLen);
72685bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho        ures_close(currentBundle);
727ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    }
72850294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho
729ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    // and if it includes _neither_, that's an error
730ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    else
731ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        status = U_INVALID_FORMAT_ERROR;
732ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
733ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    // finally, finish initializing by creating a Calendar and a NumberFormat
734ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    initialize(locale, status);
735ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru}
736ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
737ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru//----------------------------------------------------------------------
738ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
739ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste QueruCalendar*
740ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste QueruSimpleDateFormat::initializeCalendar(TimeZone* adoptZone, const Locale& locale, UErrorCode& status)
741ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru{
742ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    if(!U_FAILURE(status)) {
743ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        fCalendar = Calendar::createInstance(adoptZone?adoptZone:TimeZone::createDefault(), locale, status);
744ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    }
745ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    if (U_SUCCESS(status) && fCalendar == NULL) {
746ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        status = U_MEMORY_ALLOCATION_ERROR;
747ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    }
748ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    return fCalendar;
749ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru}
750ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
751ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queruvoid
752ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste QueruSimpleDateFormat::initializeSymbols(const Locale& locale, Calendar* calendar, UErrorCode& status)
753ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru{
754ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru  if(U_FAILURE(status)) {
755ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    fSymbols = NULL;
756ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru  } else {
757ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    // pass in calendar type - use NULL (default) if no calendar set (or err).
758ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    fSymbols = new DateFormatSymbols(locale, calendar?calendar->getType() :NULL , status);
75985bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    // Null pointer check
76085bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    if (fSymbols == NULL) {
761b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho        status = U_MEMORY_ALLOCATION_ERROR;
762b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho        return;
76385bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    }
764ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru  }
765ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru}
766ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
767ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queruvoid
768ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste QueruSimpleDateFormat::initialize(const Locale& locale,
769ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                             UErrorCode& status)
770ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru{
771ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    if (U_FAILURE(status)) return;
772ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
773ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    // We don't need to check that the row count is >= 1, since all 2d arrays have at
774ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    // least one row
775ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    fNumberFormat = NumberFormat::createInstance(locale, status);
776ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    if (fNumberFormat != NULL && U_SUCCESS(status))
777ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    {
778ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        // no matter what the locale's default number format looked like, we want
779ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        // to modify it so that it doesn't use thousands separators, doesn't always
780ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        // show the decimal point, and recognizes integers only when parsing
781ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
782ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        fNumberFormat->setGroupingUsed(FALSE);
78327f654740f2a26ad62a5c155af9199af9e69b889claireho        DecimalFormat* decfmt = dynamic_cast<DecimalFormat*>(fNumberFormat);
78427f654740f2a26ad62a5c155af9199af9e69b889claireho        if (decfmt != NULL) {
78527f654740f2a26ad62a5c155af9199af9e69b889claireho            decfmt->setDecimalSeparatorAlwaysShown(FALSE);
78627f654740f2a26ad62a5c155af9199af9e69b889claireho        }
787ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        fNumberFormat->setParseIntegerOnly(TRUE);
788ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        fNumberFormat->setMinimumFractionDigits(0); // To prevent "Jan 1.00, 1997.00"
78985bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho
790b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho        //fNumberFormat->setLenient(TRUE); // Java uses a custom DateNumberFormat to format/parse
791b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho
79285bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho        initNumberFormatters(locale,status);
79350294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho
794ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    }
795ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    else if (U_SUCCESS(status))
796ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    {
797ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        status = U_MISSING_RESOURCE_ERROR;
798ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    }
799ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru}
800ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
801ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru/* Initialize the fields we use to disambiguate ambiguous years. Separate
802ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru * so we can call it from readObject().
803ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru */
80450294ead5e5d23f5bbfed76e00e6b510bd41eee1clairehovoid SimpleDateFormat::initializeDefaultCentury()
805ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru{
806ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru  if(fCalendar) {
807ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    fHaveDefaultCentury = fCalendar->haveDefaultCentury();
808ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    if(fHaveDefaultCentury) {
809ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru      fDefaultCenturyStart = fCalendar->defaultCenturyStart();
810ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru      fDefaultCenturyStartYear = fCalendar->defaultCenturyStartYear();
811ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    } else {
812ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru      fDefaultCenturyStart = DBL_MIN;
813ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru      fDefaultCenturyStartYear = -1;
814ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    }
815ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru  }
816ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru}
817ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
818fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius/*
819fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius * Initialize the boolean attributes. Separate so we can call it from all constructors.
820fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius */
821fceb39872958b9fa2505e63f8b8699a9e0f882f4ccorneliusvoid SimpleDateFormat::initializeBooleanAttributes()
822fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius{
823fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius    UErrorCode status = U_ZERO_ERROR;
824fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius
825fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius    setBooleanAttribute(UDAT_PARSE_ALLOW_WHITESPACE, true, status);
826fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius    setBooleanAttribute(UDAT_PARSE_ALLOW_NUMERIC, true, status);
827fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius    setBooleanAttribute(UDAT_PARSE_PARTIAL_MATCH, true, status);
828fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius    setBooleanAttribute(UDAT_PARSE_MULTIPLE_PATTERNS_FOR_MATCH, true, status);
829fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius}
830fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius
831ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru/* Define one-century window into which to disambiguate dates using
832ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru * two-digit years. Make public in JDK 1.2.
833ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru */
83450294ead5e5d23f5bbfed76e00e6b510bd41eee1clairehovoid SimpleDateFormat::parseAmbiguousDatesAsAfter(UDate startDate, UErrorCode& status)
835ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru{
836ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    if(U_FAILURE(status)) {
837ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        return;
838ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    }
839ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    if(!fCalendar) {
840ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru      status = U_ILLEGAL_ARGUMENT_ERROR;
841ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru      return;
842ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    }
84350294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho
844ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    fCalendar->setTime(startDate, status);
845ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    if(U_SUCCESS(status)) {
846ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        fHaveDefaultCentury = TRUE;
847ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        fDefaultCenturyStart = startDate;
848ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        fDefaultCenturyStartYear = fCalendar->get(UCAL_YEAR, status);
849ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    }
850ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru}
85150294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho
852ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru//----------------------------------------------------------------------
853ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
854ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste QueruUnicodeString&
855ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste QueruSimpleDateFormat::format(Calendar& cal, UnicodeString& appendTo, FieldPosition& pos) const
856ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru{
85750294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho  UErrorCode status = U_ZERO_ERROR;
85850294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho  FieldPositionOnlyHandler handler(pos);
85954dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius  return _format(cal, appendTo, handler, status);
86050294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho}
86150294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho
86250294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho//----------------------------------------------------------------------
86350294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho
86450294ead5e5d23f5bbfed76e00e6b510bd41eee1clairehoUnicodeString&
86550294ead5e5d23f5bbfed76e00e6b510bd41eee1clairehoSimpleDateFormat::format(Calendar& cal, UnicodeString& appendTo,
86650294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho                         FieldPositionIterator* posIter, UErrorCode& status) const
86750294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho{
86850294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho  FieldPositionIteratorHandler handler(posIter, status);
86954dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius  return _format(cal, appendTo, handler, status);
87050294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho}
87150294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho
87250294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho//----------------------------------------------------------------------
873ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
87450294ead5e5d23f5bbfed76e00e6b510bd41eee1clairehoUnicodeString&
87554dcd9b6a06071f647dac967e9e267abb9410720Craig CorneliusSimpleDateFormat::_format(Calendar& cal, UnicodeString& appendTo,
87654dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius                            FieldPositionHandler& handler, UErrorCode& status) const
87750294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho{
878103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius    if ( U_FAILURE(status) ) {
879103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius       return appendTo;
880103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius    }
881103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius    Calendar* workCal = &cal;
882103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius    Calendar* calClone = NULL;
88385bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    if (&cal != fCalendar && uprv_strcmp(cal.getType(), fCalendar->getType()) != 0) {
88485bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho        // Different calendar type
88585bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho        // We use the time and time zone from the input calendar, but
88685bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho        // do not use the input calendar for field calculation.
887103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius        calClone = fCalendar->clone();
888103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius        if (calClone != NULL) {
889103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius            UDate t = cal.getTime(status);
890103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius            calClone->setTime(t, status);
891103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius            calClone->setTimeZone(cal.getTimeZone());
892103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius            workCal = calClone;
893103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius        } else {
894103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius            status = U_MEMORY_ALLOCATION_ERROR;
895103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius            return appendTo;
896103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius        }
89785bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    }
89885bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho
899ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    UBool inQuote = FALSE;
900ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    UChar prevCh = 0;
901ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    int32_t count = 0;
902103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius    int32_t fieldNum = 0;
903fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius    UDisplayContext capitalizationContext = getContext(UDISPCTX_TYPE_CAPITALIZATION, status);
90450294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho
905ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    // loop through the pattern string character by character
906ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    for (int32_t i = 0; i < fPattern.length() && U_SUCCESS(status); ++i) {
907ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        UChar ch = fPattern[i];
90850294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho
909ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        // Use subFormat() to format a repeated pattern character
910ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        // when a different pattern or non-pattern character is seen
911ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        if (ch != prevCh && count > 0) {
912fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius            subFormat(appendTo, prevCh, count, capitalizationContext, fieldNum++, handler, *workCal, status);
913ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            count = 0;
914ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        }
915ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        if (ch == QUOTE) {
916ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            // Consecutive single quotes are a single quote literal,
917ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            // either outside of quotes or between quotes
918ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            if ((i+1) < fPattern.length() && fPattern[i+1] == QUOTE) {
919ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                appendTo += (UChar)QUOTE;
920ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                ++i;
921ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            } else {
922ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                inQuote = ! inQuote;
923ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            }
92450294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho        }
92550294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho        else if ( ! inQuote && ((ch >= 0x0061 /*'a'*/ && ch <= 0x007A /*'z'*/)
926ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                    || (ch >= 0x0041 /*'A'*/ && ch <= 0x005A /*'Z'*/))) {
927ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            // ch is a date-time pattern character to be interpreted
928ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            // by subFormat(); count the number of times it is repeated
929ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            prevCh = ch;
930ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            ++count;
931ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        }
932ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        else {
933ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            // Append quoted characters and unquoted non-pattern characters
934ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            appendTo += ch;
935ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        }
936ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    }
937ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
938ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    // Format the last item in the pattern, if any
939ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    if (count > 0) {
940fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius        subFormat(appendTo, prevCh, count, capitalizationContext, fieldNum++, handler, *workCal, status);
94185bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    }
94285bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho
943103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius    if (calClone != NULL) {
944103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius        delete calClone;
945ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    }
946ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
947ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    return appendTo;
948ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru}
949ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
950ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru//----------------------------------------------------------------------
951ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
95285bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho/* Map calendar field into calendar field level.
95385bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho * the larger the level, the smaller the field unit.
95485bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho * For example, UCAL_ERA level is 0, UCAL_YEAR level is 10,
95585bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho * UCAL_MONTH level is 20.
95685bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho * NOTE: if new fields adds in, the table needs to update.
95785bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho */
95885bf2e2fbc60a9f938064abc8127d61da7d19882Claire Hoconst int32_t
95985bf2e2fbc60a9f938064abc8127d61da7d19882Claire HoSimpleDateFormat::fgCalendarFieldToLevel[] =
96085bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho{
96185bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    /*GyM*/ 0, 10, 20,
96285bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    /*wW*/ 20, 30,
96385bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    /*dDEF*/ 30, 20, 30, 30,
96485bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    /*ahHm*/ 40, 50, 50, 60,
965fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius    /*sS*/ 70, 80,
96650294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    /*z?Y*/ 0, 0, 10,
96785bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    /*eug*/ 30, 10, 0,
968fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius    /*A?.*/ 40, 0, 0
96985bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho};
97085bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho
97185bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho
97285bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho/* Map calendar field LETTER into calendar field level.
97385bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho * the larger the level, the smaller the field unit.
97485bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho * NOTE: if new fields adds in, the table needs to update.
97585bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho */
97685bf2e2fbc60a9f938064abc8127d61da7d19882Claire Hoconst int32_t
97785bf2e2fbc60a9f938064abc8127d61da7d19882Claire HoSimpleDateFormat::fgPatternCharToLevel[] = {
97885bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    //       A   B   C   D   E   F   G   H   I   J   K   L   M   N   O
9798393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius        -1, 40, -1, -1, 20, 30, 30,  0, 50, -1, -1, 50, 20, 20, -1,  0,
98085bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    //   P   Q   R   S   T   U   V   W   X   Y   Z
9818393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius        -1, 20, -1, 80, -1, 10,  0, 30,  0, 10,  0, -1, -1, -1, -1, -1,
98285bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    //       a   b   c   d   e   f   g   h   i   j   k   l   m   n   o
983b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho        -1, 40, -1, 30, 30, 30, -1,  0, 50, -1, -1, 50, -1, 60, -1, -1,
98485bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    //   p   q   r   s   t   u   v   w   x   y   z
985fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius        -1, 20, 10, 70, -1, 10,  0, 20,  0, 10,  0, -1, -1, -1, -1, -1
98685bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho};
98785bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho
98885bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho
989ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru// Map index into pattern character string to Calendar field number.
990ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queruconst UCalendarDateFields
991ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste QueruSimpleDateFormat::fgPatternIndexToCalendarField[] =
992ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru{
993ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    /*GyM*/ UCAL_ERA, UCAL_YEAR, UCAL_MONTH,
994ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    /*dkH*/ UCAL_DATE, UCAL_HOUR_OF_DAY, UCAL_HOUR_OF_DAY,
995ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    /*msS*/ UCAL_MINUTE, UCAL_SECOND, UCAL_MILLISECOND,
996ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    /*EDF*/ UCAL_DAY_OF_WEEK, UCAL_DAY_OF_YEAR, UCAL_DAY_OF_WEEK_IN_MONTH,
997ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    /*wWa*/ UCAL_WEEK_OF_YEAR, UCAL_WEEK_OF_MONTH, UCAL_AM_PM,
998ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    /*hKz*/ UCAL_HOUR, UCAL_HOUR, UCAL_ZONE_OFFSET,
999ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    /*Yeu*/ UCAL_YEAR_WOY, UCAL_DOW_LOCAL, UCAL_EXTENDED_YEAR,
1000ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    /*gAZ*/ UCAL_JULIAN_DAY, UCAL_MILLISECONDS_IN_DAY, UCAL_ZONE_OFFSET,
1001ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    /*v*/   UCAL_ZONE_OFFSET,
100285bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    /*c*/   UCAL_DOW_LOCAL,
1003ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    /*L*/   UCAL_MONTH,
1004ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    /*Q*/   UCAL_MONTH,
1005ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    /*q*/   UCAL_MONTH,
1006ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    /*V*/   UCAL_ZONE_OFFSET,
1007103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius    /*U*/   UCAL_YEAR,
10088393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius    /*O*/   UCAL_ZONE_OFFSET,
10098393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius    /*Xx*/  UCAL_ZONE_OFFSET, UCAL_ZONE_OFFSET,
1010fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius    /*r*/   UCAL_EXTENDED_YEAR,
1011ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru};
1012ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
1013ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru// Map index into pattern character string to DateFormat field number
1014ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queruconst UDateFormatField
1015ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste QueruSimpleDateFormat::fgPatternIndexToDateFormatField[] = {
1016ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    /*GyM*/ UDAT_ERA_FIELD, UDAT_YEAR_FIELD, UDAT_MONTH_FIELD,
1017ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    /*dkH*/ UDAT_DATE_FIELD, UDAT_HOUR_OF_DAY1_FIELD, UDAT_HOUR_OF_DAY0_FIELD,
1018ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    /*msS*/ UDAT_MINUTE_FIELD, UDAT_SECOND_FIELD, UDAT_FRACTIONAL_SECOND_FIELD,
1019ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    /*EDF*/ UDAT_DAY_OF_WEEK_FIELD, UDAT_DAY_OF_YEAR_FIELD, UDAT_DAY_OF_WEEK_IN_MONTH_FIELD,
1020ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    /*wWa*/ UDAT_WEEK_OF_YEAR_FIELD, UDAT_WEEK_OF_MONTH_FIELD, UDAT_AM_PM_FIELD,
1021ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    /*hKz*/ UDAT_HOUR1_FIELD, UDAT_HOUR0_FIELD, UDAT_TIMEZONE_FIELD,
1022ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    /*Yeu*/ UDAT_YEAR_WOY_FIELD, UDAT_DOW_LOCAL_FIELD, UDAT_EXTENDED_YEAR_FIELD,
1023ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    /*gAZ*/ UDAT_JULIAN_DAY_FIELD, UDAT_MILLISECONDS_IN_DAY_FIELD, UDAT_TIMEZONE_RFC_FIELD,
1024ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    /*v*/   UDAT_TIMEZONE_GENERIC_FIELD,
1025ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    /*c*/   UDAT_STANDALONE_DAY_FIELD,
1026ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    /*L*/   UDAT_STANDALONE_MONTH_FIELD,
1027ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    /*Q*/   UDAT_QUARTER_FIELD,
1028ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    /*q*/   UDAT_STANDALONE_QUARTER_FIELD,
1029ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    /*V*/   UDAT_TIMEZONE_SPECIAL_FIELD,
1030103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius    /*U*/   UDAT_YEAR_NAME_FIELD,
10318393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius    /*O*/   UDAT_TIMEZONE_LOCALIZED_GMT_OFFSET_FIELD,
10328393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius    /*Xx*/  UDAT_TIMEZONE_ISO_FIELD, UDAT_TIMEZONE_ISO_LOCAL_FIELD,
1033fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius    /*r*/   UDAT_RELATED_YEAR_FIELD,
1034ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru};
1035ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
1036ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru//----------------------------------------------------------------------
1037ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
1038ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru/**
1039ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru * Append symbols[value] to dst.  Make sure the array index is not out
1040ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru * of bounds.
1041ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru */
1042ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Querustatic inline void
1043ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru_appendSymbol(UnicodeString& dst,
1044ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru              int32_t value,
1045ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru              const UnicodeString* symbols,
1046ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru              int32_t symbolsCount) {
1047ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    U_ASSERT(0 <= value && value < symbolsCount);
1048ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    if (0 <= value && value < symbolsCount) {
1049ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        dst += symbols[value];
1050ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    }
1051ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru}
1052ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
1053103e9ffba2cba345d0078eb8b8db33249f81840aCraig Corneliusstatic inline void
1054103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius_appendSymbolWithMonthPattern(UnicodeString& dst, int32_t value, const UnicodeString* symbols, int32_t symbolsCount,
1055103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius              const UnicodeString* monthPattern, UErrorCode& status) {
1056103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius    U_ASSERT(0 <= value && value < symbolsCount);
1057103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius    if (0 <= value && value < symbolsCount) {
1058103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius        if (monthPattern == NULL) {
1059103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius            dst += symbols[value];
1060b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        } else {
1061103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius            Formattable monthName((const UnicodeString&)(symbols[value]));
1062103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius            MessageFormat::format(*monthPattern, &monthName, 1, dst, status);
1063b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        }
1064b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    }
1065ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru}
1066ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
1067103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius//----------------------------------------------------------------------
106885bf2e2fbc60a9f938064abc8127d61da7d19882Claire Hovoid
106985bf2e2fbc60a9f938064abc8127d61da7d19882Claire HoSimpleDateFormat::initNumberFormatters(const Locale &locale,UErrorCode &status) {
107085bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    if (U_FAILURE(status)) {
107185bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho        return;
107285bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    }
107385bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    if ( fDateOverride.isBogus() && fTimeOverride.isBogus() ) {
107485bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho        return;
107585bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    }
107685bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    umtx_lock(&LOCK);
107785bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    if (fNumberFormatters == NULL) {
107885bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho        fNumberFormatters = (NumberFormat**)uprv_malloc(UDAT_FIELD_COUNT * sizeof(NumberFormat*));
107985bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho        if (fNumberFormatters) {
108085bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho            for (int32_t i = 0; i < UDAT_FIELD_COUNT; i++) {
108185bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho                fNumberFormatters[i] = fNumberFormat;
108285bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho            }
108385bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho        } else {
108485bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho            status = U_MEMORY_ALLOCATION_ERROR;
108585bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho        }
108685bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    }
108785bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    umtx_unlock(&LOCK);
108850294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho
108985bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    processOverrideString(locale,fDateOverride,kOvrStrDate,status);
109085bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    processOverrideString(locale,fTimeOverride,kOvrStrTime,status);
109185bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho
109285bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho}
109385bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho
109485bf2e2fbc60a9f938064abc8127d61da7d19882Claire Hovoid
109585bf2e2fbc60a9f938064abc8127d61da7d19882Claire HoSimpleDateFormat::processOverrideString(const Locale &locale, const UnicodeString &str, int8_t type, UErrorCode &status) {
109685bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    if (str.isBogus()) {
109785bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho        return;
109885bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    }
109985bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    int32_t start = 0;
110085bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    int32_t len;
110185bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    UnicodeString nsName;
110285bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    UnicodeString ovrField;
110385bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    UBool moreToProcess = TRUE;
110485bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho
110585bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    while (moreToProcess) {
1106b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho        int32_t delimiterPosition = str.indexOf((UChar)ULOC_KEYWORD_ITEM_SEPARATOR_UNICODE,start);
110785bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho        if (delimiterPosition == -1) {
110885bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho            moreToProcess = FALSE;
110985bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho            len = str.length() - start;
111085bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho        } else {
111185bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho            len = delimiterPosition - start;
111285bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho        }
111385bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho        UnicodeString currentString(str,start,len);
1114b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho        int32_t equalSignPosition = currentString.indexOf((UChar)ULOC_KEYWORD_ASSIGN_UNICODE,0);
111585bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho        if (equalSignPosition == -1) { // Simple override string such as "hebrew"
111685bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho            nsName.setTo(currentString);
111785bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho            ovrField.setToBogus();
111885bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho        } else { // Field specific override string such as "y=hebrew"
111985bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho            nsName.setTo(currentString,equalSignPosition+1);
112085bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho            ovrField.setTo(currentString,0,1); // We just need the first character.
112185bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho        }
112285bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho
112385bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho        int32_t nsNameHash = nsName.hashCode();
112485bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho        // See if the numbering system is in the override list, if not, then add it.
112585bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho        NSOverride *cur = fOverrideList;
112685bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho        NumberFormat *nf = NULL;
112785bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho        UBool found = FALSE;
112885bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho        while ( cur && !found ) {
112985bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho            if ( cur->hash == nsNameHash ) {
113085bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho                nf = cur->nf;
113185bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho                found = TRUE;
113285bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho            }
113385bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho            cur = cur->next;
113485bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho        }
113585bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho
113685bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho        if (!found) {
113785bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho           cur = (NSOverride *)uprv_malloc(sizeof(NSOverride));
113885bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho           if (cur) {
113985bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho               char kw[ULOC_KEYWORD_AND_VALUES_CAPACITY];
114085bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho               uprv_strcpy(kw,"numbers=");
114185bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho               nsName.extract(0,len,kw+8,ULOC_KEYWORD_AND_VALUES_CAPACITY-8,US_INV);
114285bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho
114385bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho               Locale ovrLoc(locale.getLanguage(),locale.getCountry(),locale.getVariant(),kw);
114485bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho               nf = NumberFormat::createInstance(ovrLoc,status);
114585bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho
114685bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho               // no matter what the locale's default number format looked like, we want
114785bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho               // to modify it so that it doesn't use thousands separators, doesn't always
114885bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho               // show the decimal point, and recognizes integers only when parsing
114985bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho
115085bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho               if (U_SUCCESS(status)) {
115185bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho                   nf->setGroupingUsed(FALSE);
115227f654740f2a26ad62a5c155af9199af9e69b889claireho                   DecimalFormat* decfmt = dynamic_cast<DecimalFormat*>(nf);
115327f654740f2a26ad62a5c155af9199af9e69b889claireho                   if (decfmt != NULL) {
115427f654740f2a26ad62a5c155af9199af9e69b889claireho                       decfmt->setDecimalSeparatorAlwaysShown(FALSE);
115527f654740f2a26ad62a5c155af9199af9e69b889claireho                   }
115685bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho                   nf->setParseIntegerOnly(TRUE);
115785bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho                   nf->setMinimumFractionDigits(0); // To prevent "Jan 1.00, 1997.00"
115885bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho
115985bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho                   cur->nf = nf;
116085bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho                   cur->hash = nsNameHash;
116185bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho                   cur->next = fOverrideList;
116285bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho                   fOverrideList = cur;
116385bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho               }
116485bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho               else {
116585bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho                   // clean up before returning
116685bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho                   if (cur != NULL) {
116785bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho                       uprv_free(cur);
116885bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho                   }
116985bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho                  return;
117085bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho               }
117185bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho
117285bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho           } else {
117385bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho               status = U_MEMORY_ALLOCATION_ERROR;
117485bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho               return;
117585bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho           }
117685bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho        }
117750294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho
117885bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho        // Now that we have an appropriate number formatter, fill in the appropriate spaces in the
117985bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho        // number formatters table.
118085bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho
118185bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho        if (ovrField.isBogus()) {
118285bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho            switch (type) {
118385bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho                case kOvrStrDate:
118485bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho                case kOvrStrBoth: {
118585bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho                    for ( int8_t i=0 ; i<kDateFieldsCount; i++ ) {
118685bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho                        fNumberFormatters[kDateFields[i]] = nf;
118785bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho                    }
118885bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho                    if (type==kOvrStrDate) {
118985bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho                        break;
119085bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho                    }
119185bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho                }
119285bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho                case kOvrStrTime : {
119385bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho                    for ( int8_t i=0 ; i<kTimeFieldsCount; i++ ) {
119485bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho                        fNumberFormatters[kTimeFields[i]] = nf;
119585bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho                    }
119685bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho                    break;
119785bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho                }
119885bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho            }
119985bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho        } else {
120085bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho           // if the pattern character is unrecognized, signal an error and bail out
120154dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius           UDateFormatField patternCharIndex =
120254dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius              DateFormatSymbols::getPatternCharIndex(ovrField.charAt(0));
120354dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius           if (patternCharIndex == UDAT_FIELD_COUNT) {
120485bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho               status = U_INVALID_FORMAT_ERROR;
120585bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho               return;
120685bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho           }
120785bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho
120885bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho           // Set the number formatter in the table
120985bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho           fNumberFormatters[patternCharIndex] = nf;
121085bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho        }
121185bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho
121285bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho        start = delimiterPosition + 1;
121385bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    }
121450294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho}
121554dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius
1216ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru//---------------------------------------------------------------------
1217ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queruvoid
1218ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste QueruSimpleDateFormat::subFormat(UnicodeString &appendTo,
1219ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                            UChar ch,
1220ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                            int32_t count,
122154dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius                            UDisplayContext capitalizationContext,
1222103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius                            int32_t fieldNum,
122350294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho                            FieldPositionHandler& handler,
1224ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                            Calendar& cal,
1225ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                            UErrorCode& status) const
1226ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru{
1227ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    if (U_FAILURE(status)) {
1228ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        return;
1229ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    }
1230ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
1231ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    // this function gets called by format() to produce the appropriate substitution
1232ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    // text for an individual pattern symbol (e.g., "HH" or "yyyy")
1233ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
123454dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius    UDateFormatField patternCharIndex = DateFormatSymbols::getPatternCharIndex(ch);
1235ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    const int32_t maxIntCount = 10;
1236ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    int32_t beginOffset = appendTo.length();
123785bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    NumberFormat *currentNumberFormat;
1238103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius    DateFormatSymbols::ECapitalizationContextUsageType capContextUsageType = DateFormatSymbols::kCapContextUsageOther;
1239ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
1240103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius    UBool isHebrewCalendar = (uprv_strcmp(cal.getType(),"hebrew") == 0);
124159d709d503bab6e2b61931737e662dd293b40578ccornelius    UBool isChineseCalendar = (uprv_strcmp(cal.getType(),"chinese") == 0 || uprv_strcmp(cal.getType(),"dangi") == 0);
124250294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho
1243ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    // if the pattern character is unrecognized, signal an error and dump out
124454dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius    if (patternCharIndex == UDAT_FIELD_COUNT)
1245ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    {
1246103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius        if (ch != 0x6C) { // pattern char 'l' (SMALL LETTER L) just gets ignored
1247103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius            status = U_INVALID_FORMAT_ERROR;
1248103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius        }
1249ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        return;
1250ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    }
1251ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
1252ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    UCalendarDateFields field = fgPatternIndexToCalendarField[patternCharIndex];
1253fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius    int32_t value = (patternCharIndex != UDAT_RELATED_YEAR_FIELD)? cal.get(field, status): cal.getRelatedYear(status);
1254ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    if (U_FAILURE(status)) {
1255ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        return;
1256ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    }
1257ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
125827f654740f2a26ad62a5c155af9199af9e69b889claireho    currentNumberFormat = getNumberFormatByIndex(patternCharIndex);
125954dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius    UnicodeString hebr("hebr", 4, US_INV);
126054dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius
1261ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    switch (patternCharIndex) {
126250294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho
1263ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    // for any "G" symbol, write out the appropriate era string
126485bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    // "GGGG" is wide era name, "GGGGG" is narrow era name, anything else is abbreviated name
1265ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    case UDAT_ERA_FIELD:
1266103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius        if (isChineseCalendar) {
1267103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius            zeroPaddingNumber(currentNumberFormat,appendTo, value, 1, 9); // as in ICU4J
1268103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius        } else {
1269103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius            if (count == 5) {
1270103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius                _appendSymbol(appendTo, value, fSymbols->fNarrowEras, fSymbols->fNarrowErasCount);
1271103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius                capContextUsageType = DateFormatSymbols::kCapContextUsageEraNarrow;
1272103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius            } else if (count == 4) {
1273103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius                _appendSymbol(appendTo, value, fSymbols->fEraNames, fSymbols->fEraNamesCount);
1274103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius                capContextUsageType = DateFormatSymbols::kCapContextUsageEraWide;
1275103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius            } else {
1276103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius                _appendSymbol(appendTo, value, fSymbols->fEras, fSymbols->fErasCount);
1277103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius                capContextUsageType = DateFormatSymbols::kCapContextUsageEraAbbrev;
1278103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius            }
1279103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius        }
1280ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        break;
1281ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
1282103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius     case UDAT_YEAR_NAME_FIELD:
1283103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius        if (fSymbols->fShortYearNames != NULL && value <= fSymbols->fShortYearNamesCount) {
1284103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius            // the Calendar YEAR field runs 1 through 60 for cyclic years
1285103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius            _appendSymbol(appendTo, value - 1, fSymbols->fShortYearNames, fSymbols->fShortYearNamesCount);
1286103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius            break;
1287103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius        }
1288103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius        // else fall through to numeric year handling, do not break here
1289103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius
1290103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius   // OLD: for "yyyy", write out the whole year; for "yy", write out the last 2 digits
129185bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    // NEW: UTS#35:
1292b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho//Year         y     yy     yyy     yyyy     yyyyy
1293b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho//AD 1         1     01     001     0001     00001
1294b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho//AD 12       12     12     012     0012     00012
1295b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho//AD 123     123     23     123     0123     00123
1296b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho//AD 1234   1234     34    1234     1234     01234
1297b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho//AD 12345 12345     45   12345    12345     12345
1298ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    case UDAT_YEAR_FIELD:
1299ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    case UDAT_YEAR_WOY_FIELD:
130054dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius        if (fDateOverride.compare(hebr)==0 && value>HEBREW_CAL_CUR_MILLENIUM_START_YEAR && value<HEBREW_CAL_CUR_MILLENIUM_END_YEAR) {
130154dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius            value-=HEBREW_CAL_CUR_MILLENIUM_START_YEAR;
130254dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius        }
130385bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho        if(count == 2)
130450294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho            zeroPaddingNumber(currentNumberFormat, appendTo, value, 2, 2);
130550294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho        else
130650294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho            zeroPaddingNumber(currentNumberFormat, appendTo, value, count, maxIntCount);
130750294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho        break;
1308ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
1309103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius    // for "MMMM"/"LLLL", write out the whole month name, for "MMM"/"LLL", write out the month
1310103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius    // abbreviation, for "M"/"L" or "MM"/"LL", write out the month as a number with the
1311ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    // appropriate number of digits
1312103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius    // for "MMMMM"/"LLLLL", use the narrow form
1313ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    case UDAT_MONTH_FIELD:
1314103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius    case UDAT_STANDALONE_MONTH_FIELD:
131550294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho        if ( isHebrewCalendar ) {
131650294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho           HebrewCalendar *hc = (HebrewCalendar*)&cal;
131750294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho           if (hc->isLeapYear(hc->get(UCAL_YEAR,status)) && value == 6 && count >= 3 )
131850294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho               value = 13; // Show alternate form for Adar II in leap years in Hebrew calendar.
131950294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho           if (!hc->isLeapYear(hc->get(UCAL_YEAR,status)) && value >= 6 && count < 3 )
132050294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho               value--; // Adjust the month number down 1 in Hebrew non-leap years, i.e. Adar is 6, not 7.
132150294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho        }
1322103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius        {
1323103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius            int32_t isLeapMonth = (fSymbols->fLeapMonthPatterns != NULL && fSymbols->fLeapMonthPatternsCount >= DateFormatSymbols::kMonthPatternsCount)?
1324103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius                        cal.get(UCAL_IS_LEAP_MONTH, status): 0;
1325103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius            // should consolidate the next section by using arrays of pointers & counts for the right symbols...
1326103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius            if (count == 5) {
1327103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius                if (patternCharIndex == UDAT_MONTH_FIELD) {
1328103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius                    _appendSymbolWithMonthPattern(appendTo, value, fSymbols->fNarrowMonths, fSymbols->fNarrowMonthsCount,
1329103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius                            (isLeapMonth!=0)? &(fSymbols->fLeapMonthPatterns[DateFormatSymbols::kLeapMonthPatternFormatNarrow]): NULL, status);
1330103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius                } else {
1331103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius                    _appendSymbolWithMonthPattern(appendTo, value, fSymbols->fStandaloneNarrowMonths, fSymbols->fStandaloneNarrowMonthsCount,
1332103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius                            (isLeapMonth!=0)? &(fSymbols->fLeapMonthPatterns[DateFormatSymbols::kLeapMonthPatternStandaloneNarrow]): NULL, status);
1333103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius                }
1334103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius                capContextUsageType = DateFormatSymbols::kCapContextUsageMonthNarrow;
1335103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius            } else if (count == 4) {
1336103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius                if (patternCharIndex == UDAT_MONTH_FIELD) {
1337103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius                    _appendSymbolWithMonthPattern(appendTo, value, fSymbols->fMonths, fSymbols->fMonthsCount,
1338103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius                            (isLeapMonth!=0)? &(fSymbols->fLeapMonthPatterns[DateFormatSymbols::kLeapMonthPatternFormatWide]): NULL, status);
1339103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius                    capContextUsageType = DateFormatSymbols::kCapContextUsageMonthFormat;
1340103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius                } else {
1341103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius                    _appendSymbolWithMonthPattern(appendTo, value, fSymbols->fStandaloneMonths, fSymbols->fStandaloneMonthsCount,
1342103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius                            (isLeapMonth!=0)? &(fSymbols->fLeapMonthPatterns[DateFormatSymbols::kLeapMonthPatternStandaloneWide]): NULL, status);
1343103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius                    capContextUsageType = DateFormatSymbols::kCapContextUsageMonthStandalone;
1344103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius                }
1345103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius            } else if (count == 3) {
1346103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius                if (patternCharIndex == UDAT_MONTH_FIELD) {
1347103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius                    _appendSymbolWithMonthPattern(appendTo, value, fSymbols->fShortMonths, fSymbols->fShortMonthsCount,
1348103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius                            (isLeapMonth!=0)? &(fSymbols->fLeapMonthPatterns[DateFormatSymbols::kLeapMonthPatternFormatAbbrev]): NULL, status);
1349103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius                    capContextUsageType = DateFormatSymbols::kCapContextUsageMonthFormat;
1350103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius                } else {
1351103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius                    _appendSymbolWithMonthPattern(appendTo, value, fSymbols->fStandaloneShortMonths, fSymbols->fStandaloneShortMonthsCount,
1352103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius                            (isLeapMonth!=0)? &(fSymbols->fLeapMonthPatterns[DateFormatSymbols::kLeapMonthPatternStandaloneAbbrev]): NULL, status);
1353103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius                    capContextUsageType = DateFormatSymbols::kCapContextUsageMonthStandalone;
1354103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius                }
1355103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius            } else {
1356103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius                UnicodeString monthNumber;
1357103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius                zeroPaddingNumber(currentNumberFormat,monthNumber, value + 1, count, maxIntCount);
1358103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius                _appendSymbolWithMonthPattern(appendTo, 0, &monthNumber, 1,
1359103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius                        (isLeapMonth!=0)? &(fSymbols->fLeapMonthPatterns[DateFormatSymbols::kLeapMonthPatternNumeric]): NULL, status);
1360103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius            }
1361103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius        }
1362ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        break;
1363ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
1364ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    // for "k" and "kk", write out the hour, adjusting midnight to appear as "24"
1365ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    case UDAT_HOUR_OF_DAY1_FIELD:
136650294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho        if (value == 0)
136785bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho            zeroPaddingNumber(currentNumberFormat,appendTo, cal.getMaximum(UCAL_HOUR_OF_DAY) + 1, count, maxIntCount);
136850294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho        else
136985bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho            zeroPaddingNumber(currentNumberFormat,appendTo, value, count, maxIntCount);
1370ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        break;
1371ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
1372ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    case UDAT_FRACTIONAL_SECOND_FIELD:
1373ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        // Fractional seconds left-justify
1374ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        {
137585bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho            currentNumberFormat->setMinimumIntegerDigits((count > 3) ? 3 : count);
137685bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho            currentNumberFormat->setMaximumIntegerDigits(maxIntCount);
1377ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            if (count == 1) {
137827f654740f2a26ad62a5c155af9199af9e69b889claireho                value /= 100;
1379ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            } else if (count == 2) {
138027f654740f2a26ad62a5c155af9199af9e69b889claireho                value /= 10;
1381ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            }
1382ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            FieldPosition p(0);
138385bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho            currentNumberFormat->format(value, appendTo, p);
1384ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            if (count > 3) {
138585bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho                currentNumberFormat->setMinimumIntegerDigits(count - 3);
138685bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho                currentNumberFormat->format((int32_t)0, appendTo, p);
1387ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            }
1388ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        }
1389ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        break;
1390ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
139185bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    // for "ee" or "e", use local numeric day-of-the-week
13928393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius    // for "EEEEEE" or "eeeeee", write out the short day-of-the-week name
139385bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    // for "EEEEE" or "eeeee", write out the narrow day-of-the-week name
139485bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    // for "EEEE" or "eeee", write out the wide day-of-the-week name
139585bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    // for "EEE" or "EE" or "E" or "eee", write out the abbreviated day-of-the-week name
139685bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    case UDAT_DOW_LOCAL_FIELD:
139785bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho        if ( count < 3 ) {
139885bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho            zeroPaddingNumber(currentNumberFormat,appendTo, value, count, maxIntCount);
139985bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho            break;
140085bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho        }
140185bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho        // fall through to EEEEE-EEE handling, but for that we don't want local day-of-week,
140285bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho        // we want standard day-of-week, so first fix value to work for EEEEE-EEE.
140385bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho        value = cal.get(UCAL_DAY_OF_WEEK, status);
140485bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho        if (U_FAILURE(status)) {
140585bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho            return;
140685bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho        }
140785bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho        // fall through, do not break here
1408ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    case UDAT_DAY_OF_WEEK_FIELD:
1409103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius        if (count == 5) {
1410ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            _appendSymbol(appendTo, value, fSymbols->fNarrowWeekdays,
1411ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                          fSymbols->fNarrowWeekdaysCount);
1412103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius            capContextUsageType = DateFormatSymbols::kCapContextUsageDayNarrow;
1413103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius        } else if (count == 4) {
1414ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            _appendSymbol(appendTo, value, fSymbols->fWeekdays,
1415ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                          fSymbols->fWeekdaysCount);
1416103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius            capContextUsageType = DateFormatSymbols::kCapContextUsageDayFormat;
14178393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius        } else if (count == 6) {
14188393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius            _appendSymbol(appendTo, value, fSymbols->fShorterWeekdays,
14198393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius                          fSymbols->fShorterWeekdaysCount);
14208393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius            capContextUsageType = DateFormatSymbols::kCapContextUsageDayFormat;
1421103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius        } else {
1422ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            _appendSymbol(appendTo, value, fSymbols->fShortWeekdays,
1423ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                          fSymbols->fShortWeekdaysCount);
1424103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius            capContextUsageType = DateFormatSymbols::kCapContextUsageDayFormat;
1425103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius        }
1426ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        break;
1427ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
1428ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    // for "ccc", write out the abbreviated day-of-the-week name
1429ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    // for "cccc", write out the wide day-of-the-week name
1430ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    // for "ccccc", use the narrow day-of-the-week name
14318393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius    // for "ccccc", use the short day-of-the-week name
1432ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    case UDAT_STANDALONE_DAY_FIELD:
143385bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho        if ( count < 3 ) {
143485bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho            zeroPaddingNumber(currentNumberFormat,appendTo, value, 1, maxIntCount);
143585bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho            break;
143685bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho        }
143785bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho        // fall through to alpha DOW handling, but for that we don't want local day-of-week,
143885bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho        // we want standard day-of-week, so first fix value.
143985bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho        value = cal.get(UCAL_DAY_OF_WEEK, status);
144085bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho        if (U_FAILURE(status)) {
144185bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho            return;
144285bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho        }
1443103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius        if (count == 5) {
1444ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            _appendSymbol(appendTo, value, fSymbols->fStandaloneNarrowWeekdays,
1445ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                          fSymbols->fStandaloneNarrowWeekdaysCount);
1446103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius            capContextUsageType = DateFormatSymbols::kCapContextUsageDayNarrow;
1447103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius        } else if (count == 4) {
1448ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            _appendSymbol(appendTo, value, fSymbols->fStandaloneWeekdays,
1449ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                          fSymbols->fStandaloneWeekdaysCount);
1450103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius            capContextUsageType = DateFormatSymbols::kCapContextUsageDayStandalone;
14518393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius        } else if (count == 6) {
14528393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius            _appendSymbol(appendTo, value, fSymbols->fStandaloneShorterWeekdays,
14538393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius                          fSymbols->fStandaloneShorterWeekdaysCount);
14548393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius            capContextUsageType = DateFormatSymbols::kCapContextUsageDayStandalone;
1455103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius        } else { // count == 3
1456ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            _appendSymbol(appendTo, value, fSymbols->fStandaloneShortWeekdays,
1457ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                          fSymbols->fStandaloneShortWeekdaysCount);
1458103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius            capContextUsageType = DateFormatSymbols::kCapContextUsageDayStandalone;
1459103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius        }
1460ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        break;
1461ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
1462ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    // for and "a" symbol, write out the whole AM/PM string
1463ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    case UDAT_AM_PM_FIELD:
1464ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        _appendSymbol(appendTo, value, fSymbols->fAmPms,
1465ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                      fSymbols->fAmPmsCount);
1466ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        break;
1467ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
1468ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    // for "h" and "hh", write out the hour, adjusting noon and midnight to show up
1469ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    // as "12"
1470ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    case UDAT_HOUR1_FIELD:
147150294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho        if (value == 0)
147285bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho            zeroPaddingNumber(currentNumberFormat,appendTo, cal.getLeastMaximum(UCAL_HOUR) + 1, count, maxIntCount);
147350294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho        else
147485bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho            zeroPaddingNumber(currentNumberFormat,appendTo, value, count, maxIntCount);
1475ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        break;
1476ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
14778393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius    case UDAT_TIMEZONE_FIELD: // 'z'
14788393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius    case UDAT_TIMEZONE_RFC_FIELD: // 'Z'
14798393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius    case UDAT_TIMEZONE_GENERIC_FIELD: // 'v'
14808393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius    case UDAT_TIMEZONE_SPECIAL_FIELD: // 'V'
14818393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius    case UDAT_TIMEZONE_LOCALIZED_GMT_OFFSET_FIELD: // 'O'
14828393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius    case UDAT_TIMEZONE_ISO_FIELD: // 'X'
14838393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius    case UDAT_TIMEZONE_ISO_LOCAL_FIELD: // 'x'
1484b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        {
1485b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru            UnicodeString zoneString;
1486b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho            const TimeZone& tz = cal.getTimeZone();
1487b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho            UDate date = cal.getTime(status);
1488b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho            if (U_SUCCESS(status)) {
14898393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius                if (patternCharIndex == UDAT_TIMEZONE_FIELD) {
1490b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                    if (count < 4) {
1491b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                        // "z", "zz", "zzz"
1492103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius                        tzFormat()->format(UTZFMT_STYLE_SPECIFIC_SHORT, tz, date, zoneString);
1493103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius                        capContextUsageType = DateFormatSymbols::kCapContextUsageMetazoneShort;
1494b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                    } else {
14958393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius                        // "zzzz" or longer
1496b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho                        tzFormat()->format(UTZFMT_STYLE_SPECIFIC_LONG, tz, date, zoneString);
1497103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius                        capContextUsageType = DateFormatSymbols::kCapContextUsageMetazoneLong;
1498ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                    }
14998393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius                }
15008393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius                else if (patternCharIndex == UDAT_TIMEZONE_RFC_FIELD) {
15018393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius                    if (count < 4) {
15028393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius                        // "Z"
15038393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius                        tzFormat()->format(UTZFMT_STYLE_ISO_BASIC_LOCAL_FULL, tz, date, zoneString);
15048393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius                    } else if (count == 5) {
15058393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius                        // "ZZZZZ"
15068393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius                        tzFormat()->format(UTZFMT_STYLE_ISO_EXTENDED_FULL, tz, date, zoneString);
15078393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius                    } else {
15088393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius                        // "ZZ", "ZZZ", "ZZZZ"
15098393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius                        tzFormat()->format(UTZFMT_STYLE_LOCALIZED_GMT, tz, date, zoneString);
15108393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius                    }
15118393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius                }
15128393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius                else if (patternCharIndex == UDAT_TIMEZONE_GENERIC_FIELD) {
1513b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                    if (count == 1) {
1514b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                        // "v"
1515b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho                        tzFormat()->format(UTZFMT_STYLE_GENERIC_SHORT, tz, date, zoneString);
1516103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius                        capContextUsageType = DateFormatSymbols::kCapContextUsageMetazoneShort;
1517b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                    } else if (count == 4) {
1518b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                        // "vvvv"
1519b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho                        tzFormat()->format(UTZFMT_STYLE_GENERIC_LONG, tz, date, zoneString);
1520103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius                        capContextUsageType = DateFormatSymbols::kCapContextUsageMetazoneLong;
1521ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                    }
15228393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius                }
15238393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius                else if (patternCharIndex == UDAT_TIMEZONE_SPECIAL_FIELD) {
1524b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                    if (count == 1) {
1525b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                        // "V"
15268393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius                        tzFormat()->format(UTZFMT_STYLE_ZONE_ID_SHORT, tz, date, zoneString);
15278393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius                    } else if (count == 2) {
15288393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius                        // "VV"
15298393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius                        tzFormat()->format(UTZFMT_STYLE_ZONE_ID, tz, date, zoneString);
15308393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius                    } else if (count == 3) {
15318393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius                        // "VVV"
15328393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius                        tzFormat()->format(UTZFMT_STYLE_EXEMPLAR_LOCATION, tz, date, zoneString);
1533b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                    } else if (count == 4) {
1534b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                        // "VVVV"
1535103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius                        tzFormat()->format(UTZFMT_STYLE_GENERIC_LOCATION, tz, date, zoneString);
1536103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius                        capContextUsageType = DateFormatSymbols::kCapContextUsageZoneLong;
1537ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                    }
1538ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                }
15398393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius                else if (patternCharIndex == UDAT_TIMEZONE_LOCALIZED_GMT_OFFSET_FIELD) {
15408393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius                    if (count == 1) {
15418393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius                        // "O"
15428393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius                        tzFormat()->format(UTZFMT_STYLE_LOCALIZED_GMT_SHORT, tz, date, zoneString);
15438393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius                    } else if (count == 4) {
15448393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius                        // "OOOO"
15458393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius                        tzFormat()->format(UTZFMT_STYLE_LOCALIZED_GMT, tz, date, zoneString);
15468393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius                    }
15478393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius                }
15488393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius                else if (patternCharIndex == UDAT_TIMEZONE_ISO_FIELD) {
15498393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius                    if (count == 1) {
15508393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius                        // "X"
15518393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius                        tzFormat()->format(UTZFMT_STYLE_ISO_BASIC_SHORT, tz, date, zoneString);
15528393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius                    } else if (count == 2) {
15538393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius                        // "XX"
15548393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius                        tzFormat()->format(UTZFMT_STYLE_ISO_BASIC_FIXED, tz, date, zoneString);
15558393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius                    } else if (count == 3) {
15568393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius                        // "XXX"
15578393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius                        tzFormat()->format(UTZFMT_STYLE_ISO_EXTENDED_FIXED, tz, date, zoneString);
15588393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius                    } else if (count == 4) {
15598393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius                        // "XXXX"
15608393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius                        tzFormat()->format(UTZFMT_STYLE_ISO_BASIC_FULL, tz, date, zoneString);
15618393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius                    } else if (count == 5) {
15628393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius                        // "XXXXX"
15638393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius                        tzFormat()->format(UTZFMT_STYLE_ISO_EXTENDED_FULL, tz, date, zoneString);
15648393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius                    }
15658393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius                }
15668393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius                else if (patternCharIndex == UDAT_TIMEZONE_ISO_LOCAL_FIELD) {
15678393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius                    if (count == 1) {
15688393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius                        // "x"
15698393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius                        tzFormat()->format(UTZFMT_STYLE_ISO_BASIC_LOCAL_SHORT, tz, date, zoneString);
15708393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius                    } else if (count == 2) {
15718393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius                        // "xx"
15728393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius                        tzFormat()->format(UTZFMT_STYLE_ISO_BASIC_LOCAL_FIXED, tz, date, zoneString);
15738393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius                    } else if (count == 3) {
15748393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius                        // "xxx"
15758393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius                        tzFormat()->format(UTZFMT_STYLE_ISO_EXTENDED_LOCAL_FIXED, tz, date, zoneString);
15768393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius                    } else if (count == 4) {
15778393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius                        // "xxxx"
15788393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius                        tzFormat()->format(UTZFMT_STYLE_ISO_BASIC_LOCAL_FULL, tz, date, zoneString);
15798393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius                    } else if (count == 5) {
15808393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius                        // "xxxxx"
15818393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius                        tzFormat()->format(UTZFMT_STYLE_ISO_EXTENDED_LOCAL_FULL, tz, date, zoneString);
15828393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius                    }
15838393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius                }
15848393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius                else {
15858393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius                    U_ASSERT(FALSE);
15868393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius                }
1587ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            }
1588103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius            appendTo += zoneString;
1589ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        }
1590ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        break;
1591ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
1592ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    case UDAT_QUARTER_FIELD:
159350294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho        if (count >= 4)
1594ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            _appendSymbol(appendTo, value/3, fSymbols->fQuarters,
1595ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                          fSymbols->fQuartersCount);
159650294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho        else if (count == 3)
1597ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            _appendSymbol(appendTo, value/3, fSymbols->fShortQuarters,
1598ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                          fSymbols->fShortQuartersCount);
159950294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho        else
160085bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho            zeroPaddingNumber(currentNumberFormat,appendTo, (value/3) + 1, count, maxIntCount);
1601ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        break;
1602ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
1603ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    case UDAT_STANDALONE_QUARTER_FIELD:
160450294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho        if (count >= 4)
1605ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            _appendSymbol(appendTo, value/3, fSymbols->fStandaloneQuarters,
1606ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                          fSymbols->fStandaloneQuartersCount);
160750294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho        else if (count == 3)
1608ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            _appendSymbol(appendTo, value/3, fSymbols->fStandaloneShortQuarters,
1609ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                          fSymbols->fStandaloneShortQuartersCount);
161050294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho        else
161185bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho            zeroPaddingNumber(currentNumberFormat,appendTo, (value/3) + 1, count, maxIntCount);
1612ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        break;
1613ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
1614ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
1615ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    // all of the other pattern symbols can be formatted as simple numbers with
1616ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    // appropriate zero padding
1617ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    default:
161885bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho        zeroPaddingNumber(currentNumberFormat,appendTo, value, count, maxIntCount);
1619ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        break;
1620ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    }
1621103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius#if !UCONFIG_NO_BREAK_ITERATION
1622fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius    // if first field, check to see whether we need to and are able to titlecase it
1623fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius    if (fieldNum == 0 && u_islower(appendTo.char32At(beginOffset)) && fCapitalizationBrkIter != NULL) {
1624103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius        UBool titlecase = FALSE;
1625103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius        switch (capitalizationContext) {
162654dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius            case UDISPCTX_CAPITALIZATION_FOR_BEGINNING_OF_SENTENCE:
1627103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius                titlecase = TRUE;
1628103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius                break;
162954dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius            case UDISPCTX_CAPITALIZATION_FOR_UI_LIST_OR_MENU:
163054dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius                titlecase = fSymbols->fCapitalization[capContextUsageType][0];
163154dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius                break;
163254dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius            case UDISPCTX_CAPITALIZATION_FOR_STANDALONE:
163354dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius                titlecase = fSymbols->fCapitalization[capContextUsageType][1];
163454dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius                break;
1635103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius            default:
1636103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius                // titlecase = FALSE;
1637103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius                break;
1638103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius        }
1639103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius        if (titlecase) {
1640103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius            UnicodeString firstField(appendTo, beginOffset);
1641fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius            firstField.toTitle(fCapitalizationBrkIter, fLocale, U_TITLECASE_NO_LOWERCASE | U_TITLECASE_NO_BREAK_ADJUSTMENT);
1642103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius            appendTo.replaceBetween(beginOffset, appendTo.length(), firstField);
1643103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius        }
1644103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius    }
1645103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius#endif
1646ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
164750294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    handler.addAttribute(fgPatternIndexToDateFormatField[patternCharIndex], beginOffset, appendTo.length());
1648ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru}
164950294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho
165085bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho//----------------------------------------------------------------------
165185bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho
165285bf2e2fbc60a9f938064abc8127d61da7d19882Claire HoNumberFormat *
165327f654740f2a26ad62a5c155af9199af9e69b889clairehoSimpleDateFormat::getNumberFormatByIndex(UDateFormatField index) const {
165485bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    if (fNumberFormatters != NULL) {
165585bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho        return fNumberFormatters[index];
165685bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    } else {
165785bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho        return fNumberFormat;
165885bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    }
165985bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho}
1660ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
1661ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru//----------------------------------------------------------------------
1662ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queruvoid
166350294ead5e5d23f5bbfed76e00e6b510bd41eee1clairehoSimpleDateFormat::zeroPaddingNumber(NumberFormat *currentNumberFormat,UnicodeString &appendTo,
166450294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho                                    int32_t value, int32_t minDigits, int32_t maxDigits) const
1665ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru{
166685bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    if (currentNumberFormat!=NULL) {
166785bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho        FieldPosition pos(0);
1668ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
166985bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho        currentNumberFormat->setMinimumIntegerDigits(minDigits);
167085bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho        currentNumberFormat->setMaximumIntegerDigits(maxDigits);
167185bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho        currentNumberFormat->format(value, appendTo, pos);  // 3rd arg is there to speed up processing
167285bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    }
1673ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru}
1674ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
1675ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru//----------------------------------------------------------------------
1676ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
1677ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru/**
1678ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru * Return true if the given format character, occuring count
1679ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru * times, represents a numeric field.
1680ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru */
1681ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste QueruUBool SimpleDateFormat::isNumeric(UChar formatChar, int32_t count) {
168254dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius    return DateFormatSymbols::isNumericPatternChar(formatChar, count);
168354dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius}
168454dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius
168554dcd9b6a06071f647dac967e9e267abb9410720Craig CorneliusUBool
168654dcd9b6a06071f647dac967e9e267abb9410720Craig CorneliusSimpleDateFormat::isAtNumericField(const UnicodeString &pattern, int32_t patternOffset) {
168754dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius    if (patternOffset >= pattern.length()) {
168854dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius        // not at any field
168954dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius        return FALSE;
169054dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius    }
169154dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius    UChar ch = pattern.charAt(patternOffset);
169254dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius    UDateFormatField f = DateFormatSymbols::getPatternCharIndex(ch);
169354dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius    if (f == UDAT_FIELD_COUNT) {
169454dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius        // not at any field
169554dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius        return FALSE;
169654dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius    }
169754dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius    int32_t i = patternOffset;
169854dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius    while (pattern.charAt(++i) == ch) {}
169954dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius    return DateFormatSymbols::isNumericField(f, i - patternOffset);
170054dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius}
170154dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius
170254dcd9b6a06071f647dac967e9e267abb9410720Craig CorneliusUBool
170354dcd9b6a06071f647dac967e9e267abb9410720Craig CorneliusSimpleDateFormat::isAfterNonNumericField(const UnicodeString &pattern, int32_t patternOffset) {
170454dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius    if (patternOffset <= 0) {
170554dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius        // not after any field
170654dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius        return FALSE;
170754dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius    }
170854dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius    UChar ch = pattern.charAt(--patternOffset);
170954dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius    UDateFormatField f = DateFormatSymbols::getPatternCharIndex(ch);
171054dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius    if (f == UDAT_FIELD_COUNT) {
171154dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius        // not after any field
171254dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius        return FALSE;
171354dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius    }
171454dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius    int32_t i = patternOffset;
171554dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius    while (pattern.charAt(--i) == ch) {}
171654dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius    return !DateFormatSymbols::isNumericField(f, patternOffset - i);
1717ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru}
1718ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
1719ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queruvoid
1720ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste QueruSimpleDateFormat::parse(const UnicodeString& text, Calendar& cal, ParsePosition& parsePos) const
1721ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru{
172285bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    UErrorCode status = U_ZERO_ERROR;
1723ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    int32_t pos = parsePos.getIndex();
1724ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    int32_t start = pos;
172585bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho
1726ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    UBool ambiguousYear[] = { FALSE };
172750294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    int32_t saveHebrewMonth = -1;
1728ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    int32_t count = 0;
1729fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius    UTimeZoneFormatTimeType tzTimeType = UTZFMT_TIME_TYPE_UNKNOWN;
1730ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
1731ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    // For parsing abutting numeric fields. 'abutPat' is the
1732ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    // offset into 'pattern' of the first of 2 or more abutting
1733ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    // numeric fields.  'abutStart' is the offset into 'text'
1734ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    // where parsing the fields begins. 'abutPass' starts off as 0
1735ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    // and increments each time we try to parse the fields.
1736ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    int32_t abutPat = -1; // If >=0, we are in a run of abutting numeric fields
1737ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    int32_t abutStart = 0;
1738ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    int32_t abutPass = 0;
1739ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    UBool inQuote = FALSE;
1740ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
1741103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius    MessageFormat * numericLeapMonthFormatter = NULL;
1742ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
1743103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius    Calendar* calClone = NULL;
174485bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    Calendar *workCal = &cal;
174585bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    if (&cal != fCalendar && uprv_strcmp(cal.getType(), fCalendar->getType()) != 0) {
174685bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho        // Different calendar type
174785bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho        // We use the time/zone from the input calendar, but
174885bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho        // do not use the input calendar for field calculation.
1749103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius        calClone = fCalendar->clone();
1750103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius        if (calClone != NULL) {
1751103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius            calClone->setTime(cal.getTime(status),status);
1752103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius            if (U_FAILURE(status)) {
1753103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius                goto ExitParse;
1754103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius            }
1755103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius            calClone->setTimeZone(cal.getTimeZone());
1756103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius            workCal = calClone;
1757103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius        } else {
1758103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius            status = U_MEMORY_ALLOCATION_ERROR;
175985bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho            goto ExitParse;
176085bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho        }
1761103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius    }
1762103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius
1763103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius    if (fSymbols->fLeapMonthPatterns != NULL && fSymbols->fLeapMonthPatternsCount >= DateFormatSymbols::kMonthPatternsCount) {
1764103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius        numericLeapMonthFormatter = new MessageFormat(fSymbols->fLeapMonthPatterns[DateFormatSymbols::kLeapMonthPatternNumeric], fLocale, status);
1765103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius        if (numericLeapMonthFormatter == NULL) {
1766103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius             status = U_MEMORY_ALLOCATION_ERROR;
1767103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius             goto ExitParse;
1768103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius        } else if (U_FAILURE(status)) {
1769103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius             goto ExitParse; // this will delete numericLeapMonthFormatter
1770103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius        }
177185bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    }
177285bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho
1773ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    for (int32_t i=0; i<fPattern.length(); ++i) {
1774ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        UChar ch = fPattern.charAt(i);
1775ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
1776ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        // Handle alphabetic field characters.
1777ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        if (!inQuote && ((ch >= 0x41 && ch <= 0x5A) || (ch >= 0x61 && ch <= 0x7A))) { // [A-Za-z]
1778ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            int32_t fieldPat = i;
1779ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
1780ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            // Count the length of this field specifier
1781ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            count = 1;
1782ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            while ((i+1)<fPattern.length() &&
1783ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                   fPattern.charAt(i+1) == ch) {
1784ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                ++count;
1785ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                ++i;
1786ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            }
1787ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
1788ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            if (isNumeric(ch, count)) {
1789ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                if (abutPat < 0) {
179054dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius                    // Determine if there is an abutting numeric field.
179154dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius                    // Record the start of a set of abutting numeric fields.
179254dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius                    if (isAtNumericField(fPattern, i + 1)) {
179354dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius                        abutPat = fieldPat;
179454dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius                        abutStart = pos;
179554dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius                        abutPass = 0;
1796ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                    }
1797ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                }
1798ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            } else {
1799ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                abutPat = -1; // End of any abutting fields
1800ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            }
1801ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
1802ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            // Handle fields within a run of abutting numeric fields.  Take
1803ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            // the pattern "HHmmss" as an example. We will try to parse
1804ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            // 2/2/2 characters of the input text, then if that fails,
1805ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            // 1/2/2.  We only adjust the width of the leftmost field; the
1806ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            // others remain fixed.  This allows "123456" => 12:34:56, but
1807ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            // "12345" => 1:23:45.  Likewise, for the pattern "yyyyMMdd" we
1808ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            // try 4/2/2, 3/2/2, 2/2/2, and finally 1/2/2.
1809ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            if (abutPat >= 0) {
1810ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                // If we are at the start of a run of abutting fields, then
1811ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                // shorten this field in each pass.  If we can't shorten
1812ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                // this field any more, then the parse of this set of
1813ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                // abutting numeric fields has failed.
1814ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                if (fieldPat == abutPat) {
1815ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                    count -= abutPass++;
1816ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                    if (count == 0) {
181785bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho                        status = U_PARSE_ERROR;
181885bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho                        goto ExitParse;
1819ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                    }
1820ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                }
1821ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
1822ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                pos = subParse(text, pos, ch, count,
1823fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius                               TRUE, FALSE, ambiguousYear, saveHebrewMonth, *workCal, i, numericLeapMonthFormatter, &tzTimeType);
1824ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
1825ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                // If the parse fails anywhere in the run, back up to the
1826ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                // start of the run and retry.
1827ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                if (pos < 0) {
1828ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                    i = abutPat - 1;
1829ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                    pos = abutStart;
1830ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                    continue;
1831ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                }
1832ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            }
1833ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
1834ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            // Handle non-numeric fields and non-abutting numeric
1835ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            // fields.
1836103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius            else if (ch != 0x6C) { // pattern char 'l' (SMALL LETTER L) just gets ignored
183785bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho                int32_t s = subParse(text, pos, ch, count,
1838fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius                               FALSE, TRUE, ambiguousYear, saveHebrewMonth, *workCal, i, numericLeapMonthFormatter, &tzTimeType);
1839ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
184027f654740f2a26ad62a5c155af9199af9e69b889claireho                if (s == -pos-1) {
184127f654740f2a26ad62a5c155af9199af9e69b889claireho                    // era not present, in special cases allow this to continue
184254dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius                    // from the position where the era was expected
184354dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius                    s = pos;
184427f654740f2a26ad62a5c155af9199af9e69b889claireho
184527f654740f2a26ad62a5c155af9199af9e69b889claireho                    if (i+1 < fPattern.length()) {
184627f654740f2a26ad62a5c155af9199af9e69b889claireho                        // move to next pattern character
184727f654740f2a26ad62a5c155af9199af9e69b889claireho                        UChar ch = fPattern.charAt(i+1);
184827f654740f2a26ad62a5c155af9199af9e69b889claireho
184927f654740f2a26ad62a5c155af9199af9e69b889claireho                        // check for whitespace
1850b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho                        if (PatternProps::isWhiteSpace(ch)) {
185127f654740f2a26ad62a5c155af9199af9e69b889claireho                            i++;
185227f654740f2a26ad62a5c155af9199af9e69b889claireho                            // Advance over run in pattern
185327f654740f2a26ad62a5c155af9199af9e69b889claireho                            while ((i+1)<fPattern.length() &&
1854b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho                                   PatternProps::isWhiteSpace(fPattern.charAt(i+1))) {
185527f654740f2a26ad62a5c155af9199af9e69b889claireho                                ++i;
185627f654740f2a26ad62a5c155af9199af9e69b889claireho                            }
185727f654740f2a26ad62a5c155af9199af9e69b889claireho                        }
185827f654740f2a26ad62a5c155af9199af9e69b889claireho                    }
185927f654740f2a26ad62a5c155af9199af9e69b889claireho                }
1860b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho                else if (s <= 0) {
186185bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho                    status = U_PARSE_ERROR;
186285bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho                    goto ExitParse;
1863ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                }
186485bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho                pos = s;
1865ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            }
1866ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        }
1867ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
1868ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        // Handle literal pattern characters.  These are any
1869ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        // quoted characters and non-alphabetic unquoted
1870ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        // characters.
1871ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        else {
187250294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho
1873ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            abutPat = -1; // End of any abutting fields
1874b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho
1875fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius            if (! matchLiterals(fPattern, i, text, pos, getBooleanAttribute(UDAT_PARSE_ALLOW_WHITESPACE, status), getBooleanAttribute(UDAT_PARSE_PARTIAL_MATCH, status))) {
1876b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho                status = U_PARSE_ERROR;
1877b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho                goto ExitParse;
1878ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            }
1879ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        }
1880ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    }
1881ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
188254dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius    // Special hack for trailing "." after non-numeric field.
188359d709d503bab6e2b61931737e662dd293b40578ccornelius    if (text.charAt(pos) == 0x2e && getBooleanAttribute(UDAT_PARSE_ALLOW_WHITESPACE, status)) {
188454dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius        // only do if the last field is not numeric
188554dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius        if (isAfterNonNumericField(fPattern, fPattern.length())) {
188654dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius            pos++; // skip the extra "."
188754dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius        }
188854dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius    }
188954dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius
1890ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    // At this point the fields of Calendar have been set.  Calendar
1891ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    // will fill in default values for missing fields when the time
1892ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    // is computed.
1893ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
1894ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    parsePos.setIndex(pos);
1895ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
1896ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    // This part is a problem:  When we call parsedDate.after, we compute the time.
1897ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    // Take the date April 3 2004 at 2:30 am.  When this is first set up, the year
1898ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    // will be wrong if we're parsing a 2-digit year pattern.  It will be 1904.
1899ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    // April 3 1904 is a Sunday (unlike 2004) so it is the DST onset day.  2:30 am
1900ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    // is therefore an "impossible" time, since the time goes from 1:59 to 3:00 am
1901ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    // on that day.  It is therefore parsed out to fields as 3:30 am.  Then we
1902ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    // add 100 years, and get April 3 2004 at 3:30 am.  Note that April 3 2004 is
1903ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    // a Saturday, so it can have a 2:30 am -- and it should. [LIU]
1904ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    /*
1905ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        UDate parsedDate = calendar.getTime();
1906ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        if( ambiguousYear[0] && !parsedDate.after(fDefaultCenturyStart) ) {
1907ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            calendar.add(Calendar.YEAR, 100);
1908ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            parsedDate = calendar.getTime();
1909ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        }
1910ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    */
1911ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    // Because of the above condition, save off the fields in case we need to readjust.
1912ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    // The procedure we use here is not particularly efficient, but there is no other
1913ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    // way to do this given the API restrictions present in Calendar.  We minimize
1914ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    // inefficiency by only performing this computation when it might apply, that is,
1915ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    // when the two-digit year is equal to the start year, and thus might fall at the
1916ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    // front or the back of the default century.  This only works because we adjust
1917ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    // the year correctly to start with in other cases -- see subParse().
1918fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius    if (ambiguousYear[0] || tzTimeType != UTZFMT_TIME_TYPE_UNKNOWN) // If this is true then the two-digit year == the default start year
1919ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    {
1920ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        // We need a copy of the fields, and we need to avoid triggering a call to
1921ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        // complete(), which will recalculate the fields.  Since we can't access
1922ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        // the fields[] array in Calendar, we clone the entire object.  This will
1923ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        // stop working if Calendar.clone() is ever rewritten to call complete().
1924b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        Calendar *copy;
1925ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        if (ambiguousYear[0]) {
1926b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru            copy = cal.clone();
192785bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho            // Check for failed cloning.
192885bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho            if (copy == NULL) {
1929b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho                status = U_MEMORY_ALLOCATION_ERROR;
1930b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho                goto ExitParse;
193185bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho            }
1932ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            UDate parsedDate = copy->getTime(status);
1933ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            // {sfb} check internalGetDefaultCenturyStart
1934ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            if (fHaveDefaultCentury && (parsedDate < fDefaultCenturyStart)) {
1935ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                // We can't use add here because that does a complete() first.
1936ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                cal.set(UCAL_YEAR, fDefaultCenturyStartYear + 100);
1937ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            }
1938b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru            delete copy;
1939ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        }
1940ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
1941fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius        if (tzTimeType != UTZFMT_TIME_TYPE_UNKNOWN) {
1942b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru            copy = cal.clone();
194385bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho            // Check for failed cloning.
194485bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho            if (copy == NULL) {
1945b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho                status = U_MEMORY_ALLOCATION_ERROR;
1946b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho                goto ExitParse;
194785bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho            }
1948b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru            const TimeZone & tz = cal.getTimeZone();
1949b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru            BasicTimeZone *btz = NULL;
1950ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
195127f654740f2a26ad62a5c155af9199af9e69b889claireho            if (dynamic_cast<const OlsonTimeZone *>(&tz) != NULL
195227f654740f2a26ad62a5c155af9199af9e69b889claireho                || dynamic_cast<const SimpleTimeZone *>(&tz) != NULL
195327f654740f2a26ad62a5c155af9199af9e69b889claireho                || dynamic_cast<const RuleBasedTimeZone *>(&tz) != NULL
195427f654740f2a26ad62a5c155af9199af9e69b889claireho                || dynamic_cast<const VTimeZone *>(&tz) != NULL) {
1955b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                btz = (BasicTimeZone*)&tz;
1956ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            }
1957ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
1958b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru            // Get local millis
1959b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru            copy->set(UCAL_ZONE_OFFSET, 0);
1960b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru            copy->set(UCAL_DST_OFFSET, 0);
1961b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru            UDate localMillis = copy->getTime(status);
1962b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
1963b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru            // Make sure parsed time zone type (Standard or Daylight)
1964b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru            // matches the rule used by the parsed time zone.
1965b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru            int32_t raw, dst;
1966b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru            if (btz != NULL) {
1967fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius                if (tzTimeType == UTZFMT_TIME_TYPE_STANDARD) {
1968b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                    btz->getOffsetFromLocal(localMillis,
1969b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                        BasicTimeZone::kStandard, BasicTimeZone::kStandard, raw, dst, status);
1970b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                } else {
1971b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                    btz->getOffsetFromLocal(localMillis,
1972b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                        BasicTimeZone::kDaylight, BasicTimeZone::kDaylight, raw, dst, status);
1973b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                }
1974b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru            } else {
1975b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                // No good way to resolve ambiguous time at transition,
1976b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                // but following code work in most case.
1977b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                tz.getOffset(localMillis, TRUE, raw, dst, status);
1978b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru            }
1979b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
1980b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru            // Now, compare the results with parsed type, either standard or daylight saving time
1981b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru            int32_t resolvedSavings = dst;
1982fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius            if (tzTimeType == UTZFMT_TIME_TYPE_STANDARD) {
1983b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                if (dst != 0) {
1984b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                    // Override DST_OFFSET = 0 in the result calendar
1985b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                    resolvedSavings = 0;
1986b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                }
1987b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru            } else { // tztype == TZTYPE_DST
1988b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                if (dst == 0) {
1989b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                    if (btz != NULL) {
1990b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                        UDate time = localMillis + raw;
1991b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                        // We use the nearest daylight saving time rule.
1992b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                        TimeZoneTransition beforeTrs, afterTrs;
1993b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                        UDate beforeT = time, afterT = time;
1994b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                        int32_t beforeSav = 0, afterSav = 0;
1995b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                        UBool beforeTrsAvail, afterTrsAvail;
1996b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
1997b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                        // Search for DST rule before or on the time
1998b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                        while (TRUE) {
1999b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                            beforeTrsAvail = btz->getPreviousTransition(beforeT, TRUE, beforeTrs);
2000b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                            if (!beforeTrsAvail) {
2001b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                                break;
2002b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                            }
2003b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                            beforeT = beforeTrs.getTime() - 1;
2004b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                            beforeSav = beforeTrs.getFrom()->getDSTSavings();
2005b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                            if (beforeSav != 0) {
2006b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                                break;
2007b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                            }
2008b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                        }
2009b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
2010b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                        // Search for DST rule after the time
2011b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                        while (TRUE) {
2012b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                            afterTrsAvail = btz->getNextTransition(afterT, FALSE, afterTrs);
2013b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                            if (!afterTrsAvail) {
2014b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                                break;
2015b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                            }
2016b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                            afterT = afterTrs.getTime();
2017b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                            afterSav = afterTrs.getTo()->getDSTSavings();
2018b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                            if (afterSav != 0) {
2019b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                                break;
2020b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                            }
2021b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                        }
2022b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
2023b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                        if (beforeTrsAvail && afterTrsAvail) {
2024b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                            if (time - beforeT > afterT - time) {
2025b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                                resolvedSavings = afterSav;
2026b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                            } else {
2027b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                                resolvedSavings = beforeSav;
2028b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                            }
2029b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                        } else if (beforeTrsAvail && beforeSav != 0) {
2030b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                            resolvedSavings = beforeSav;
2031b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                        } else if (afterTrsAvail && afterSav != 0) {
2032b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                            resolvedSavings = afterSav;
2033b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                        } else {
2034b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                            resolvedSavings = btz->getDSTSavings();
2035b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                        }
2036b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                    } else {
2037b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                        resolvedSavings = tz.getDSTSavings();
2038b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                    }
2039b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                    if (resolvedSavings == 0) {
2040b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                        // final fallback
2041b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                        resolvedSavings = U_MILLIS_PER_HOUR;
2042b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                    }
2043b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                }
2044b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru            }
2045b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru            cal.set(UCAL_ZONE_OFFSET, raw);
2046b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru            cal.set(UCAL_DST_OFFSET, resolvedSavings);
2047b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru            delete copy;
2048b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        }
2049ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    }
205085bf2e2fbc60a9f938064abc8127d61da7d19882Claire HoExitParse:
205185bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    // Set the parsed result if local calendar is used
205285bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    // instead of the input calendar
205385bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    if (U_SUCCESS(status) && workCal != &cal) {
205485bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho        cal.setTimeZone(workCal->getTimeZone());
205585bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho        cal.setTime(workCal->getTime(status), status);
205685bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    }
205785bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho
2058103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius    if (numericLeapMonthFormatter != NULL) {
2059103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius        delete numericLeapMonthFormatter;
2060103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius    }
2061103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius    if (calClone != NULL) {
2062103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius        delete calClone;
206385bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    }
2064ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
2065ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    // If any Calendar calls failed, we pretend that we
2066ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    // couldn't parse the string, when in reality this isn't quite accurate--
2067ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    // we did parse it; the Calendar calls just failed.
206850294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    if (U_FAILURE(status)) {
2069ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        parsePos.setErrorIndex(pos);
207085bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho        parsePos.setIndex(start);
2071ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    }
2072ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru}
2073ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
2074ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru//----------------------------------------------------------------------
2075ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
207654dcd9b6a06071f647dac967e9e267abb9410720Craig Corneliusstatic UBool
207754dcd9b6a06071f647dac967e9e267abb9410720Craig CorneliusnewBestMatchWithOptionalDot(const UnicodeString &lcaseText,
207854dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius                            const UnicodeString &data,
207954dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius                            UnicodeString &bestMatchName,
208054dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius                            int32_t &bestMatchLength);
208154dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius
2082ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queruint32_t SimpleDateFormat::matchQuarterString(const UnicodeString& text,
2083ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                              int32_t start,
2084ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                              UCalendarDateFields field,
2085ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                              const UnicodeString* data,
2086ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                              int32_t dataCount,
2087ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                              Calendar& cal) const
2088ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru{
2089ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    int32_t i = 0;
2090ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    int32_t count = dataCount;
2091ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
2092ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    // There may be multiple strings in the data[] array which begin with
2093ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    // the same prefix (e.g., Cerven and Cervenec (June and July) in Czech).
2094ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    // We keep track of the longest match, and return that.  Note that this
2095ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    // unfortunately requires us to test all array elements.
2096ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    int32_t bestMatchLength = 0, bestMatch = -1;
209754dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius    UnicodeString bestMatchName;
2098ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
2099ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    // {sfb} kludge to support case-insensitive comparison
2100ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    // {markus 2002oct11} do not just use caseCompareBetween because we do not know
2101ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    // the length of the match after case folding
2102ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    // {alan 20040607} don't case change the whole string, since the length
2103ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    // can change
2104ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    // TODO we need a case-insensitive startsWith function
210554dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius    UnicodeString lcaseText;
2106ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    text.extract(start, INT32_MAX, lcaseText);
2107ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    lcaseText.foldCase();
2108ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
2109ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    for (; i < count; ++i)
2110ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    {
2111ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        // Always compare if we have no match yet; otherwise only compare
2112ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        // against potentially better matches (longer strings).
2113ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
211454dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius        if (newBestMatchWithOptionalDot(lcaseText, data[i], bestMatchName, bestMatchLength)) {
2115ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            bestMatch = i;
2116ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        }
2117ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    }
2118ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    if (bestMatch >= 0)
2119ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    {
2120ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        cal.set(field, bestMatch * 3);
2121ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
2122ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        // Once we have a match, we have to determine the length of the
2123ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        // original source string.  This will usually be == the length of
2124ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        // the case folded string, but it may differ (e.g. sharp s).
2125ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
2126ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        // Most of the time, the length will be the same as the length
2127ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        // of the string from the locale data.  Sometimes it will be
2128ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        // different, in which case we will have to figure it out by
2129ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        // adding a character at a time, until we have a match.  We do
2130ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        // this all in one loop, where we try 'len' first (at index
2131ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        // i==0).
213254dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius        int32_t len = bestMatchName.length(); // 99+% of the time
2133ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        int32_t n = text.length() - start;
2134ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        for (i=0; i<=n; ++i) {
2135ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            int32_t j=i;
2136ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            if (i == 0) {
2137ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                j = len;
2138ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            } else if (i == len) {
2139ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                continue; // already tried this when i was 0
2140ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            }
2141ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            text.extract(start, j, lcaseText);
2142ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            lcaseText.foldCase();
214354dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius            if (bestMatchName == lcaseText) {
2144ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                return start + j;
2145ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            }
2146ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        }
2147ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    }
214850294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho
2149ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    return -start;
2150ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru}
2151ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
2152ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru//----------------------------------------------------------------------
2153b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2clairehoUBool SimpleDateFormat::matchLiterals(const UnicodeString &pattern,
2154b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho                                      int32_t &patternOffset,
2155b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho                                      const UnicodeString &text,
2156b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho                                      int32_t &textOffset,
2157fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius                                      UBool whitespaceLenient,
2158fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius                                      UBool partialMatchLenient)
2159b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho{
2160b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho    UBool inQuote = FALSE;
2161b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho    UnicodeString literal;
2162b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho    int32_t i = patternOffset;
2163b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho
2164b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho    // scan pattern looking for contiguous literal characters
2165b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho    for ( ; i < pattern.length(); i += 1) {
2166b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho        UChar ch = pattern.charAt(i);
2167b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho
2168b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho        if (!inQuote && ((ch >= 0x41 && ch <= 0x5A) || (ch >= 0x61 && ch <= 0x7A))) { // unquoted [A-Za-z]
2169b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho            break;
2170b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho        }
2171b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho
2172b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho        if (ch == QUOTE) {
2173b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho            // Match a quote literal ('') inside OR outside of quotes
2174b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho            if ((i + 1) < pattern.length() && pattern.charAt(i + 1) == QUOTE) {
2175b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho                i += 1;
2176b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho            } else {
2177b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho                inQuote = !inQuote;
2178b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho                continue;
2179b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho            }
2180b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho        }
2181b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho
2182b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho        literal += ch;
2183b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho    }
2184b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho
2185b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho    // at this point, literal contains the literal text
2186b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho    // and i is the index of the next non-literal pattern character.
2187b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho    int32_t p;
2188b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho    int32_t t = textOffset;
2189b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho
2190fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius    if (whitespaceLenient) {
2191b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho        // trim leading, trailing whitespace from
2192b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho        // the literal text
2193b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho        literal.trim();
2194b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho
2195b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho        // ignore any leading whitespace in the text
2196b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho        while (t < text.length() && u_isWhitespace(text.charAt(t))) {
2197b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho            t += 1;
2198b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho        }
2199b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho    }
2200b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho
220154dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius    for (p = 0; p < literal.length() && t < text.length();) {
2202b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho        UBool needWhitespace = FALSE;
2203b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho
2204b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho        while (p < literal.length() && PatternProps::isWhiteSpace(literal.charAt(p))) {
2205b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho            needWhitespace = TRUE;
2206b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho            p += 1;
2207b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho        }
2208b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho
2209b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho        if (needWhitespace) {
2210b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho            int32_t tStart = t;
2211b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho
2212b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho            while (t < text.length()) {
2213b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho                UChar tch = text.charAt(t);
2214b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho
2215b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho                if (!u_isUWhiteSpace(tch) && !PatternProps::isWhiteSpace(tch)) {
2216b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho                    break;
2217b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho                }
2218b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho
2219b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho                t += 1;
2220b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho            }
2221b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho
2222b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho            // TODO: should we require internal spaces
2223b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho            // in lenient mode? (There won't be any
2224b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho            // leading or trailing spaces)
2225fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius            if (!whitespaceLenient && t == tStart) {
2226b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho                // didn't find matching whitespace:
2227b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho                // an error in strict mode
2228b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho                return FALSE;
2229b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho            }
2230b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho
2231b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho            // In strict mode, this run of whitespace
2232b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho            // may have been at the end.
2233b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho            if (p >= literal.length()) {
2234b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho                break;
2235b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho            }
2236b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho        }
2237b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho
2238b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho        if (t >= text.length() || literal.charAt(p) != text.charAt(t)) {
2239b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho            // Ran out of text, or found a non-matching character:
2240b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho            // OK in lenient mode, an error in strict mode.
2241fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius            if (whitespaceLenient) {
224254dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius                if (t == textOffset && text.charAt(t) == 0x2e &&
224354dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius                        isAfterNonNumericField(pattern, patternOffset)) {
224454dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius                    // Lenient mode and the literal input text begins with a "." and
224554dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius                    // we are after a non-numeric field: We skip the "."
224654dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius                    ++t;
224754dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius                    continue;  // Do not update p.
224854dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius                }
2249fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius                // if it is actual whitespace and we're whitespace lenient it's OK
2250fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius                UChar wsc = text.charAt(t);
2251fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius                if(PatternProps::isWhiteSpace(wsc))
2252fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius                    break;
2253fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius            }
2254fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius            // or if we're partial match lenient it's OK
2255fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius            if(partialMatchLenient) {
2256b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho                break;
2257b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho            }
2258fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius
2259b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho            return FALSE;
2260b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho        }
226154dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius        ++p;
226254dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius        ++t;
2263b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho    }
2264b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho
2265b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho    // At this point if we're in strict mode we have a complete match.
2266b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho    // If we're in lenient mode we may have a partial match, or no
2267b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho    // match at all.
2268b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho    if (p <= 0) {
2269b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho        // no match. Pretend it matched a run of whitespace
2270b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho        // and ignorables in the text.
2271b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho        const  UnicodeSet *ignorables = NULL;
227254dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius        UDateFormatField patternCharIndex = DateFormatSymbols::getPatternCharIndex(pattern.charAt(i));
227354dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius        if (patternCharIndex != UDAT_FIELD_COUNT) {
2274b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho            ignorables = SimpleDateFormatStaticSets::getIgnorables(patternCharIndex);
2275b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho        }
2276b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho
2277b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho        for (t = textOffset; t < text.length(); t += 1) {
2278b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho            UChar ch = text.charAt(t);
2279b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho
2280b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho            if (ignorables == NULL || !ignorables->contains(ch)) {
2281b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho                break;
2282b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho            }
2283b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho        }
2284b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho    }
2285b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho
2286b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho    // if we get here, we've got a complete match.
2287b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho    patternOffset = i - 1;
2288b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho    textOffset = t;
2289b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho
2290b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho    return TRUE;
2291b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho}
2292b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho
2293b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho//----------------------------------------------------------------------
2294ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
2295ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queruint32_t SimpleDateFormat::matchString(const UnicodeString& text,
2296ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                              int32_t start,
2297ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                              UCalendarDateFields field,
2298ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                              const UnicodeString* data,
2299ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                              int32_t dataCount,
2300103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius                              const UnicodeString* monthPattern,
2301ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                              Calendar& cal) const
2302ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru{
2303ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    int32_t i = 0;
2304ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    int32_t count = dataCount;
2305ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
2306ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    if (field == UCAL_DAY_OF_WEEK) i = 1;
2307ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
2308ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    // There may be multiple strings in the data[] array which begin with
2309ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    // the same prefix (e.g., Cerven and Cervenec (June and July) in Czech).
2310ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    // We keep track of the longest match, and return that.  Note that this
2311ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    // unfortunately requires us to test all array elements.
2312ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    int32_t bestMatchLength = 0, bestMatch = -1;
2313103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius    UnicodeString bestMatchName;
2314103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius    int32_t isLeapMonth = 0;
2315ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
2316ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    // {sfb} kludge to support case-insensitive comparison
2317ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    // {markus 2002oct11} do not just use caseCompareBetween because we do not know
2318ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    // the length of the match after case folding
2319ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    // {alan 20040607} don't case change the whole string, since the length
2320ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    // can change
2321ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    // TODO we need a case-insensitive startsWith function
232254dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius    UnicodeString lcaseText;
2323ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    text.extract(start, INT32_MAX, lcaseText);
2324ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    lcaseText.foldCase();
2325ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
2326ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    for (; i < count; ++i)
2327ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    {
2328ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        // Always compare if we have no match yet; otherwise only compare
2329ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        // against potentially better matches (longer strings).
2330ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
233154dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius        if (newBestMatchWithOptionalDot(lcaseText, data[i], bestMatchName, bestMatchLength)) {
2332ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            bestMatch = i;
2333103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius            isLeapMonth = 0;
2334103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius        }
2335103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius
2336103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius        if (monthPattern != NULL) {
2337103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius            UErrorCode status = U_ZERO_ERROR;
2338103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius            UnicodeString leapMonthName;
2339103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius            Formattable monthName((const UnicodeString&)(data[i]));
2340103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius            MessageFormat::format(*monthPattern, &monthName, 1, leapMonthName, status);
2341103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius            if (U_SUCCESS(status)) {
234254dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius                if (newBestMatchWithOptionalDot(lcaseText, leapMonthName, bestMatchName, bestMatchLength)) {
2343103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius                    bestMatch = i;
2344103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius                    isLeapMonth = 1;
2345103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius                }
2346103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius            }
2347ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        }
2348ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    }
2349ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    if (bestMatch >= 0)
2350ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    {
235150294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho        // Adjustment for Hebrew Calendar month Adar II
235250294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho        if (!strcmp(cal.getType(),"hebrew") && field==UCAL_MONTH && bestMatch==13) {
235350294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho            cal.set(field,6);
235450294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho        }
235550294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho        else {
2356103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius            if (field == UCAL_YEAR) {
2357103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius                bestMatch++; // only get here for cyclic year names, which match 1-based years 1-60
2358103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius            }
235950294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho            cal.set(field, bestMatch);
236050294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho        }
2361103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius        if (monthPattern != NULL) {
2362103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius            cal.set(UCAL_IS_LEAP_MONTH, isLeapMonth);
2363103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius        }
2364ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
2365ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        // Once we have a match, we have to determine the length of the
2366ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        // original source string.  This will usually be == the length of
2367ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        // the case folded string, but it may differ (e.g. sharp s).
2368ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
2369ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        // Most of the time, the length will be the same as the length
2370ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        // of the string from the locale data.  Sometimes it will be
2371ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        // different, in which case we will have to figure it out by
2372ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        // adding a character at a time, until we have a match.  We do
2373ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        // this all in one loop, where we try 'len' first (at index
2374ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        // i==0).
2375103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius        int32_t len = bestMatchName.length(); // 99+% of the time
2376ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        int32_t n = text.length() - start;
2377ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        for (i=0; i<=n; ++i) {
2378ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            int32_t j=i;
2379ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            if (i == 0) {
2380ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                j = len;
2381ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            } else if (i == len) {
2382ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                continue; // already tried this when i was 0
2383ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            }
2384ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            text.extract(start, j, lcaseText);
2385ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            lcaseText.foldCase();
238654dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius            if (bestMatchName == lcaseText) {
2387ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                return start + j;
2388ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            }
2389ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        }
2390ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    }
239150294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho
2392ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    return -start;
2393ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru}
2394ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
239554dcd9b6a06071f647dac967e9e267abb9410720Craig Corneliusstatic UBool
239654dcd9b6a06071f647dac967e9e267abb9410720Craig CorneliusnewBestMatchWithOptionalDot(const UnicodeString &lcaseText,
239754dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius                            const UnicodeString &data,
239854dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius                            UnicodeString &bestMatchName,
239954dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius                            int32_t &bestMatchLength) {
240054dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius    UnicodeString lcase;
240154dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius    lcase.fastCopyFrom(data).foldCase();
240254dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius    int32_t length = lcase.length();
240354dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius    if (length <= bestMatchLength) {
240454dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius        // data cannot provide a better match.
240554dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius        return FALSE;
240654dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius    }
240754dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius
240854dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius    if (lcaseText.compareBetween(0, length, lcase, 0, length) == 0) {
240954dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius        // normal match
241054dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius        bestMatchName = lcase;
241154dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius        bestMatchLength = length;
241254dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius        return TRUE;
241354dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius    }
241454dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius    if (lcase.charAt(--length) == 0x2e) {
241554dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius        if (lcaseText.compareBetween(0, length, lcase, 0, length) == 0) {
241654dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius            // The input text matches the data except for data's trailing dot.
241754dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius            bestMatchName = lcase;
241854dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius            bestMatchName.truncate(length);
241954dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius            bestMatchLength = length;
242054dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius            return TRUE;
242154dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius        }
242254dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius    }
242354dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius    return FALSE;
242454dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius}
242554dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius
2426ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru//----------------------------------------------------------------------
2427ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
2428ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queruvoid
2429ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste QueruSimpleDateFormat::set2DigitYearStart(UDate d, UErrorCode& status)
2430ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru{
2431ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    parseAmbiguousDatesAsAfter(d, status);
2432ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru}
2433ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
2434ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru/**
2435ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru * Private member function that converts the parsed date strings into
2436ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru * timeFields. Returns -start (for ParsePosition) if failed.
2437ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru */
2438ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queruint32_t SimpleDateFormat::subParse(const UnicodeString& text, int32_t& start, UChar ch, int32_t count,
243950294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho                           UBool obeyCount, UBool allowNegative, UBool ambiguousYear[], int32_t& saveHebrewMonth, Calendar& cal,
2440fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius                           int32_t patLoc, MessageFormat * numericLeapMonthFormatter, UTimeZoneFormatTimeType *tzTimeType) const
2441ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru{
2442ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    Formattable number;
2443ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    int32_t value = 0;
2444ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    int32_t i;
244527f654740f2a26ad62a5c155af9199af9e69b889claireho    int32_t ps = 0;
244659d709d503bab6e2b61931737e662dd293b40578ccornelius    UErrorCode status = U_ZERO_ERROR;
2447ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    ParsePosition pos(0);
244854dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius    UDateFormatField patternCharIndex = DateFormatSymbols::getPatternCharIndex(ch);
244985bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    NumberFormat *currentNumberFormat;
2450ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    UnicodeString temp;
2451b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho    UBool gotNumber = FALSE;
2452ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
2453ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru#if defined (U_DEBUG_CAL)
2454ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    //fprintf(stderr, "%s:%d - [%c]  st=%d \n", __FILE__, __LINE__, (char) ch, start);
2455ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru#endif
2456ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
245754dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius    if (patternCharIndex == UDAT_FIELD_COUNT) {
2458ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        return -start;
2459ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    }
2460ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
246127f654740f2a26ad62a5c155af9199af9e69b889claireho    currentNumberFormat = getNumberFormatByIndex(patternCharIndex);
2462ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    UCalendarDateFields field = fgPatternIndexToCalendarField[patternCharIndex];
246354dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius    UnicodeString hebr("hebr", 4, US_INV);
2464ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
2465103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius    if (numericLeapMonthFormatter != NULL) {
2466103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius        numericLeapMonthFormatter->setFormats((const Format **)&currentNumberFormat, 1);
2467103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius    }
246859d709d503bab6e2b61931737e662dd293b40578ccornelius    UBool isChineseCalendar = (uprv_strcmp(cal.getType(),"chinese") == 0 || uprv_strcmp(cal.getType(),"dangi") == 0);
2469103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius
2470ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    // If there are any spaces here, skip over them.  If we hit the end
2471ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    // of the string, then fail.
2472ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    for (;;) {
2473ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        if (start >= text.length()) {
2474ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            return -start;
2475ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        }
2476ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        UChar32 c = text.char32At(start);
2477b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho        if (!u_isUWhiteSpace(c) /*||*/ && !PatternProps::isWhiteSpace(c)) {
2478ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            break;
2479ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        }
2480103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius        start += U16_LENGTH(c);
2481ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    }
2482ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    pos.setIndex(start);
2483ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
2484ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    // We handle a few special cases here where we need to parse
2485ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    // a number value.  We handle further, more generic cases below.  We need
2486ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    // to handle some of them here because some fields require extra processing on
2487ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    // the parsed value.
2488b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho    if (patternCharIndex == UDAT_HOUR_OF_DAY1_FIELD ||                       // k
2489b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho        patternCharIndex == UDAT_HOUR_OF_DAY0_FIELD ||                       // H
2490b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho        patternCharIndex == UDAT_HOUR1_FIELD ||                              // h
2491b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho        patternCharIndex == UDAT_HOUR0_FIELD ||                              // K
2492b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho        (patternCharIndex == UDAT_DOW_LOCAL_FIELD && count <= 2) ||          // e
2493b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho        (patternCharIndex == UDAT_STANDALONE_DAY_FIELD && count <= 2) ||     // c
2494b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho        (patternCharIndex == UDAT_MONTH_FIELD && count <= 2) ||              // M
2495b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho        (patternCharIndex == UDAT_STANDALONE_MONTH_FIELD && count <= 2) ||   // L
2496b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho        (patternCharIndex == UDAT_QUARTER_FIELD && count <= 2) ||            // Q
2497b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho        (patternCharIndex == UDAT_STANDALONE_QUARTER_FIELD && count <= 2) || // q
2498b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho        patternCharIndex == UDAT_YEAR_FIELD ||                               // y
2499b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho        patternCharIndex == UDAT_YEAR_WOY_FIELD ||                           // Y
2500103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius        patternCharIndex == UDAT_YEAR_NAME_FIELD ||                          // U (falls back to numeric)
2501103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius        (patternCharIndex == UDAT_ERA_FIELD && isChineseCalendar) ||         // G
2502b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho        patternCharIndex == UDAT_FRACTIONAL_SECOND_FIELD)                    // S
2503ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    {
2504ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        int32_t parseStart = pos.getIndex();
2505ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        // It would be good to unify this with the obeyCount logic below,
2506ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        // but that's going to be difficult.
2507ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        const UnicodeString* src;
2508ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
2509103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius        UBool parsedNumericLeapMonth = FALSE;
2510103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius        if (numericLeapMonthFormatter != NULL && (patternCharIndex == UDAT_MONTH_FIELD || patternCharIndex == UDAT_STANDALONE_MONTH_FIELD)) {
2511103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius            int32_t argCount;
2512103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius            Formattable * args = numericLeapMonthFormatter->parse(text, pos, argCount);
2513103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius            if (args != NULL && argCount == 1 && pos.getIndex() > parseStart && args[0].isNumeric()) {
2514103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius                parsedNumericLeapMonth = TRUE;
2515103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius                number.setLong(args[0].getLong());
2516103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius                cal.set(UCAL_IS_LEAP_MONTH, 1);
2517103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius                delete[] args;
2518103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius            } else {
2519103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius                pos.setIndex(parseStart);
2520103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius                cal.set(UCAL_IS_LEAP_MONTH, 0);
2521ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            }
2522ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        }
2523ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
2524103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius        if (!parsedNumericLeapMonth) {
2525103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius            if (obeyCount) {
2526103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius                if ((start+count) > text.length()) {
2527103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius                    return -start;
2528103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius                }
2529103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius
2530103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius                text.extractBetween(0, start + count, temp);
2531103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius                src = &temp;
2532103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius            } else {
2533103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius                src = &text;
2534103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius            }
2535103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius
2536103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius            parseInt(*src, number, pos, allowNegative,currentNumberFormat);
2537103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius        }
2538ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
253985bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho        int32_t txtLoc = pos.getIndex();
2540b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho
2541b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho        if (txtLoc > parseStart) {
2542b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho            value = number.getLong();
2543b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho            gotNumber = TRUE;
2544b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho
2545b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho            // suffix processing
2546b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho            if (value < 0 ) {
2547b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho                txtLoc = checkIntSuffix(text, txtLoc, patLoc+1, TRUE);
2548b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho                if (txtLoc != pos.getIndex()) {
2549b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho                    value *= -1;
2550b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho                }
2551b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho            }
2552b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho            else {
2553b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho                txtLoc = checkIntSuffix(text, txtLoc, patLoc+1, FALSE);
255485bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho            }
255585bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho
255659d709d503bab6e2b61931737e662dd293b40578ccornelius            if (!getBooleanAttribute(UDAT_PARSE_ALLOW_WHITESPACE, status)) {
2557b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho                // Check the range of the value
2558b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho                int32_t bias = gFieldRangeBias[patternCharIndex];
2559b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho                if (bias >= 0 && (value > cal.getMaximum(field) + bias || value < cal.getMinimum(field) + bias)) {
2560b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho                    return -start;
2561b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho                }
2562b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho            }
2563b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho
2564b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho            pos.setIndex(txtLoc);
2565b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho        }
2566b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho    }
2567b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho
2568b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho    // Make sure that we got a number if
2569b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho    // we want one, and didn't get one
2570b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho    // if we don't want one.
2571b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho    switch (patternCharIndex) {
2572b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho        case UDAT_HOUR_OF_DAY1_FIELD:
2573b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho        case UDAT_HOUR_OF_DAY0_FIELD:
2574b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho        case UDAT_HOUR1_FIELD:
2575b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho        case UDAT_HOUR0_FIELD:
2576b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho            // special range check for hours:
2577b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho            if (value < 0 || value > 24) {
2578b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho                return -start;
2579b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho            }
2580b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho
2581b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho            // fall through to gotNumber check
2582b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho
2583b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho        case UDAT_YEAR_FIELD:
2584b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho        case UDAT_YEAR_WOY_FIELD:
2585b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho        case UDAT_FRACTIONAL_SECOND_FIELD:
2586b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho            // these must be a number
2587b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho            if (! gotNumber) {
2588b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho                return -start;
2589b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho            }
2590b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho
2591b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho            break;
2592b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho
2593b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho        default:
2594b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho            // we check the rest of the fields below.
2595b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho            break;
2596ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    }
2597ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
2598ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    switch (patternCharIndex) {
2599ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    case UDAT_ERA_FIELD:
2600103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius        if (isChineseCalendar) {
2601103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius            if (!gotNumber) {
2602103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius                return -start;
2603103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius            }
2604103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius            cal.set(UCAL_ERA, value);
2605103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius            return pos.getIndex();
2606103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius        }
260785bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho        if (count == 5) {
2608103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius            ps = matchString(text, start, UCAL_ERA, fSymbols->fNarrowEras, fSymbols->fNarrowErasCount, NULL, cal);
2609b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho        } else if (count == 4) {
2610103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius            ps = matchString(text, start, UCAL_ERA, fSymbols->fEraNames, fSymbols->fEraNamesCount, NULL, cal);
2611b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho        } else {
2612103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius            ps = matchString(text, start, UCAL_ERA, fSymbols->fEras, fSymbols->fErasCount, NULL, cal);
261327f654740f2a26ad62a5c155af9199af9e69b889claireho        }
261427f654740f2a26ad62a5c155af9199af9e69b889claireho
261527f654740f2a26ad62a5c155af9199af9e69b889claireho        // check return position, if it equals -start, then matchString error
261627f654740f2a26ad62a5c155af9199af9e69b889claireho        // special case the return code so we don't necessarily fail out until we
261727f654740f2a26ad62a5c155af9199af9e69b889claireho        // verify no year information also
261827f654740f2a26ad62a5c155af9199af9e69b889claireho        if (ps == -start)
261927f654740f2a26ad62a5c155af9199af9e69b889claireho            ps--;
2620ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
262127f654740f2a26ad62a5c155af9199af9e69b889claireho        return ps;
2622ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
2623ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    case UDAT_YEAR_FIELD:
2624ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        // If there are 3 or more YEAR pattern characters, this indicates
2625ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        // that the year value is to be treated literally, without any
2626ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        // two-digit year adjustments (e.g., from "01" to 2001).  Otherwise
2627ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        // we made adjustments to place the 2-digit year in the proper
2628ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        // century, for parsed strings from "00" to "99".  Any other string
2629ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        // is treated literally:  "2250", "-1", "1", "002".
263054dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius        if (fDateOverride.compare(hebr)==0 && value < 1000) {
263154dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius            value += HEBREW_CAL_CUR_MILLENIUM_START_YEAR;
263254dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius        } else if ((pos.getIndex() - start) == 2 && !isChineseCalendar
2633ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            && u_isdigit(text.charAt(start))
2634ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            && u_isdigit(text.charAt(start+1)))
2635ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        {
2636fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius            // only adjust year for patterns less than 3.
2637fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius            if(count < 3) {
2638fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius                // Assume for example that the defaultCenturyStart is 6/18/1903.
2639fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius                // This means that two-digit years will be forced into the range
2640fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius                // 6/18/1903 to 6/17/2003.  As a result, years 00, 01, and 02
2641fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius                // correspond to 2000, 2001, and 2002.  Years 04, 05, etc. correspond
2642fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius                // to 1904, 1905, etc.  If the year is 03, then it is 2003 if the
2643fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius                // other fields specify a date before 6/18, or 1903 if they specify a
2644fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius                // date afterwards.  As a result, 03 is an ambiguous year.  All other
2645fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius                // two-digit years are unambiguous.
2646fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius                if(fHaveDefaultCentury) { // check if this formatter even has a pivot year
2647fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius                    int32_t ambiguousTwoDigitYear = fDefaultCenturyStartYear % 100;
2648fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius                    ambiguousYear[0] = (value == ambiguousTwoDigitYear);
2649fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius                    value += (fDefaultCenturyStartYear/100)*100 +
2650fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius                            (value < ambiguousTwoDigitYear ? 100 : 0);
2651fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius                }
2652ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            }
2653ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        }
2654ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        cal.set(UCAL_YEAR, value);
265550294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho
265650294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho        // Delayed checking for adjustment of Hebrew month numbers in non-leap years.
265750294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho        if (saveHebrewMonth >= 0) {
265850294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho            HebrewCalendar *hc = (HebrewCalendar*)&cal;
265950294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho            if (!hc->isLeapYear(value) && saveHebrewMonth >= 6) {
266050294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho               cal.set(UCAL_MONTH,saveHebrewMonth);
266150294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho            } else {
266250294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho               cal.set(UCAL_MONTH,saveHebrewMonth-1);
266350294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho            }
266450294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho            saveHebrewMonth = -1;
266550294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho        }
2666ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        return pos.getIndex();
2667ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
2668ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    case UDAT_YEAR_WOY_FIELD:
2669ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        // Comment is the same as for UDAT_Year_FIELDs - look above
267054dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius        if (fDateOverride.compare(hebr)==0 && value < 1000) {
267154dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius            value += HEBREW_CAL_CUR_MILLENIUM_START_YEAR;
267254dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius        } else if ((pos.getIndex() - start) == 2
2673ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            && u_isdigit(text.charAt(start))
2674ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            && u_isdigit(text.charAt(start+1))
2675ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            && fHaveDefaultCentury )
2676ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        {
2677ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            int32_t ambiguousTwoDigitYear = fDefaultCenturyStartYear % 100;
2678ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            ambiguousYear[0] = (value == ambiguousTwoDigitYear);
2679ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            value += (fDefaultCenturyStartYear/100)*100 +
2680ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                (value < ambiguousTwoDigitYear ? 100 : 0);
2681ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        }
2682ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        cal.set(UCAL_YEAR_WOY, value);
2683ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        return pos.getIndex();
2684ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
2685103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius    case UDAT_YEAR_NAME_FIELD:
2686103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius        if (fSymbols->fShortYearNames != NULL) {
2687103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius            int32_t newStart = matchString(text, start, UCAL_YEAR, fSymbols->fShortYearNames, fSymbols->fShortYearNamesCount, NULL, cal);
2688103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius            if (newStart > 0) {
2689103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius                return newStart;
2690103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius            }
2691103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius        }
269259d709d503bab6e2b61931737e662dd293b40578ccornelius        if (gotNumber && (getBooleanAttribute(UDAT_PARSE_ALLOW_NUMERIC,status) || value > fSymbols->fShortYearNamesCount)) {
2693103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius            cal.set(UCAL_YEAR, value);
2694103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius            return pos.getIndex();
2695103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius        }
2696103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius        return -start;
2697103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius
2698ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    case UDAT_MONTH_FIELD:
2699103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius    case UDAT_STANDALONE_MONTH_FIELD:
2700b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho        if (gotNumber) // i.e., M or MM.
2701ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        {
270250294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho            // When parsing month numbers from the Hebrew Calendar, we might need to adjust the month depending on whether
270350294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho            // 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
270450294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho            // the year is parsed.
270550294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho            if (!strcmp(cal.getType(),"hebrew")) {
270650294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho                HebrewCalendar *hc = (HebrewCalendar*)&cal;
270750294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho                if (cal.isSet(UCAL_YEAR)) {
270850294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho                   UErrorCode status = U_ZERO_ERROR;
270950294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho                   if (!hc->isLeapYear(hc->get(UCAL_YEAR,status)) && value >= 6) {
271050294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho                       cal.set(UCAL_MONTH, value);
271150294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho                   } else {
271250294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho                       cal.set(UCAL_MONTH, value - 1);
271350294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho                   }
271450294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho                } else {
271550294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho                    saveHebrewMonth = value;
271650294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho                }
271750294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho            } else {
271850294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho                // Don't want to parse the month if it is a string
2719103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius                // while pattern uses numeric style: M/MM, L/LL
272050294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho                // [We computed 'value' above.]
272150294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho                cal.set(UCAL_MONTH, value - 1);
272250294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho            }
2723ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            return pos.getIndex();
2724ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        } else {
2725103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius            // count >= 3 // i.e., MMM/MMMM, LLL/LLLL
2726ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            // Want to be able to parse both short and long forms.
2727ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            // Try count == 4 first:
2728103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius            UnicodeString * wideMonthPat = NULL;
2729103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius            UnicodeString * shortMonthPat = NULL;
2730103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius            if (fSymbols->fLeapMonthPatterns != NULL && fSymbols->fLeapMonthPatternsCount >= DateFormatSymbols::kMonthPatternsCount) {
2731103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius                if (patternCharIndex==UDAT_MONTH_FIELD) {
2732103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius                    wideMonthPat = &fSymbols->fLeapMonthPatterns[DateFormatSymbols::kLeapMonthPatternFormatWide];
2733103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius                    shortMonthPat = &fSymbols->fLeapMonthPatterns[DateFormatSymbols::kLeapMonthPatternFormatAbbrev];
2734103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius                } else {
2735103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius                    wideMonthPat = &fSymbols->fLeapMonthPatterns[DateFormatSymbols::kLeapMonthPatternStandaloneWide];
2736103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius                    shortMonthPat = &fSymbols->fLeapMonthPatterns[DateFormatSymbols::kLeapMonthPatternStandaloneAbbrev];
2737103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius                }
2738103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius            }
2739ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            int32_t newStart = 0;
2740103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius            if (patternCharIndex==UDAT_MONTH_FIELD) {
2741fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius                if(getBooleanAttribute(UDAT_PARSE_MULTIPLE_PATTERNS_FOR_MATCH, status) || count == 4) {
2742fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius                    newStart = matchString(text, start, UCAL_MONTH, fSymbols->fMonths, fSymbols->fMonthsCount, wideMonthPat, cal); // try MMMM
2743fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius                    if (newStart > 0) {
2744fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius                        return newStart;
2745fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius                    }
2746fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius                }
2747fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius                if(getBooleanAttribute(UDAT_PARSE_MULTIPLE_PATTERNS_FOR_MATCH, status) || count == 3) {
2748fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius                    newStart = matchString(text, start, UCAL_MONTH, fSymbols->fShortMonths, fSymbols->fShortMonthsCount, shortMonthPat, cal); // try MMM
2749103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius                }
2750103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius            } else {
2751fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius                if(getBooleanAttribute(UDAT_PARSE_MULTIPLE_PATTERNS_FOR_MATCH, status) || count == 4) {
2752fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius                    newStart = matchString(text, start, UCAL_MONTH, fSymbols->fStandaloneMonths, fSymbols->fStandaloneMonthsCount, wideMonthPat, cal); // try LLLL
2753fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius                    if (newStart > 0) {
2754fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius                        return newStart;
2755fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius                    }
2756fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius                }
2757fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius                if(getBooleanAttribute(UDAT_PARSE_MULTIPLE_PATTERNS_FOR_MATCH, status) || count == 3) {
2758fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius                    newStart = matchString(text, start, UCAL_MONTH, fSymbols->fStandaloneShortMonths, fSymbols->fStandaloneShortMonthsCount, shortMonthPat, cal); // try LLL
2759103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius                }
2760103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius            }
276159d709d503bab6e2b61931737e662dd293b40578ccornelius            if (newStart > 0 || !getBooleanAttribute(UDAT_PARSE_ALLOW_NUMERIC, status))  // currently we do not try to parse MMMMM/LLLLL: #8860
2762b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho                return newStart;
2763b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho            // else we allowing parsing as number, below
2764ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        }
2765b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho        break;
2766ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
2767ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    case UDAT_HOUR_OF_DAY1_FIELD:
2768ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        // [We computed 'value' above.]
276950294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho        if (value == cal.getMaximum(UCAL_HOUR_OF_DAY) + 1)
2770ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            value = 0;
2771b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho
2772b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho        // fall through to set field
2773b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho
2774b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho    case UDAT_HOUR_OF_DAY0_FIELD:
2775ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        cal.set(UCAL_HOUR_OF_DAY, value);
2776ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        return pos.getIndex();
2777ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
2778ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    case UDAT_FRACTIONAL_SECOND_FIELD:
2779ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        // Fractional seconds left-justify
2780ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        i = pos.getIndex() - start;
2781ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        if (i < 3) {
2782ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            while (i < 3) {
2783ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                value *= 10;
2784ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                i++;
2785ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            }
2786ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        } else {
2787ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            int32_t a = 1;
2788ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            while (i > 3) {
2789ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                a *= 10;
2790ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                i--;
2791ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            }
27928393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius            value /= a;
2793ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        }
2794ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        cal.set(UCAL_MILLISECOND, value);
2795ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        return pos.getIndex();
2796ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
279785bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    case UDAT_DOW_LOCAL_FIELD:
2798b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho        if (gotNumber) // i.e., e or ee
279985bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho        {
280085bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho            // [We computed 'value' above.]
280185bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho            cal.set(UCAL_DOW_LOCAL, value);
280285bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho            return pos.getIndex();
280385bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho        }
280485bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho        // else for eee-eeeee fall through to handling of EEE-EEEEE
280585bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho        // fall through, do not break here
2806ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    case UDAT_DAY_OF_WEEK_FIELD:
2807ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        {
2808ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            // Want to be able to parse both short and long forms.
28098393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius            // Try count == 4 (EEEE) wide first:
2810ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            int32_t newStart = 0;
2811fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius            if(getBooleanAttribute(UDAT_PARSE_MULTIPLE_PATTERNS_FOR_MATCH, status) || count == 4) {
2812fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius                if ((newStart = matchString(text, start, UCAL_DAY_OF_WEEK,
2813fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius                                          fSymbols->fWeekdays, fSymbols->fWeekdaysCount, NULL, cal)) > 0)
2814fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius                    return newStart;
2815fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius            }
28168393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius            // EEEE wide failed, now try EEE abbreviated
2817fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius            if(getBooleanAttribute(UDAT_PARSE_MULTIPLE_PATTERNS_FOR_MATCH, status) || count == 3) {
2818fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius                if ((newStart = matchString(text, start, UCAL_DAY_OF_WEEK,
2819fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius                                       fSymbols->fShortWeekdays, fSymbols->fShortWeekdaysCount, NULL, cal)) > 0)
2820fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius                    return newStart;
2821fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius            }
28228393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius            // EEE abbreviated failed, now try EEEEEE short
2823fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius            if(getBooleanAttribute(UDAT_PARSE_MULTIPLE_PATTERNS_FOR_MATCH, status) || count == 6) {
2824fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius                if ((newStart = matchString(text, start, UCAL_DAY_OF_WEEK,
2825fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius                                       fSymbols->fShorterWeekdays, fSymbols->fShorterWeekdaysCount, NULL, cal)) > 0)
2826fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius                    return newStart;
2827fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius            }
28288393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius            // EEEEEE short failed, now try EEEEE narrow
2829fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius            if(getBooleanAttribute(UDAT_PARSE_MULTIPLE_PATTERNS_FOR_MATCH, status) || count == 5) {
2830fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius                if ((newStart = matchString(text, start, UCAL_DAY_OF_WEEK,
2831fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius                                       fSymbols->fNarrowWeekdays, fSymbols->fNarrowWeekdaysCount, NULL, cal)) > 0)
2832fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius                    return newStart;
2833fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius            }
2834fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius            if (!getBooleanAttribute(UDAT_PARSE_ALLOW_NUMERIC, status) || patternCharIndex == UDAT_DAY_OF_WEEK_FIELD)
2835b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho                return newStart;
2836b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho            // else we allowing parsing as number, below
2837ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        }
2838b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho        break;
2839ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
2840ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    case UDAT_STANDALONE_DAY_FIELD:
2841ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        {
2842b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho            if (gotNumber) // c or cc
284385bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho            {
284485bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho                // [We computed 'value' above.]
284585bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho                cal.set(UCAL_DOW_LOCAL, value);
284685bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho                return pos.getIndex();
284785bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho            }
2848ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            // Want to be able to parse both short and long forms.
284985bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho            // Try count == 4 (cccc) first:
2850ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            int32_t newStart = 0;
2851fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius            if(getBooleanAttribute(UDAT_PARSE_MULTIPLE_PATTERNS_FOR_MATCH, status) || count == 4) {
2852fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius                if ((newStart = matchString(text, start, UCAL_DAY_OF_WEEK,
2853103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius                                      fSymbols->fStandaloneWeekdays, fSymbols->fStandaloneWeekdaysCount, NULL, cal)) > 0)
2854fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius                    return newStart;
2855fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius            }
2856fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius            if(getBooleanAttribute(UDAT_PARSE_MULTIPLE_PATTERNS_FOR_MATCH, status) || count == 3) {
2857fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius                if ((newStart = matchString(text, start, UCAL_DAY_OF_WEEK,
2858103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius                                          fSymbols->fStandaloneShortWeekdays, fSymbols->fStandaloneShortWeekdaysCount, NULL, cal)) > 0)
2859fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius                    return newStart;
2860fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius            }
2861fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius            if(getBooleanAttribute(UDAT_PARSE_MULTIPLE_PATTERNS_FOR_MATCH, status) || count == 6) {
2862fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius                if ((newStart = matchString(text, start, UCAL_DAY_OF_WEEK,
28638393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius                                          fSymbols->fStandaloneShorterWeekdays, fSymbols->fStandaloneShorterWeekdaysCount, NULL, cal)) > 0)
2864fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius                    return newStart;
2865fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius            }
2866fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius            if (!getBooleanAttribute(UDAT_PARSE_ALLOW_NUMERIC, status))
2867b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho                return newStart;
2868b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho            // else we allowing parsing as number, below
2869ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        }
2870b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho        break;
2871ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
2872ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    case UDAT_AM_PM_FIELD:
2873103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius        return matchString(text, start, UCAL_AM_PM, fSymbols->fAmPms, fSymbols->fAmPmsCount, NULL, cal);
2874ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
2875ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    case UDAT_HOUR1_FIELD:
2876ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        // [We computed 'value' above.]
287750294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho        if (value == cal.getLeastMaximum(UCAL_HOUR)+1)
2878ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            value = 0;
2879b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho
2880b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho        // fall through to set field
2881b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho
2882b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho    case UDAT_HOUR0_FIELD:
2883ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        cal.set(UCAL_HOUR, value);
2884ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        return pos.getIndex();
2885ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
2886ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    case UDAT_QUARTER_FIELD:
2887b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho        if (gotNumber) // i.e., Q or QQ.
2888ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        {
2889ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            // Don't want to parse the month if it is a string
2890ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            // while pattern uses numeric style: Q or QQ.
2891ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            // [We computed 'value' above.]
2892ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            cal.set(UCAL_MONTH, (value - 1) * 3);
2893ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            return pos.getIndex();
2894ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        } else {
2895ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            // count >= 3 // i.e., QQQ or QQQQ
2896ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            // Want to be able to parse both short and long forms.
2897ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            // Try count == 4 first:
2898ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            int32_t newStart = 0;
2899ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
2900fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius            if(getBooleanAttribute(UDAT_PARSE_MULTIPLE_PATTERNS_FOR_MATCH, status) || count == 4) {
2901fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius                if ((newStart = matchQuarterString(text, start, UCAL_MONTH,
2902ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                                      fSymbols->fQuarters, fSymbols->fQuartersCount, cal)) > 0)
2903fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius                    return newStart;
2904fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius            }
2905fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius            if(getBooleanAttribute(UDAT_PARSE_MULTIPLE_PATTERNS_FOR_MATCH, status) || count == 3) {
2906fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius                if ((newStart = matchQuarterString(text, start, UCAL_MONTH,
2907b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho                                          fSymbols->fShortQuarters, fSymbols->fShortQuartersCount, cal)) > 0)
2908fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius                    return newStart;
2909fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius            }
2910fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius            if (!getBooleanAttribute(UDAT_PARSE_ALLOW_NUMERIC, status))
2911b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho                return newStart;
2912b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho            // else we allowing parsing as number, below
2913fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius            if(!getBooleanAttribute(UDAT_PARSE_MULTIPLE_PATTERNS_FOR_MATCH, status))
2914fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius                return -start;
2915ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        }
2916b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho        break;
2917ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
2918ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    case UDAT_STANDALONE_QUARTER_FIELD:
2919b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho        if (gotNumber) // i.e., q or qq.
2920ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        {
2921ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            // Don't want to parse the month if it is a string
2922ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            // while pattern uses numeric style: q or q.
2923ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            // [We computed 'value' above.]
2924ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            cal.set(UCAL_MONTH, (value - 1) * 3);
2925ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            return pos.getIndex();
2926ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        } else {
2927ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            // count >= 3 // i.e., qqq or qqqq
2928ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            // Want to be able to parse both short and long forms.
2929ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            // Try count == 4 first:
2930ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            int32_t newStart = 0;
2931ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
2932fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius            if(getBooleanAttribute(UDAT_PARSE_MULTIPLE_PATTERNS_FOR_MATCH, status) || count == 4) {
2933fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius                if ((newStart = matchQuarterString(text, start, UCAL_MONTH,
2934ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                                      fSymbols->fStandaloneQuarters, fSymbols->fStandaloneQuartersCount, cal)) > 0)
2935fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius                    return newStart;
2936fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius            }
2937fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius            if(getBooleanAttribute(UDAT_PARSE_MULTIPLE_PATTERNS_FOR_MATCH, status) || count == 3) {
2938fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius                if ((newStart = matchQuarterString(text, start, UCAL_MONTH,
2939b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho                                          fSymbols->fStandaloneShortQuarters, fSymbols->fStandaloneShortQuartersCount, cal)) > 0)
2940fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius                    return newStart;
2941fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius            }
2942fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius            if (!getBooleanAttribute(UDAT_PARSE_ALLOW_NUMERIC, status))
2943b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho                return newStart;
2944b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho            // else we allowing parsing as number, below
2945fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius            if(!getBooleanAttribute(UDAT_PARSE_MULTIPLE_PATTERNS_FOR_MATCH, status))
2946fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius                return -start;
2947ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        }
2948b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho        break;
2949ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
29508393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius    case UDAT_TIMEZONE_FIELD: // 'z'
2951ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        {
2952103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius            UTimeZoneFormatStyle style = (count < 4) ? UTZFMT_STYLE_SPECIFIC_SHORT : UTZFMT_STYLE_SPECIFIC_LONG;
2953fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius            TimeZone *tz  = tzFormat()->parse(style, text, pos, tzTimeType);
2954103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius            if (tz != NULL) {
2955103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius                cal.adoptTimeZone(tz);
2956b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                return pos.getIndex();
2957ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            }
2958103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius        }
2959103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius        break;
29608393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius    case UDAT_TIMEZONE_RFC_FIELD: // 'Z'
2961103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius        {
29628393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius            UTimeZoneFormatStyle style = (count < 4) ?
29638393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius                UTZFMT_STYLE_ISO_BASIC_LOCAL_FULL : ((count == 5) ? UTZFMT_STYLE_ISO_EXTENDED_FULL: UTZFMT_STYLE_LOCALIZED_GMT);
2964fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius            TimeZone *tz  = tzFormat()->parse(style, text, pos, tzTimeType);
2965103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius            if (tz != NULL) {
2966b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho                cal.adoptTimeZone(tz);
2967103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius                return pos.getIndex();
2968b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho            }
2969103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius            return -start;
2970103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius        }
29718393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius    case UDAT_TIMEZONE_GENERIC_FIELD: // 'v'
2972103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius        {
2973103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius            UTimeZoneFormatStyle style = (count < 4) ? UTZFMT_STYLE_GENERIC_SHORT : UTZFMT_STYLE_GENERIC_LONG;
2974fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius            TimeZone *tz  = tzFormat()->parse(style, text, pos, tzTimeType);
2975103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius            if (tz != NULL) {
2976103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius                cal.adoptTimeZone(tz);
2977103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius                return pos.getIndex();
2978ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            }
2979103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius            return -start;
2980103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius        }
29818393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius    case UDAT_TIMEZONE_SPECIAL_FIELD: // 'V'
29828393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius        {
29838393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius            UTimeZoneFormatStyle style;
29848393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius            switch (count) {
29858393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius            case 1:
29868393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius                style = UTZFMT_STYLE_ZONE_ID_SHORT;
29878393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius                break;
29888393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius            case 2:
29898393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius                style = UTZFMT_STYLE_ZONE_ID;
29908393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius                break;
29918393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius            case 3:
29928393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius                style = UTZFMT_STYLE_EXEMPLAR_LOCATION;
29938393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius                break;
29948393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius            default:
29958393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius                style = UTZFMT_STYLE_GENERIC_LOCATION;
29968393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius                break;
29978393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius            }
2998fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius            TimeZone *tz  = tzFormat()->parse(style, text, pos, tzTimeType);
29998393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius            if (tz != NULL) {
30008393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius                cal.adoptTimeZone(tz);
30018393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius                return pos.getIndex();
30028393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius            }
30038393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius            return -start;
30048393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius        }
30058393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius    case UDAT_TIMEZONE_LOCALIZED_GMT_OFFSET_FIELD: // 'O'
30068393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius        {
30078393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius            UTimeZoneFormatStyle style = (count < 4) ? UTZFMT_STYLE_LOCALIZED_GMT_SHORT : UTZFMT_STYLE_LOCALIZED_GMT;
3008fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius            TimeZone *tz  = tzFormat()->parse(style, text, pos, tzTimeType);
30098393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius            if (tz != NULL) {
30108393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius                cal.adoptTimeZone(tz);
30118393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius                return pos.getIndex();
30128393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius            }
30138393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius            return -start;
30148393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius        }
30158393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius    case UDAT_TIMEZONE_ISO_FIELD: // 'X'
3016103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius        {
30178393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius            UTimeZoneFormatStyle style;
30188393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius            switch (count) {
30198393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius            case 1:
30208393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius                style = UTZFMT_STYLE_ISO_BASIC_SHORT;
30218393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius                break;
30228393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius            case 2:
30238393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius                style = UTZFMT_STYLE_ISO_BASIC_FIXED;
30248393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius                break;
30258393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius            case 3:
30268393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius                style = UTZFMT_STYLE_ISO_EXTENDED_FIXED;
30278393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius                break;
30288393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius            case 4:
30298393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius                style = UTZFMT_STYLE_ISO_BASIC_FULL;
30308393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius                break;
30318393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius            default:
30328393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius                style = UTZFMT_STYLE_ISO_EXTENDED_FULL;
30338393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius                break;
30348393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius            }
3035fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius            TimeZone *tz  = tzFormat()->parse(style, text, pos, tzTimeType);
30368393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius            if (tz != NULL) {
30378393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius                cal.adoptTimeZone(tz);
30388393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius                return pos.getIndex();
30398393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius            }
30408393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius            return -start;
30418393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius        }
30428393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius    case UDAT_TIMEZONE_ISO_LOCAL_FIELD: // 'x'
30438393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius        {
30448393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius            UTimeZoneFormatStyle style;
30458393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius            switch (count) {
30468393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius            case 1:
30478393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius                style = UTZFMT_STYLE_ISO_BASIC_LOCAL_SHORT;
30488393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius                break;
30498393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius            case 2:
30508393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius                style = UTZFMT_STYLE_ISO_BASIC_LOCAL_FIXED;
30518393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius                break;
30528393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius            case 3:
30538393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius                style = UTZFMT_STYLE_ISO_EXTENDED_LOCAL_FIXED;
30548393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius                break;
30558393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius            case 4:
30568393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius                style = UTZFMT_STYLE_ISO_BASIC_LOCAL_FULL;
30578393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius                break;
30588393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius            default:
30598393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius                style = UTZFMT_STYLE_ISO_EXTENDED_LOCAL_FULL;
30608393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius                break;
30618393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius            }
3062fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius            TimeZone *tz  = tzFormat()->parse(style, text, pos, tzTimeType);
3063103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius            if (tz != NULL) {
306485bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho                cal.adoptTimeZone(tz);
3065103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius                return pos.getIndex();
306685bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho            }
3067b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru            return -start;
3068ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        }
3069ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
3070ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    default:
3071ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        // Handle "generic" fields
3072b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho        // this is now handled below, outside the switch block
3073b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho        break;
3074b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho    }
3075b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho    // Handle "generic" fields:
3076b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho    // switch default case now handled here (outside switch block) to allow
3077b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho    // parsing of some string fields as digits for lenient case
3078b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho
3079b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho    int32_t parseStart = pos.getIndex();
3080b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho    const UnicodeString* src;
3081b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho    if (obeyCount) {
3082b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho        if ((start+count) > text.length()) {
3083b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho            return -start;
3084b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho        }
3085b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho        text.extractBetween(0, start + count, temp);
3086b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho        src = &temp;
3087b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho    } else {
3088b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho        src = &text;
3089b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho    }
3090b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho    parseInt(*src, number, pos, allowNegative,currentNumberFormat);
3091b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho    if (pos.getIndex() != parseStart) {
3092b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho        int32_t value = number.getLong();
3093b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho
3094b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho        // Don't need suffix processing here (as in number processing at the beginning of the function);
3095b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho        // the new fields being handled as numeric values (month, weekdays, quarters) should not have suffixes.
3096b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho
309759d709d503bab6e2b61931737e662dd293b40578ccornelius        if (!getBooleanAttribute(UDAT_PARSE_ALLOW_NUMERIC, status)) {
3098b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho            // Check the range of the value
3099b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho            int32_t bias = gFieldRangeBias[patternCharIndex];
3100b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho            if (bias >= 0 && (value > cal.getMaximum(field) + bias || value < cal.getMinimum(field) + bias)) {
3101ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                return -start;
3102ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            }
3103ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        }
3104b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho
3105b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho        // For the following, need to repeat some of the "if (gotNumber)" code above:
3106b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho        // UDAT_[STANDALONE_]MONTH_FIELD, UDAT_DOW_LOCAL_FIELD, UDAT_STANDALONE_DAY_FIELD,
3107b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho        // UDAT_[STANDALONE_]QUARTER_FIELD
3108b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho        switch (patternCharIndex) {
3109b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho        case UDAT_MONTH_FIELD:
3110b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho            // See notes under UDAT_MONTH_FIELD case above
3111b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho            if (!strcmp(cal.getType(),"hebrew")) {
3112b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho                HebrewCalendar *hc = (HebrewCalendar*)&cal;
3113b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho                if (cal.isSet(UCAL_YEAR)) {
3114b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho                   UErrorCode status = U_ZERO_ERROR;
3115b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho                   if (!hc->isLeapYear(hc->get(UCAL_YEAR,status)) && value >= 6) {
3116b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho                       cal.set(UCAL_MONTH, value);
3117b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho                   } else {
3118b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho                       cal.set(UCAL_MONTH, value - 1);
3119b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho                   }
3120b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho                } else {
3121b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho                    saveHebrewMonth = value;
3122b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho                }
3123b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho            } else {
3124b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho                cal.set(UCAL_MONTH, value - 1);
3125b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho            }
3126b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho            break;
3127b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho        case UDAT_STANDALONE_MONTH_FIELD:
3128b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho            cal.set(UCAL_MONTH, value - 1);
3129b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho            break;
3130b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho        case UDAT_DOW_LOCAL_FIELD:
3131b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho        case UDAT_STANDALONE_DAY_FIELD:
3132b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho            cal.set(UCAL_DOW_LOCAL, value);
3133b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho            break;
3134b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho        case UDAT_QUARTER_FIELD:
3135b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho        case UDAT_STANDALONE_QUARTER_FIELD:
3136b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho             cal.set(UCAL_MONTH, (value - 1) * 3);
3137b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho             break;
3138fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius        case UDAT_RELATED_YEAR_FIELD:
3139fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius            cal.setRelatedYear(value);
3140fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius            break;
3141b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho        default:
3142b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho            cal.set(field, value);
3143b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho            break;
3144ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        }
3145b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho        return pos.getIndex();
3146ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    }
3147b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho    return -start;
3148ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru}
3149ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
3150ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru/**
3151ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru * Parse an integer using fNumberFormat.  This method is semantically
3152ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru * const, but actually may modify fNumberFormat.
3153ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru */
3154ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queruvoid SimpleDateFormat::parseInt(const UnicodeString& text,
3155ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                                Formattable& number,
3156ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                                ParsePosition& pos,
315785bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho                                UBool allowNegative,
315885bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho                                NumberFormat *fmt) const {
315985bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    parseInt(text, number, -1, pos, allowNegative,fmt);
3160b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru}
3161b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
3162b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru/**
3163b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * Parse an integer using fNumberFormat up to maxDigits.
3164b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru */
3165b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queruvoid SimpleDateFormat::parseInt(const UnicodeString& text,
3166b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                                Formattable& number,
3167b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                                int32_t maxDigits,
3168b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                                ParsePosition& pos,
316985bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho                                UBool allowNegative,
317085bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho                                NumberFormat *fmt) const {
3171ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    UnicodeString oldPrefix;
3172ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    DecimalFormat* df = NULL;
317327f654740f2a26ad62a5c155af9199af9e69b889claireho    if (!allowNegative && (df = dynamic_cast<DecimalFormat*>(fmt)) != NULL) {
3174ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        df->getNegativePrefix(oldPrefix);
3175b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho        df->setNegativePrefix(UnicodeString(TRUE, SUPPRESS_NEGATIVE_PREFIX, -1));
3176ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    }
3177b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    int32_t oldPos = pos.getIndex();
317885bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    fmt->parse(text, number, pos);
3179ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    if (df != NULL) {
3180ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        df->setNegativePrefix(oldPrefix);
3181ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    }
3182b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
3183b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    if (maxDigits > 0) {
3184b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        // adjust the result to fit into
3185b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        // the maxDigits and move the position back
3186b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        int32_t nDigits = pos.getIndex() - oldPos;
3187b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        if (nDigits > maxDigits) {
3188b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru            int32_t val = number.getLong();
3189b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru            nDigits -= maxDigits;
3190b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru            while (nDigits > 0) {
3191b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                val /= 10;
3192b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                nDigits--;
3193b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru            }
3194b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru            pos.setIndex(oldPos + maxDigits);
3195b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru            number.setLong(val);
3196b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        }
3197b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    }
3198ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru}
3199ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
3200ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru//----------------------------------------------------------------------
3201ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
3202ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queruvoid SimpleDateFormat::translatePattern(const UnicodeString& originalPattern,
3203ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                                        UnicodeString& translatedPattern,
3204ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                                        const UnicodeString& from,
3205ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                                        const UnicodeString& to,
3206ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                                        UErrorCode& status)
3207ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru{
3208ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru  // run through the pattern and convert any pattern symbols from the version
3209ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru  // in "from" to the corresponding character ion "to".  This code takes
3210ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru  // quoted strings into account (it doesn't try to translate them), and it signals
3211ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru  // an error if a particular "pattern character" doesn't appear in "from".
3212ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru  // Depending on the values of "from" and "to" this can convert from generic
3213ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru  // to localized patterns or localized to generic.
321450294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho  if (U_FAILURE(status))
3215ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    return;
321650294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho
3217ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru  translatedPattern.remove();
3218ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru  UBool inQuote = FALSE;
3219ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru  for (int32_t i = 0; i < originalPattern.length(); ++i) {
3220ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    UChar c = originalPattern[i];
3221ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    if (inQuote) {
322250294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho      if (c == QUOTE)
3223ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    inQuote = FALSE;
3224ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    }
3225ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    else {
322650294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho      if (c == QUOTE)
3227ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    inQuote = TRUE;
322850294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho      else if ((c >= 0x0061 /*'a'*/ && c <= 0x007A) /*'z'*/
3229ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru           || (c >= 0x0041 /*'A'*/ && c <= 0x005A /*'Z'*/)) {
3230ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    int32_t ci = from.indexOf(c);
3231ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    if (ci == -1) {
3232ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru      status = U_INVALID_FORMAT_ERROR;
3233ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru      return;
3234ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    }
3235ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    c = to[ci];
3236ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru      }
3237ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    }
3238ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    translatedPattern += c;
3239ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru  }
3240ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru  if (inQuote) {
3241ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    status = U_INVALID_FORMAT_ERROR;
3242ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    return;
3243ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru  }
3244ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru}
3245ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
3246ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru//----------------------------------------------------------------------
3247ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
3248ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste QueruUnicodeString&
3249ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste QueruSimpleDateFormat::toPattern(UnicodeString& result) const
3250ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru{
3251ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    result = fPattern;
3252ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    return result;
3253ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru}
3254ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
3255ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru//----------------------------------------------------------------------
3256ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
3257ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste QueruUnicodeString&
3258ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste QueruSimpleDateFormat::toLocalizedPattern(UnicodeString& result,
3259ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                                     UErrorCode& status) const
3260ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru{
3261b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho    translatePattern(fPattern, result,
3262b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho                     UnicodeString(DateFormatSymbols::getPatternUChars()),
3263b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho                     fSymbols->fLocalPatternChars, status);
3264ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    return result;
3265ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru}
3266ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
3267ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru//----------------------------------------------------------------------
3268ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
3269ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queruvoid
3270ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste QueruSimpleDateFormat::applyPattern(const UnicodeString& pattern)
3271ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru{
3272ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    fPattern = pattern;
3273ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru}
3274ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
3275ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru//----------------------------------------------------------------------
3276ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
3277ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queruvoid
3278ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste QueruSimpleDateFormat::applyLocalizedPattern(const UnicodeString& pattern,
3279ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                                        UErrorCode &status)
3280ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru{
3281b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho    translatePattern(pattern, fPattern,
3282b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho                     fSymbols->fLocalPatternChars,
3283b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho                     UnicodeString(DateFormatSymbols::getPatternUChars()), status);
3284ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru}
3285ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
3286ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru//----------------------------------------------------------------------
3287ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
3288ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queruconst DateFormatSymbols*
3289ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste QueruSimpleDateFormat::getDateFormatSymbols() const
3290ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru{
3291ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    return fSymbols;
3292ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru}
3293ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
3294ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru//----------------------------------------------------------------------
3295ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
3296ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queruvoid
3297ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste QueruSimpleDateFormat::adoptDateFormatSymbols(DateFormatSymbols* newFormatSymbols)
3298ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru{
3299ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    delete fSymbols;
3300ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    fSymbols = newFormatSymbols;
3301ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru}
3302ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
3303ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru//----------------------------------------------------------------------
3304ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queruvoid
3305ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste QueruSimpleDateFormat::setDateFormatSymbols(const DateFormatSymbols& newFormatSymbols)
3306ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru{
3307ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    delete fSymbols;
3308ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    fSymbols = new DateFormatSymbols(newFormatSymbols);
3309ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru}
3310ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
3311103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius//----------------------------------------------------------------------
3312103e9ffba2cba345d0078eb8b8db33249f81840aCraig Corneliusconst TimeZoneFormat*
3313103e9ffba2cba345d0078eb8b8db33249f81840aCraig CorneliusSimpleDateFormat::getTimeZoneFormat(void) const {
3314103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius    return (const TimeZoneFormat*)tzFormat();
3315103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius}
3316103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius
3317103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius//----------------------------------------------------------------------
3318103e9ffba2cba345d0078eb8b8db33249f81840aCraig Corneliusvoid
3319103e9ffba2cba345d0078eb8b8db33249f81840aCraig CorneliusSimpleDateFormat::adoptTimeZoneFormat(TimeZoneFormat* timeZoneFormatToAdopt)
3320103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius{
3321103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius    delete fTimeZoneFormat;
3322103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius    fTimeZoneFormat = timeZoneFormatToAdopt;
3323103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius}
3324103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius
3325103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius//----------------------------------------------------------------------
3326103e9ffba2cba345d0078eb8b8db33249f81840aCraig Corneliusvoid
3327103e9ffba2cba345d0078eb8b8db33249f81840aCraig CorneliusSimpleDateFormat::setTimeZoneFormat(const TimeZoneFormat& newTimeZoneFormat)
3328103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius{
3329103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius    delete fTimeZoneFormat;
3330103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius    fTimeZoneFormat = new TimeZoneFormat(newTimeZoneFormat);
3331103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius}
3332ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
3333ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru//----------------------------------------------------------------------
3334ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
3335ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
3336ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queruvoid SimpleDateFormat::adoptCalendar(Calendar* calendarToAdopt)
3337ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru{
3338ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru  UErrorCode status = U_ZERO_ERROR;
3339ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru  DateFormat::adoptCalendar(calendarToAdopt);
334050294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho  delete fSymbols;
3341ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru  fSymbols=NULL;
3342ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru  initializeSymbols(fLocale, fCalendar, status);  // we need new symbols
3343ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru  initializeDefaultCentury();  // we need a new century (possibly)
3344ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru}
3345ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
334685bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho
334785bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho//----------------------------------------------------------------------
334885bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho
334985bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho
3350fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius// override the DateFormat implementation in order to
3351fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius// lazily initialize fCapitalizationBrkIter
3352fceb39872958b9fa2505e63f8b8699a9e0f882f4ccorneliusvoid
3353fceb39872958b9fa2505e63f8b8699a9e0f882f4ccorneliusSimpleDateFormat::setContext(UDisplayContext value, UErrorCode& status)
3354103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius{
3355fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius    DateFormat::setContext(value, status);
3356fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius#if !UCONFIG_NO_BREAK_ITERATION
3357fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius    if (U_SUCCESS(status)) {
3358fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius        if ( fCapitalizationBrkIter == NULL && (value==UDISPCTX_CAPITALIZATION_FOR_BEGINNING_OF_SENTENCE ||
3359fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius                value==UDISPCTX_CAPITALIZATION_FOR_UI_LIST_OR_MENU || value==UDISPCTX_CAPITALIZATION_FOR_STANDALONE) ) {
3360fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius            UErrorCode status = U_ZERO_ERROR;
3361fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius            fCapitalizationBrkIter = BreakIterator::createSentenceInstance(fLocale, status);
3362fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius            if (U_FAILURE(status)) {
3363fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius                delete fCapitalizationBrkIter;
3364fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius                fCapitalizationBrkIter = NULL;
3365fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius            }
3366fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius        }
3367103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius    }
3368fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius#endif
3369103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius}
3370103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius
3371103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius
3372103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius//----------------------------------------------------------------------
3373103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius
3374103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius
337585bf2e2fbc60a9f938064abc8127d61da7d19882Claire HoUBool
337685bf2e2fbc60a9f938064abc8127d61da7d19882Claire HoSimpleDateFormat::isFieldUnitIgnored(UCalendarDateFields field) const {
337785bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    return isFieldUnitIgnored(fPattern, field);
337885bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho}
337985bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho
338085bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho
338185bf2e2fbc60a9f938064abc8127d61da7d19882Claire HoUBool
338250294ead5e5d23f5bbfed76e00e6b510bd41eee1clairehoSimpleDateFormat::isFieldUnitIgnored(const UnicodeString& pattern,
338385bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho                                     UCalendarDateFields field) {
338485bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    int32_t fieldLevel = fgCalendarFieldToLevel[field];
338585bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    int32_t level;
338685bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    UChar ch;
338785bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    UBool inQuote = FALSE;
338885bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    UChar prevCh = 0;
338985bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    int32_t count = 0;
339085bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho
339185bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    for (int32_t i = 0; i < pattern.length(); ++i) {
339285bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho        ch = pattern[i];
339385bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho        if (ch != prevCh && count > 0) {
339485bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho            level = fgPatternCharToLevel[prevCh - PATTERN_CHAR_BASE];
339585bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho            // the larger the level, the smaller the field unit.
339685bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho            if ( fieldLevel <= level ) {
339785bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho                return FALSE;
339885bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho            }
339985bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho            count = 0;
340085bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho        }
340185bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho        if (ch == QUOTE) {
340285bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho            if ((i+1) < pattern.length() && pattern[i+1] == QUOTE) {
340385bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho                ++i;
340485bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho            } else {
340585bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho                inQuote = ! inQuote;
340685bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho            }
340750294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho        }
340850294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho        else if ( ! inQuote && ((ch >= 0x0061 /*'a'*/ && ch <= 0x007A /*'z'*/)
340985bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho                    || (ch >= 0x0041 /*'A'*/ && ch <= 0x005A /*'Z'*/))) {
341085bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho            prevCh = ch;
341185bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho            ++count;
341285bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho        }
341385bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    }
341485bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    if ( count > 0 ) {
341585bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho        // last item
341685bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho        level = fgPatternCharToLevel[prevCh - PATTERN_CHAR_BASE];
341785bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho            if ( fieldLevel <= level ) {
341885bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho                return FALSE;
341985bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho            }
342085bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    }
342185bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    return TRUE;
342285bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho}
342385bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho
342485bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho//----------------------------------------------------------------------
342585bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho
342685bf2e2fbc60a9f938064abc8127d61da7d19882Claire Hoconst Locale&
342785bf2e2fbc60a9f938064abc8127d61da7d19882Claire HoSimpleDateFormat::getSmpFmtLocale(void) const {
342885bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    return fLocale;
342985bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho}
343085bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho
343185bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho//----------------------------------------------------------------------
343285bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho
343350294ead5e5d23f5bbfed76e00e6b510bd41eee1clairehoint32_t
343485bf2e2fbc60a9f938064abc8127d61da7d19882Claire HoSimpleDateFormat::checkIntSuffix(const UnicodeString& text, int32_t start,
343585bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho                                 int32_t patLoc, UBool isNegative) const {
343685bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    // local variables
343785bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    UnicodeString suf;
343885bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    int32_t patternMatch;
343985bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    int32_t textPreMatch;
344085bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    int32_t textPostMatch;
344185bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho
344285bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    // check that we are still in range
344385bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    if ( (start > text.length()) ||
344485bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho         (start < 0) ||
344585bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho         (patLoc < 0) ||
344685bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho         (patLoc > fPattern.length())) {
344785bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho        // out of range, don't advance location in text
344885bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho        return start;
344985bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    }
345085bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho
345185bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    // get the suffix
345227f654740f2a26ad62a5c155af9199af9e69b889claireho    DecimalFormat* decfmt = dynamic_cast<DecimalFormat*>(fNumberFormat);
345327f654740f2a26ad62a5c155af9199af9e69b889claireho    if (decfmt != NULL) {
345485bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho        if (isNegative) {
345527f654740f2a26ad62a5c155af9199af9e69b889claireho            suf = decfmt->getNegativeSuffix(suf);
345685bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho        }
345785bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho        else {
345827f654740f2a26ad62a5c155af9199af9e69b889claireho            suf = decfmt->getPositiveSuffix(suf);
345985bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho        }
346085bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    }
346150294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho
346285bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    // check for suffix
346385bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    if (suf.length() <= 0) {
346485bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho        return start;
346585bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    }
346685bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho
346785bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    // check suffix will be encountered in the pattern
346885bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    patternMatch = compareSimpleAffix(suf,fPattern,patLoc);
346985bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho
347085bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    // check if a suffix will be encountered in the text
347185bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    textPreMatch = compareSimpleAffix(suf,text,start);
347285bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho
347385bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    // check if a suffix was encountered in the text
347485bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    textPostMatch = compareSimpleAffix(suf,text,start-suf.length());
347585bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho
347685bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    // check for suffix match
347785bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    if ((textPreMatch >= 0) && (patternMatch >= 0) && (textPreMatch == patternMatch)) {
347885bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho        return start;
347985bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    }
348085bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    else if ((textPostMatch >= 0) && (patternMatch >= 0) && (textPostMatch == patternMatch)) {
348185bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho        return  start - suf.length();
348285bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    }
348385bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho
348485bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    // should not get here
348585bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    return start;
348685bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho}
348785bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho
348885bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho//----------------------------------------------------------------------
348985bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho
349085bf2e2fbc60a9f938064abc8127d61da7d19882Claire Hoint32_t
349150294ead5e5d23f5bbfed76e00e6b510bd41eee1clairehoSimpleDateFormat::compareSimpleAffix(const UnicodeString& affix,
349250294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho                   const UnicodeString& input,
349385bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho                   int32_t pos) const {
349485bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    int32_t start = pos;
349585bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    for (int32_t i=0; i<affix.length(); ) {
349685bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho        UChar32 c = affix.char32At(i);
349785bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho        int32_t len = U16_LENGTH(c);
3498b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho        if (PatternProps::isWhiteSpace(c)) {
349985bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho            // We may have a pattern like: \u200F \u0020
350085bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho            //        and input text like: \u200F \u0020
3501b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho            // Note that U+200F and U+0020 are Pattern_White_Space but only
350285bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho            // U+0020 is UWhiteSpace.  So we have to first do a direct
3503b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho            // match of the run of Pattern_White_Space in the pattern,
350485bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho            // then match any extra characters.
350585bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho            UBool literalMatch = FALSE;
350685bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho            while (pos < input.length() &&
350785bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho                   input.char32At(pos) == c) {
350885bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho                literalMatch = TRUE;
350985bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho                i += len;
351085bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho                pos += len;
351185bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho                if (i == affix.length()) {
351285bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho                    break;
351385bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho                }
351485bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho                c = affix.char32At(i);
351585bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho                len = U16_LENGTH(c);
3516b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho                if (!PatternProps::isWhiteSpace(c)) {
351785bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho                    break;
351885bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho                }
351985bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho            }
352085bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho
352185bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho            // Advance over run in pattern
3522b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho            i = skipPatternWhiteSpace(affix, i);
352385bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho
352485bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho            // Advance over run in input text
352585bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho            // Must see at least one white space char in input,
352685bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho            // unless we've already matched some characters literally.
352785bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho            int32_t s = pos;
352885bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho            pos = skipUWhiteSpace(input, pos);
352985bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho            if (pos == s && !literalMatch) {
353085bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho                return -1;
353185bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho            }
353285bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho
353385bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho            // If we skip UWhiteSpace in the input text, we need to skip it in the pattern.
353485bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho            // Otherwise, the previous lines may have skipped over text (such as U+00A0) that
353585bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho            // is also in the affix.
353685bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho            i = skipUWhiteSpace(affix, i);
353785bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho        } else {
353885bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho            if (pos < input.length() &&
353985bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho                input.char32At(pos) == c) {
354085bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho                i += len;
354185bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho                pos += len;
354285bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho            } else {
354385bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho                return -1;
354485bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho            }
354585bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho        }
354685bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    }
354785bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    return pos - start;
354885bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho}
354985bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho
355085bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho//----------------------------------------------------------------------
355185bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho
355250294ead5e5d23f5bbfed76e00e6b510bd41eee1clairehoint32_t
3553b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2clairehoSimpleDateFormat::skipPatternWhiteSpace(const UnicodeString& text, int32_t pos) const {
3554b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho    const UChar* s = text.getBuffer();
3555b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho    return (int32_t)(PatternProps::skipWhiteSpace(s + pos, text.length() - pos) - s);
355685bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho}
355785bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho
355885bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho//----------------------------------------------------------------------
355985bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho
356050294ead5e5d23f5bbfed76e00e6b510bd41eee1clairehoint32_t
356185bf2e2fbc60a9f938064abc8127d61da7d19882Claire HoSimpleDateFormat::skipUWhiteSpace(const UnicodeString& text, int32_t pos) const {
356285bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    while (pos < text.length()) {
356385bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho        UChar32 c = text.char32At(pos);
356485bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho        if (!u_isUWhiteSpace(c)) {
356585bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho            break;
356685bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho        }
356785bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho        pos += U16_LENGTH(c);
356885bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    }
356985bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    return pos;
357085bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho}
357185bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho
3572b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho//----------------------------------------------------------------------
3573b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho
3574b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho// Lazy TimeZoneFormat instantiation, semantically const.
3575b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2clairehoTimeZoneFormat *
3576b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2clairehoSimpleDateFormat::tzFormat() const {
3577b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho    if (fTimeZoneFormat == NULL) {
3578b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho        umtx_lock(&LOCK);
3579b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho        {
3580b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho            if (fTimeZoneFormat == NULL) {
3581b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho                UErrorCode status = U_ZERO_ERROR;
3582b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho                TimeZoneFormat *tzfmt = TimeZoneFormat::createInstance(fLocale, status);
3583103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius                if (U_FAILURE(status)) {
3584103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius                    return NULL;
3585103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius                }
3586b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho
3587b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho                const_cast<SimpleDateFormat *>(this)->fTimeZoneFormat = tzfmt;
3588b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho            }
3589b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho        }
3590b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho        umtx_unlock(&LOCK);
3591b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho    }
3592b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho    return fTimeZoneFormat;
3593b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho}
3594103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius
3595ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste QueruU_NAMESPACE_END
3596ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
3597ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru#endif /* #if !UCONFIG_NO_FORMATTING */
3598ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
3599ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru//eof
3600