1f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)/*
2f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)*******************************************************************************
3f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)* Copyright (C) 1997-2010, International Business Machines Corporation and    *
4f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)* others. All Rights Reserved.                                                *
5f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)*******************************************************************************
6f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)*
7f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)* File SMPDTFMT.CPP
8f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)*
9f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)* Modification History:
10f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)*
11f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)*   Date        Name        Description
12f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)*   02/19/97    aliu        Converted from java.
13f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)*   03/31/97    aliu        Modified extensively to work with 50 locales.
14f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)*   04/01/97    aliu        Added support for centuries.
15f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)*   07/09/97    helena      Made ParsePosition into a class.
16f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)*   07/21/98    stephen     Added initializeDefaultCentury.
17f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)*                             Removed getZoneIndex (added in DateFormatSymbols)
18f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)*                             Removed subParseLong
19f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)*                             Removed chk
20f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)*  02/22/99     stephen     Removed character literals for EBCDIC safety
21f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)*   10/14/99    aliu        Updated 2-digit year parsing so that only "00" thru
22f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)*                           "99" are recognized. {j28 4182066}
23f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)*   11/15/99    weiv        Added support for week of year/day of week format
24f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)********************************************************************************
25f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)*/
26f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
27f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)#define ZID_KEY_MAX 128
28f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
29f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)#include "unicode/utypes.h"
30f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
31f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)#if !UCONFIG_NO_FORMATTING
32f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
33f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)#include "unicode/smpdtfmt.h"
34f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)#include "unicode/dtfmtsym.h"
35f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)#include "unicode/ures.h"
36f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)#include "unicode/msgfmt.h"
37f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)#include "unicode/calendar.h"
38f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)#include "unicode/gregocal.h"
39f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)#include "unicode/timezone.h"
40f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)#include "unicode/decimfmt.h"
41f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)#include "unicode/dcfmtsym.h"
42f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)#include "unicode/uchar.h"
43f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)#include "unicode/ustring.h"
44f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)#include "unicode/basictz.h"
45f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)#include "unicode/simpletz.h"
46f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)#include "unicode/rbtz.h"
47f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)#include "unicode/vtzone.h"
48f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)#include "olsontz.h"
49f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)#include "util.h"
50f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)#include "fphdlimp.h"
51f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)#include "gregoimp.h"
52f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)#include "hebrwcal.h"
53f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)#include "cstring.h"
54f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)#include "uassert.h"
55f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)#include "zstrfmt.h"
56f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)#include "cmemory.h"
57f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)#include "umutex.h"
58f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)#include <float.h>
59f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
60f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)#if defined( U_DEBUG_CALSVC ) || defined (U_DEBUG_CAL)
61f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)#include <stdio.h>
62f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)#endif
63f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
64f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)// *****************************************************************************
65f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)// class SimpleDateFormat
66f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)// *****************************************************************************
67f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
68f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)U_NAMESPACE_BEGIN
69f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
70f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)static const UChar PATTERN_CHAR_BASE = 0x40;
71f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
72f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)/**
73f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) * Last-resort string to use for "GMT" when constructing time zone strings.
74f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) */
75f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)// For time zones that have no names, use strings GMT+minutes and
76f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)// GMT-minutes. For instance, in France the time zone is GMT+60.
77f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)// Also accepted are GMT+H:MM or GMT-H:MM.
78f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)static const UChar gGmt[]      = {0x0047, 0x004D, 0x0054, 0x0000};         // "GMT"
79f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)static const UChar gGmtPlus[]  = {0x0047, 0x004D, 0x0054, 0x002B, 0x0000}; // "GMT+"
80f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)static const UChar gGmtMinus[] = {0x0047, 0x004D, 0x0054, 0x002D, 0x0000}; // "GMT-"
81f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)static const UChar gDefGmtPat[]       = {0x0047, 0x004D, 0x0054, 0x007B, 0x0030, 0x007D, 0x0000}; /* GMT{0} */
82f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)static const UChar gDefGmtNegHmsPat[] = {0x002D, 0x0048, 0x0048, 0x003A, 0x006D, 0x006D, 0x003A, 0x0073, 0x0073, 0x0000}; /* -HH:mm:ss */
83f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)static const UChar gDefGmtNegHmPat[]  = {0x002D, 0x0048, 0x0048, 0x003A, 0x006D, 0x006D, 0x0000}; /* -HH:mm */
84f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)static const UChar gDefGmtPosHmsPat[] = {0x002B, 0x0048, 0x0048, 0x003A, 0x006D, 0x006D, 0x003A, 0x0073, 0x0073, 0x0000}; /* +HH:mm:ss */
85f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)static const UChar gDefGmtPosHmPat[]  = {0x002B, 0x0048, 0x0048, 0x003A, 0x006D, 0x006D, 0x0000}; /* +HH:mm */
86f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)static const UChar gUt[]       = {0x0055, 0x0054, 0x0000};  // "UT"
87f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)static const UChar gUtc[]      = {0x0055, 0x0054, 0x0043, 0x0000};  // "UT"
88f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
89f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)typedef enum GmtPatSize {
90f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    kGmtLen = 3,
91f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    kGmtPatLen = 6,
92f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    kNegHmsLen = 9,
93f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    kNegHmLen = 6,
94f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    kPosHmsLen = 9,
95f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    kPosHmLen = 6,
96f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    kUtLen = 2,
97f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    kUtcLen = 3
98f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)} GmtPatSize;
99f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
100f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)// Stuff needed for numbering system overrides
101f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
102f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)typedef enum OvrStrType {
103f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    kOvrStrDate = 0,
104f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    kOvrStrTime = 1,
105f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    kOvrStrBoth = 2
106f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)} OvrStrType;
107f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
108f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)static const UDateFormatField kDateFields[] = {
109f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    UDAT_YEAR_FIELD,
110f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    UDAT_MONTH_FIELD,
111f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    UDAT_DATE_FIELD,
112f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    UDAT_DAY_OF_YEAR_FIELD,
113f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    UDAT_DAY_OF_WEEK_IN_MONTH_FIELD,
114f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    UDAT_WEEK_OF_YEAR_FIELD,
115f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    UDAT_WEEK_OF_MONTH_FIELD,
116f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    UDAT_YEAR_WOY_FIELD,
117f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    UDAT_EXTENDED_YEAR_FIELD,
118f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    UDAT_JULIAN_DAY_FIELD,
119f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    UDAT_STANDALONE_DAY_FIELD,
120f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    UDAT_STANDALONE_MONTH_FIELD,
121f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    UDAT_QUARTER_FIELD,
122f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    UDAT_STANDALONE_QUARTER_FIELD };
123f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)static const int8_t kDateFieldsCount = 13;
124f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
125f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)static const UDateFormatField kTimeFields[] = {
126f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    UDAT_HOUR_OF_DAY1_FIELD,
127f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    UDAT_HOUR_OF_DAY0_FIELD,
128f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    UDAT_MINUTE_FIELD,
129f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    UDAT_SECOND_FIELD,
130f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    UDAT_FRACTIONAL_SECOND_FIELD,
131f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    UDAT_HOUR1_FIELD,
132f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    UDAT_HOUR0_FIELD,
133f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    UDAT_MILLISECONDS_IN_DAY_FIELD,
134f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    UDAT_TIMEZONE_RFC_FIELD };
135f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)static const int8_t kTimeFieldsCount = 9;
136f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
137f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
138f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)// This is a pattern-of-last-resort used when we can't load a usable pattern out
139f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)// of a resource.
140f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)static const UChar gDefaultPattern[] =
141f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles){
142f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    0x79, 0x79, 0x79, 0x79, 0x4D, 0x4D, 0x64, 0x64, 0x20, 0x68, 0x68, 0x3A, 0x6D, 0x6D, 0x20, 0x61, 0
143f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)};  /* "yyyyMMdd hh:mm a" */
144f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
145f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)// This prefix is designed to NEVER MATCH real text, in order to
146f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)// suppress the parsing of negative numbers.  Adjust as needed (if
147f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)// this becomes valid Unicode).
148f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)static const UChar SUPPRESS_NEGATIVE_PREFIX[] = {0xAB00, 0};
149f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
150f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)/**
151f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) * These are the tags we expect to see in normal resource bundle files associated
152f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) * with a locale.
153f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) */
154f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)static const char gDateTimePatternsTag[]="DateTimePatterns";
155f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
156f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)static const UChar gEtcUTC[] = {0x45, 0x74, 0x63, 0x2F, 0x55, 0x54, 0x43, 0x00}; // "Etc/UTC"
157f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)static const UChar QUOTE = 0x27; // Single quote
158f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
159f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)static UMTX LOCK;
160f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
161f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)UOBJECT_DEFINE_RTTI_IMPLEMENTATION(SimpleDateFormat)
162f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
163f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)//----------------------------------------------------------------------
164f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
165f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)SimpleDateFormat::~SimpleDateFormat()
166f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles){
167f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    delete fSymbols;
168f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    if (fGMTFormatters) {
169f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        for (int32_t i = 0; i < kNumGMTFormatters; i++) {
170f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)            if (fGMTFormatters[i]) {
171f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)                delete fGMTFormatters[i];
172f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)            }
173f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        }
174f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        uprv_free(fGMTFormatters);
175f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
176f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    }
177f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    if (fNumberFormatters) {
178f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        uprv_free(fNumberFormatters);
179f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    }
180f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
181f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    while (fOverrideList) {
182f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        NSOverride *cur = fOverrideList;
183f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        fOverrideList = cur->next;
184f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        delete cur->nf;
185f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        uprv_free(cur);
186f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    }
187f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)}
188f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
189f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)//----------------------------------------------------------------------
190f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
191f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)SimpleDateFormat::SimpleDateFormat(UErrorCode& status)
192f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)  :   fLocale(Locale::getDefault()),
193f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)      fSymbols(NULL),
194f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)      fGMTFormatters(NULL),
195f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)      fNumberFormatters(NULL),
196f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)      fOverrideList(NULL)
197f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles){
198f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    construct(kShort, (EStyle) (kShort + kDateOffset), fLocale, status);
199f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    initializeDefaultCentury();
200f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)}
201f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
202f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)//----------------------------------------------------------------------
203f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
204f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)SimpleDateFormat::SimpleDateFormat(const UnicodeString& pattern,
205f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)                                   UErrorCode &status)
206f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles):   fPattern(pattern),
207f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    fLocale(Locale::getDefault()),
208f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    fSymbols(NULL),
209f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    fGMTFormatters(NULL),
210f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    fNumberFormatters(NULL),
211f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    fOverrideList(NULL)
212f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles){
213f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    fDateOverride.setToBogus();
214f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    fTimeOverride.setToBogus();
215f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    initializeSymbols(fLocale, initializeCalendar(NULL,fLocale,status), status);
216f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    initialize(fLocale, status);
217f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    initializeDefaultCentury();
218f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
219f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)}
220f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)//----------------------------------------------------------------------
221f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
222f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)SimpleDateFormat::SimpleDateFormat(const UnicodeString& pattern,
223f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)                                   const UnicodeString& override,
224f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)                                   UErrorCode &status)
225f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles):   fPattern(pattern),
226f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    fLocale(Locale::getDefault()),
227f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    fSymbols(NULL),
228f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    fGMTFormatters(NULL),
229f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    fNumberFormatters(NULL),
230f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    fOverrideList(NULL)
231f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles){
232f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    fDateOverride.setTo(override);
233f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    fTimeOverride.setToBogus();
234f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    initializeSymbols(fLocale, initializeCalendar(NULL,fLocale,status), status);
235f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    initialize(fLocale, status);
236f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    initializeDefaultCentury();
237f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
238f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    processOverrideString(fLocale,override,kOvrStrBoth,status);
239f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
240f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)}
241f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
242f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)//----------------------------------------------------------------------
243f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
244f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)SimpleDateFormat::SimpleDateFormat(const UnicodeString& pattern,
245f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)                                   const Locale& locale,
246f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)                                   UErrorCode& status)
247f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles):   fPattern(pattern),
248f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    fLocale(locale),
249f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    fGMTFormatters(NULL),
250f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    fNumberFormatters(NULL),
251f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    fOverrideList(NULL)
252f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles){
253f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
254f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    fDateOverride.setToBogus();
255f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    fTimeOverride.setToBogus();
256f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
257f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    initializeSymbols(fLocale, initializeCalendar(NULL,fLocale,status), status);
258f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    initialize(fLocale, status);
259f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    initializeDefaultCentury();
260f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)}
261f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
262f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)//----------------------------------------------------------------------
263f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
264f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)SimpleDateFormat::SimpleDateFormat(const UnicodeString& pattern,
265f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)                                   const UnicodeString& override,
266f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)                                   const Locale& locale,
267f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)                                   UErrorCode& status)
268f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles):   fPattern(pattern),
269f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    fLocale(locale),
270f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    fGMTFormatters(NULL),
271f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    fNumberFormatters(NULL),
272f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    fOverrideList(NULL)
273f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles){
274f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
275f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    fDateOverride.setTo(override);
276f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    fTimeOverride.setToBogus();
277f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
278f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    initializeSymbols(fLocale, initializeCalendar(NULL,fLocale,status), status);
279f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    initialize(fLocale, status);
280f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    initializeDefaultCentury();
281f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
282f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    processOverrideString(locale,override,kOvrStrBoth,status);
283f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
284f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)}
285f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
286f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)//----------------------------------------------------------------------
287f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
288f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)SimpleDateFormat::SimpleDateFormat(const UnicodeString& pattern,
289f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)                                   DateFormatSymbols* symbolsToAdopt,
290f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)                                   UErrorCode& status)
291f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles):   fPattern(pattern),
292f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    fLocale(Locale::getDefault()),
293f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    fSymbols(symbolsToAdopt),
294f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    fGMTFormatters(NULL),
295f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    fNumberFormatters(NULL),
296f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    fOverrideList(NULL)
297f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles){
298f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
299f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    fDateOverride.setToBogus();
300f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    fTimeOverride.setToBogus();
301f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
302f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    initializeCalendar(NULL,fLocale,status);
303f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    initialize(fLocale, status);
304f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    initializeDefaultCentury();
305f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)}
306f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
307f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)//----------------------------------------------------------------------
308f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
309f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)SimpleDateFormat::SimpleDateFormat(const UnicodeString& pattern,
310f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)                                   const DateFormatSymbols& symbols,
311f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)                                   UErrorCode& status)
312f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles):   fPattern(pattern),
313f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    fLocale(Locale::getDefault()),
314f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    fSymbols(new DateFormatSymbols(symbols)),
315f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    fGMTFormatters(NULL),
316f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    fNumberFormatters(NULL),
317f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    fOverrideList(NULL)
318f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles){
319f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
320f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    fDateOverride.setToBogus();
321f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    fTimeOverride.setToBogus();
322f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
323f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    initializeCalendar(NULL, fLocale, status);
324f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    initialize(fLocale, status);
325f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    initializeDefaultCentury();
326f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)}
327f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
328f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)//----------------------------------------------------------------------
329f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
330f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)// Not for public consumption; used by DateFormat
331f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)SimpleDateFormat::SimpleDateFormat(EStyle timeStyle,
332f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)                                   EStyle dateStyle,
333f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)                                   const Locale& locale,
334f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)                                   UErrorCode& status)
335f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles):   fLocale(locale),
336f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    fSymbols(NULL),
337f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    fGMTFormatters(NULL),
338f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    fNumberFormatters(NULL),
339f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    fOverrideList(NULL)
340f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles){
341f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    construct(timeStyle, dateStyle, fLocale, status);
342f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    if(U_SUCCESS(status)) {
343f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)      initializeDefaultCentury();
344f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    }
345f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)}
346f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
347f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)//----------------------------------------------------------------------
348f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
349f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)/**
350f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) * Not for public consumption; used by DateFormat.  This constructor
351f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) * never fails.  If the resource data is not available, it uses the
352f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) * the last resort symbols.
353f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) */
354f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)SimpleDateFormat::SimpleDateFormat(const Locale& locale,
355f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)                                   UErrorCode& status)
356f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles):   fPattern(gDefaultPattern),
357f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    fLocale(locale),
358f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    fSymbols(NULL),
359f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    fGMTFormatters(NULL),
360f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    fNumberFormatters(NULL),
361f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    fOverrideList(NULL)
362f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles){
363f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    if (U_FAILURE(status)) return;
364f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    initializeSymbols(fLocale, initializeCalendar(NULL, fLocale, status),status);
365f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    if (U_FAILURE(status))
366f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    {
367f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        status = U_ZERO_ERROR;
368f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        delete fSymbols;
369f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        // This constructor doesn't fail; it uses last resort data
370f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        fSymbols = new DateFormatSymbols(status);
371f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        /* test for NULL */
372f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        if (fSymbols == 0) {
373f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)            status = U_MEMORY_ALLOCATION_ERROR;
374f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)            return;
375f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        }
376f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    }
377f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
378f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    fDateOverride.setToBogus();
379f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    fTimeOverride.setToBogus();
380f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
381f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    initialize(fLocale, status);
382f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    if(U_SUCCESS(status)) {
383f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)      initializeDefaultCentury();
384f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    }
385f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)}
386f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
387f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)//----------------------------------------------------------------------
388f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
389f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)SimpleDateFormat::SimpleDateFormat(const SimpleDateFormat& other)
390f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles):   DateFormat(other),
391f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    fSymbols(NULL),
392f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    fGMTFormatters(NULL),
393f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    fNumberFormatters(NULL),
394f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    fOverrideList(NULL)
395f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles){
396f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    *this = other;
397f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)}
398f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
399f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)//----------------------------------------------------------------------
400f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
401f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)SimpleDateFormat& SimpleDateFormat::operator=(const SimpleDateFormat& other)
402f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles){
403f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    if (this == &other) {
404f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        return *this;
405f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    }
406f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    DateFormat::operator=(other);
407f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
408f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    delete fSymbols;
409f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    fSymbols = NULL;
410f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
411f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    if (other.fSymbols)
412f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        fSymbols = new DateFormatSymbols(*other.fSymbols);
413f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
414f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    fDefaultCenturyStart         = other.fDefaultCenturyStart;
415f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    fDefaultCenturyStartYear     = other.fDefaultCenturyStartYear;
416f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    fHaveDefaultCentury          = other.fHaveDefaultCentury;
417f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
418f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    fPattern = other.fPattern;
419f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
420f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    return *this;
421f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)}
422f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
423f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)//----------------------------------------------------------------------
424f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
425f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)Format*
426f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)SimpleDateFormat::clone() const
427f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles){
428f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    return new SimpleDateFormat(*this);
429f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)}
430f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
431f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)//----------------------------------------------------------------------
432f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
433f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)UBool
434f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)SimpleDateFormat::operator==(const Format& other) const
435f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles){
436f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    if (DateFormat::operator==(other)) {
437f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        // DateFormat::operator== guarantees following cast is safe
438f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        SimpleDateFormat* that = (SimpleDateFormat*)&other;
439f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        return (fPattern             == that->fPattern &&
440f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)                fSymbols             != NULL && // Check for pathological object
441f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)                that->fSymbols       != NULL && // Check for pathological object
442f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)                *fSymbols            == *that->fSymbols &&
443f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)                fHaveDefaultCentury  == that->fHaveDefaultCentury &&
444f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)                fDefaultCenturyStart == that->fDefaultCenturyStart);
445f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    }
446f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    return FALSE;
447f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)}
448f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
449f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)//----------------------------------------------------------------------
450f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
451f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)void SimpleDateFormat::construct(EStyle timeStyle,
452f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)                                 EStyle dateStyle,
453f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)                                 const Locale& locale,
454f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)                                 UErrorCode& status)
455f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles){
456f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    // called by several constructors to load pattern data from the resources
457f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    if (U_FAILURE(status)) return;
458f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
459f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    // We will need the calendar to know what type of symbols to load.
460f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    initializeCalendar(NULL, locale, status);
461f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    if (U_FAILURE(status)) return;
462f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
463f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    CalendarData calData(locale, fCalendar?fCalendar->getType():NULL, status);
464f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    UResourceBundle *dateTimePatterns = calData.getByKey(gDateTimePatternsTag, status);
465f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    UResourceBundle *currentBundle;
466f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
467f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    if (U_FAILURE(status)) return;
468f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
469f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    if (ures_getSize(dateTimePatterns) <= kDateTime)
470f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    {
471f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        status = U_INVALID_FORMAT_ERROR;
472f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        return;
473f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    }
474f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
475f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    setLocaleIDs(ures_getLocaleByType(dateTimePatterns, ULOC_VALID_LOCALE, &status),
476f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)                 ures_getLocaleByType(dateTimePatterns, ULOC_ACTUAL_LOCALE, &status));
477f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
478f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    // create a symbols object from the locale
479f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    initializeSymbols(locale,fCalendar, status);
480f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    if (U_FAILURE(status)) return;
481f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    /* test for NULL */
482f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    if (fSymbols == 0) {
483f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        status = U_MEMORY_ALLOCATION_ERROR;
484f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        return;
485f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    }
486f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
487f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    const UChar *resStr,*ovrStr;
488f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    int32_t resStrLen,ovrStrLen = 0;
489f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    fDateOverride.setToBogus();
490f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    fTimeOverride.setToBogus();
491f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
492f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    // if the pattern should include both date and time information, use the date/time
493f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    // pattern string as a guide to tell use how to glue together the appropriate date
494f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    // and time pattern strings.  The actual gluing-together is handled by a convenience
495f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    // method on MessageFormat.
496f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    if ((timeStyle != kNone) && (dateStyle != kNone))
497f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    {
498f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        Formattable timeDateArray[2];
499f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
500f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        // use Formattable::adoptString() so that we can use fastCopyFrom()
501f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        // instead of Formattable::setString()'s unaware, safe, deep string clone
502f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        // see Jitterbug 2296
503f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
504f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        currentBundle = ures_getByIndex(dateTimePatterns, (int32_t)timeStyle, NULL, &status);
505f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        if (U_FAILURE(status)) {
506f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)           status = U_INVALID_FORMAT_ERROR;
507f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)           return;
508f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        }
509f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        switch (ures_getType(currentBundle)) {
510f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)            case URES_STRING: {
511f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)               resStr = ures_getString(currentBundle, &resStrLen, &status);
512f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)               break;
513f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)            }
514f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)            case URES_ARRAY: {
515f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)               resStr = ures_getStringByIndex(currentBundle, 0, &resStrLen, &status);
516f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)               ovrStr = ures_getStringByIndex(currentBundle, 1, &ovrStrLen, &status);
517f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)               fTimeOverride.setTo(TRUE, ovrStr, ovrStrLen);
518f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)               break;
519f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)            }
520f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)            default: {
521f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)               status = U_INVALID_FORMAT_ERROR;
522f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)               ures_close(currentBundle);
523f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)               return;
524f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)            }
525f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        }
526f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        ures_close(currentBundle);
527f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
528f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        UnicodeString *tempus1 = new UnicodeString(TRUE, resStr, resStrLen);
529f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        // NULL pointer check
530f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        if (tempus1 == NULL) {
531f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)            status = U_MEMORY_ALLOCATION_ERROR;
532f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)            return;
533f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        }
534f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        timeDateArray[0].adoptString(tempus1);
535f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
536f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        currentBundle = ures_getByIndex(dateTimePatterns, (int32_t)dateStyle, NULL, &status);
537f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        if (U_FAILURE(status)) {
538f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)           status = U_INVALID_FORMAT_ERROR;
539f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)           return;
540f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        }
541f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        switch (ures_getType(currentBundle)) {
542f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)            case URES_STRING: {
543f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)               resStr = ures_getString(currentBundle, &resStrLen, &status);
544f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)               break;
545f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)            }
546f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)            case URES_ARRAY: {
547f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)               resStr = ures_getStringByIndex(currentBundle, 0, &resStrLen, &status);
548f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)               ovrStr = ures_getStringByIndex(currentBundle, 1, &ovrStrLen, &status);
549f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)               fDateOverride.setTo(TRUE, ovrStr, ovrStrLen);
550f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)               break;
551f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)            }
552f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)            default: {
553f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)               status = U_INVALID_FORMAT_ERROR;
554f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)               ures_close(currentBundle);
555f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)               return;
556f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)            }
557f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        }
558f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        ures_close(currentBundle);
559f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
560f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        UnicodeString *tempus2 = new UnicodeString(TRUE, resStr, resStrLen);
561f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        // Null pointer check
562f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        if (tempus2 == NULL) {
563f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)            status = U_MEMORY_ALLOCATION_ERROR;
564f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)            return;
565f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        }
566f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        timeDateArray[1].adoptString(tempus2);
567f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
568f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        int32_t glueIndex = kDateTime;
569f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        int32_t patternsSize = ures_getSize(dateTimePatterns);
570f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        if (patternsSize >= (kDateTimeOffset + kShort + 1)) {
571f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)            // Get proper date time format
572f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)            glueIndex = (int32_t)(kDateTimeOffset + (dateStyle - kDateOffset));
573f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        }
574f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
575f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        resStr = ures_getStringByIndex(dateTimePatterns, glueIndex, &resStrLen, &status);
576f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        MessageFormat::format(UnicodeString(TRUE, resStr, resStrLen), timeDateArray, 2, fPattern, status);
577f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    }
578f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    // if the pattern includes just time data or just date date, load the appropriate
579f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    // pattern string from the resources
580f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    // setTo() - see DateFormatSymbols::assignArray comments
581f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    else if (timeStyle != kNone) {
582f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        currentBundle = ures_getByIndex(dateTimePatterns, (int32_t)timeStyle, NULL, &status);
583f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        if (U_FAILURE(status)) {
584f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)           status = U_INVALID_FORMAT_ERROR;
585f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)           return;
586f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        }
587f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        switch (ures_getType(currentBundle)) {
588f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)            case URES_STRING: {
589f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)               resStr = ures_getString(currentBundle, &resStrLen, &status);
590f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)               break;
591f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)            }
592f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)            case URES_ARRAY: {
593f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)               resStr = ures_getStringByIndex(currentBundle, 0, &resStrLen, &status);
594f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)               ovrStr = ures_getStringByIndex(currentBundle, 1, &ovrStrLen, &status);
595f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)               fDateOverride.setTo(TRUE, ovrStr, ovrStrLen);
596f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)               break;
597f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)            }
598f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)            default: {
599f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)               status = U_INVALID_FORMAT_ERROR;
600f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)                ures_close(currentBundle);
601f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)               return;
602f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)            }
603f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        }
604f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        fPattern.setTo(TRUE, resStr, resStrLen);
605f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        ures_close(currentBundle);
606f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    }
607f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    else if (dateStyle != kNone) {
608f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        currentBundle = ures_getByIndex(dateTimePatterns, (int32_t)dateStyle, NULL, &status);
609f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        if (U_FAILURE(status)) {
610f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)           status = U_INVALID_FORMAT_ERROR;
611f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)           return;
612f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        }
613f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        switch (ures_getType(currentBundle)) {
614f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)            case URES_STRING: {
615f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)               resStr = ures_getString(currentBundle, &resStrLen, &status);
616f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)               break;
617f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)            }
618f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)            case URES_ARRAY: {
619f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)               resStr = ures_getStringByIndex(currentBundle, 0, &resStrLen, &status);
620f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)               ovrStr = ures_getStringByIndex(currentBundle, 1, &ovrStrLen, &status);
621f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)               fDateOverride.setTo(TRUE, ovrStr, ovrStrLen);
622f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)               break;
623f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)            }
624f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)            default: {
625f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)               status = U_INVALID_FORMAT_ERROR;
626f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)               ures_close(currentBundle);
627f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)               return;
628f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)            }
629f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        }
630f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        fPattern.setTo(TRUE, resStr, resStrLen);
631f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        ures_close(currentBundle);
632f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    }
633f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
634f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    // and if it includes _neither_, that's an error
635f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    else
636f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        status = U_INVALID_FORMAT_ERROR;
637f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
638f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    // finally, finish initializing by creating a Calendar and a NumberFormat
639f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    initialize(locale, status);
640f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)}
641f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
642f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)//----------------------------------------------------------------------
643f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
644f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)Calendar*
645f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)SimpleDateFormat::initializeCalendar(TimeZone* adoptZone, const Locale& locale, UErrorCode& status)
646f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles){
647f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    if(!U_FAILURE(status)) {
648f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        fCalendar = Calendar::createInstance(adoptZone?adoptZone:TimeZone::createDefault(), locale, status);
649f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    }
650f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    if (U_SUCCESS(status) && fCalendar == NULL) {
651f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        status = U_MEMORY_ALLOCATION_ERROR;
652f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    }
653f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    return fCalendar;
654f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)}
655f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
656f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)void
657f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)SimpleDateFormat::initializeSymbols(const Locale& locale, Calendar* calendar, UErrorCode& status)
658f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles){
659f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)  if(U_FAILURE(status)) {
660f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    fSymbols = NULL;
661f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)  } else {
662f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    // pass in calendar type - use NULL (default) if no calendar set (or err).
663f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    fSymbols = new DateFormatSymbols(locale, calendar?calendar->getType() :NULL , status);
664f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    // Null pointer check
665f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    if (fSymbols == NULL) {
666f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    	status = U_MEMORY_ALLOCATION_ERROR;
667f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    	return;
668f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    }
669f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)  }
670f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)}
671f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
672f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)void
673f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)SimpleDateFormat::initialize(const Locale& locale,
674f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)                             UErrorCode& status)
675f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles){
676f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    if (U_FAILURE(status)) return;
677f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
678f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    // We don't need to check that the row count is >= 1, since all 2d arrays have at
679f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    // least one row
680f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    fNumberFormat = NumberFormat::createInstance(locale, status);
681f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    if (fNumberFormat != NULL && U_SUCCESS(status))
682f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    {
683f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        // no matter what the locale's default number format looked like, we want
684f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        // to modify it so that it doesn't use thousands separators, doesn't always
685f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        // show the decimal point, and recognizes integers only when parsing
686f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
687f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        fNumberFormat->setGroupingUsed(FALSE);
688f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        DecimalFormat* decfmt = dynamic_cast<DecimalFormat*>(fNumberFormat);
689f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        if (decfmt != NULL) {
690f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)            decfmt->setDecimalSeparatorAlwaysShown(FALSE);
691f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        }
692f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        fNumberFormat->setParseIntegerOnly(TRUE);
693f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        fNumberFormat->setMinimumFractionDigits(0); // To prevent "Jan 1.00, 1997.00"
694f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
695f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        initNumberFormatters(locale,status);
696f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
697f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    }
698f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    else if (U_SUCCESS(status))
699f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    {
700f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        status = U_MISSING_RESOURCE_ERROR;
701f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    }
702f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)}
703f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
704f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)/* Initialize the fields we use to disambiguate ambiguous years. Separate
705f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) * so we can call it from readObject().
706f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) */
707f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)void SimpleDateFormat::initializeDefaultCentury()
708f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles){
709f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)  if(fCalendar) {
710f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    fHaveDefaultCentury = fCalendar->haveDefaultCentury();
711f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    if(fHaveDefaultCentury) {
712f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)      fDefaultCenturyStart = fCalendar->defaultCenturyStart();
713f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)      fDefaultCenturyStartYear = fCalendar->defaultCenturyStartYear();
714f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    } else {
715f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)      fDefaultCenturyStart = DBL_MIN;
716f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)      fDefaultCenturyStartYear = -1;
717f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    }
718f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)  }
719f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)}
720f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
721f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)/* Define one-century window into which to disambiguate dates using
722f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) * two-digit years. Make public in JDK 1.2.
723f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) */
724f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)void SimpleDateFormat::parseAmbiguousDatesAsAfter(UDate startDate, UErrorCode& status)
725f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles){
726f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    if(U_FAILURE(status)) {
727f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        return;
728f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    }
729f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    if(!fCalendar) {
730f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)      status = U_ILLEGAL_ARGUMENT_ERROR;
731f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)      return;
732f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    }
733f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
734f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    fCalendar->setTime(startDate, status);
735f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    if(U_SUCCESS(status)) {
736f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        fHaveDefaultCentury = TRUE;
737f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        fDefaultCenturyStart = startDate;
738f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        fDefaultCenturyStartYear = fCalendar->get(UCAL_YEAR, status);
739f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    }
740f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)}
741f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
742f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)//----------------------------------------------------------------------
743f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
744f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)UnicodeString&
745f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)SimpleDateFormat::format(Calendar& cal, UnicodeString& appendTo, FieldPosition& pos) const
746f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles){
747f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)  UErrorCode status = U_ZERO_ERROR;
748f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)  FieldPositionOnlyHandler handler(pos);
749f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)  return _format(cal, appendTo, handler, status);
750f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)}
751f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
752f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)//----------------------------------------------------------------------
753f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
754f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)UnicodeString&
755f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)SimpleDateFormat::format(Calendar& cal, UnicodeString& appendTo,
756f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)                         FieldPositionIterator* posIter, UErrorCode& status) const
757f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles){
758f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)  FieldPositionIteratorHandler handler(posIter, status);
759f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)  return _format(cal, appendTo, handler, status);
760f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)}
761f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
762f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)//----------------------------------------------------------------------
763f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
764f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)UnicodeString&
765f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)SimpleDateFormat::_format(Calendar& cal, UnicodeString& appendTo, FieldPositionHandler& handler,
766f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)                          UErrorCode& status) const
767f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles){
768f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    Calendar *workCal = &cal;
769f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    TimeZone *backupTZ = NULL;
770f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    if (&cal != fCalendar && uprv_strcmp(cal.getType(), fCalendar->getType()) != 0) {
771f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        // Different calendar type
772f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        // We use the time and time zone from the input calendar, but
773f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        // do not use the input calendar for field calculation.
774f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        UDate t = cal.getTime(status);
775f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        fCalendar->setTime(t, status);
776f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        backupTZ = fCalendar->getTimeZone().clone();
777f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        fCalendar->setTimeZone(cal.getTimeZone());
778f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        workCal = fCalendar;
779f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    }
780f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
781f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    UBool inQuote = FALSE;
782f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    UChar prevCh = 0;
783f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    int32_t count = 0;
784f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
785f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    // loop through the pattern string character by character
786f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    for (int32_t i = 0; i < fPattern.length() && U_SUCCESS(status); ++i) {
787f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        UChar ch = fPattern[i];
788f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
789f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        // Use subFormat() to format a repeated pattern character
790f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        // when a different pattern or non-pattern character is seen
791f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        if (ch != prevCh && count > 0) {
792f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)            subFormat(appendTo, prevCh, count, handler, *workCal, status);
793f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)            count = 0;
794f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        }
795f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        if (ch == QUOTE) {
796f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)            // Consecutive single quotes are a single quote literal,
797f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)            // either outside of quotes or between quotes
798f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)            if ((i+1) < fPattern.length() && fPattern[i+1] == QUOTE) {
799f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)                appendTo += (UChar)QUOTE;
800f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)                ++i;
801f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)            } else {
802f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)                inQuote = ! inQuote;
803f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)            }
804f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        }
805f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        else if ( ! inQuote && ((ch >= 0x0061 /*'a'*/ && ch <= 0x007A /*'z'*/)
806f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)                    || (ch >= 0x0041 /*'A'*/ && ch <= 0x005A /*'Z'*/))) {
807f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)            // ch is a date-time pattern character to be interpreted
808f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)            // by subFormat(); count the number of times it is repeated
809f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)            prevCh = ch;
810f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)            ++count;
811f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        }
812f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        else {
813f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)            // Append quoted characters and unquoted non-pattern characters
814f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)            appendTo += ch;
815f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        }
816f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    }
817f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
818f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    // Format the last item in the pattern, if any
819f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    if (count > 0) {
820f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        subFormat(appendTo, prevCh, count, handler, *workCal, status);
821f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    }
822f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
823f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    if (backupTZ != NULL) {
824f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        // Restore the original time zone
825f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        fCalendar->adoptTimeZone(backupTZ);
826f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    }
827f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
828f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    return appendTo;
829f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)}
830f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
831f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)//----------------------------------------------------------------------
832f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
833f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)/* Map calendar field into calendar field level.
834f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) * the larger the level, the smaller the field unit.
835f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) * For example, UCAL_ERA level is 0, UCAL_YEAR level is 10,
836f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) * UCAL_MONTH level is 20.
837f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) * NOTE: if new fields adds in, the table needs to update.
838f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) */
839f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)const int32_t
840f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)SimpleDateFormat::fgCalendarFieldToLevel[] =
841f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles){
842f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    /*GyM*/ 0, 10, 20,
843f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    /*wW*/ 20, 30,
844f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    /*dDEF*/ 30, 20, 30, 30,
845f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    /*ahHm*/ 40, 50, 50, 60,
846f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    /*sS..*/ 70, 80,
847f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    /*z?Y*/ 0, 0, 10,
848f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    /*eug*/ 30, 10, 0,
849f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    /*A*/ 40
850f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)};
851f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
852f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
853f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)/* Map calendar field LETTER into calendar field level.
854f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) * the larger the level, the smaller the field unit.
855f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) * NOTE: if new fields adds in, the table needs to update.
856f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) */
857f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)const int32_t
858f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)SimpleDateFormat::fgPatternCharToLevel[] = {
859f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    //       A   B   C   D   E   F   G   H   I   J   K   L   M   N   O
860f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        -1, 40, -1, -1, 20,  30, 30,  0,  50, -1, -1, 50, 20,  20, -1, -1,
861f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    //   P   Q   R   S   T   U   V   W   X   Y   Z
862f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        -1, 20, -1,  80, -1, -1, 0, 30, -1, 10, 0, -1, -1, -1, -1, -1,
863f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    //       a   b   c   d   e   f   g   h   i   j   k   l   m   n   o
864f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        -1, 40, -1, 30,  30, 30, -1, 0, 50, -1, -1,  50, -1,  60, -1, -1,
865f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    //   p   q   r   s   t   u   v   w   x   y   z
866f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        -1, 20, -1,  70, -1, 10, 0, 20, -1,  10, 0, -1, -1, -1, -1, -1
867f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)};
868f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
869f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
870f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)// Map index into pattern character string to Calendar field number.
871f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)const UCalendarDateFields
872f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)SimpleDateFormat::fgPatternIndexToCalendarField[] =
873f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles){
874f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    /*GyM*/ UCAL_ERA, UCAL_YEAR, UCAL_MONTH,
875f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    /*dkH*/ UCAL_DATE, UCAL_HOUR_OF_DAY, UCAL_HOUR_OF_DAY,
876f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    /*msS*/ UCAL_MINUTE, UCAL_SECOND, UCAL_MILLISECOND,
877f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    /*EDF*/ UCAL_DAY_OF_WEEK, UCAL_DAY_OF_YEAR, UCAL_DAY_OF_WEEK_IN_MONTH,
878f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    /*wWa*/ UCAL_WEEK_OF_YEAR, UCAL_WEEK_OF_MONTH, UCAL_AM_PM,
879f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    /*hKz*/ UCAL_HOUR, UCAL_HOUR, UCAL_ZONE_OFFSET,
880f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    /*Yeu*/ UCAL_YEAR_WOY, UCAL_DOW_LOCAL, UCAL_EXTENDED_YEAR,
881f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    /*gAZ*/ UCAL_JULIAN_DAY, UCAL_MILLISECONDS_IN_DAY, UCAL_ZONE_OFFSET,
882f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    /*v*/   UCAL_ZONE_OFFSET,
883f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    /*c*/   UCAL_DOW_LOCAL,
884f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    /*L*/   UCAL_MONTH,
885f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    /*Q*/   UCAL_MONTH,
886f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    /*q*/   UCAL_MONTH,
887f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    /*V*/   UCAL_ZONE_OFFSET,
888f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)};
889f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
890f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)// Map index into pattern character string to DateFormat field number
891f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)const UDateFormatField
892f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)SimpleDateFormat::fgPatternIndexToDateFormatField[] = {
893f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    /*GyM*/ UDAT_ERA_FIELD, UDAT_YEAR_FIELD, UDAT_MONTH_FIELD,
894f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    /*dkH*/ UDAT_DATE_FIELD, UDAT_HOUR_OF_DAY1_FIELD, UDAT_HOUR_OF_DAY0_FIELD,
895f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    /*msS*/ UDAT_MINUTE_FIELD, UDAT_SECOND_FIELD, UDAT_FRACTIONAL_SECOND_FIELD,
896f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    /*EDF*/ UDAT_DAY_OF_WEEK_FIELD, UDAT_DAY_OF_YEAR_FIELD, UDAT_DAY_OF_WEEK_IN_MONTH_FIELD,
897f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    /*wWa*/ UDAT_WEEK_OF_YEAR_FIELD, UDAT_WEEK_OF_MONTH_FIELD, UDAT_AM_PM_FIELD,
898f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    /*hKz*/ UDAT_HOUR1_FIELD, UDAT_HOUR0_FIELD, UDAT_TIMEZONE_FIELD,
899f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    /*Yeu*/ UDAT_YEAR_WOY_FIELD, UDAT_DOW_LOCAL_FIELD, UDAT_EXTENDED_YEAR_FIELD,
900f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    /*gAZ*/ UDAT_JULIAN_DAY_FIELD, UDAT_MILLISECONDS_IN_DAY_FIELD, UDAT_TIMEZONE_RFC_FIELD,
901f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    /*v*/   UDAT_TIMEZONE_GENERIC_FIELD,
902f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    /*c*/   UDAT_STANDALONE_DAY_FIELD,
903f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    /*L*/   UDAT_STANDALONE_MONTH_FIELD,
904f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    /*Q*/   UDAT_QUARTER_FIELD,
905f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    /*q*/   UDAT_STANDALONE_QUARTER_FIELD,
906f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    /*V*/   UDAT_TIMEZONE_SPECIAL_FIELD,
907f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)};
908f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
909f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)//----------------------------------------------------------------------
910f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
911f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)/**
912f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) * Append symbols[value] to dst.  Make sure the array index is not out
913f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) * of bounds.
914f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) */
915f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)static inline void
916f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)_appendSymbol(UnicodeString& dst,
917f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)              int32_t value,
918f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)              const UnicodeString* symbols,
919f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)              int32_t symbolsCount) {
920f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    U_ASSERT(0 <= value && value < symbolsCount);
921f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    if (0 <= value && value < symbolsCount) {
922f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        dst += symbols[value];
923f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    }
924f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)}
925f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
926f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)//---------------------------------------------------------------------
927f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)void
928f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)SimpleDateFormat::appendGMT(NumberFormat *currentNumberFormat,UnicodeString &appendTo, Calendar& cal, UErrorCode& status) const{
929f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    int32_t offset = cal.get(UCAL_ZONE_OFFSET, status) + cal.get(UCAL_DST_OFFSET, status);
930f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    if (U_FAILURE(status)) {
931f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        return;
932f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    }
933f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    if (isDefaultGMTFormat()) {
934f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        formatGMTDefault(currentNumberFormat,appendTo, offset);
935f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    } else {
936f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        ((SimpleDateFormat*)this)->initGMTFormatters(status);
937f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        if (U_SUCCESS(status)) {
938f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)            int32_t type;
939f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)            if (offset < 0) {
940f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)                offset = -offset;
941f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)                type = (offset % U_MILLIS_PER_MINUTE) == 0 ? kGMTNegativeHM : kGMTNegativeHMS;
942f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)            } else {
943f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)                type = (offset % U_MILLIS_PER_MINUTE) == 0 ? kGMTPositiveHM : kGMTPositiveHMS;
944f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)            }
945f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)            Formattable param(offset, Formattable::kIsDate);
946f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)            FieldPosition fpos(0);
947f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)            fGMTFormatters[type]->format(&param, 1, appendTo, fpos, status);
948f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        }
949f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    }
950f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)}
951f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
952f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)int32_t
953f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)SimpleDateFormat::parseGMT(const UnicodeString &text, ParsePosition &pos) const {
954f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    if (!isDefaultGMTFormat()) {
955f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        int32_t start = pos.getIndex();
956f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
957f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        // Quick check
958f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        UBool prefixMatch = FALSE;
959f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        int32_t prefixLen = fSymbols->fGmtFormat.indexOf((UChar)0x007B /* '{' */);
960f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        if (prefixLen > 0 && text.compare(start, prefixLen, fSymbols->fGmtFormat, 0, prefixLen) == 0) {
961f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)            prefixMatch = TRUE;
962f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        }
963f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        if (prefixMatch) {
964f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)            // Prefix matched
965f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)            UErrorCode status = U_ZERO_ERROR;
966f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)            ((SimpleDateFormat*)this)->initGMTFormatters(status);
967f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)            if (U_SUCCESS(status)) {
968f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)                Formattable parsed;
969f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)                int32_t parsedCount;
970f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
971f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)                // Try negative Hms
972f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)                fGMTFormatters[kGMTNegativeHMS]->parseObject(text, parsed, pos);
973f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)                if (pos.getErrorIndex() == -1 &&
974f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)                    (pos.getIndex() - start) >= fGMTFormatHmsMinLen[kGMTNegativeHMSMinLenIdx]) {
975f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)                    parsed.getArray(parsedCount);
976f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)                    if (parsedCount == 1 && parsed[0].getType() == Formattable::kDate) {
977f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)                        return (int32_t)(-1 * (int64_t)parsed[0].getDate());
978f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)                    }
979f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)                }
980f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
981f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)                // Reset ParsePosition
982f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)                pos.setIndex(start);
983f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)                pos.setErrorIndex(-1);
984f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
985f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)                // Try positive Hms
986f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)                fGMTFormatters[kGMTPositiveHMS]->parseObject(text, parsed, pos);
987f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)                if (pos.getErrorIndex() == -1 &&
988f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)                    (pos.getIndex() - start) >= fGMTFormatHmsMinLen[kGMTPositiveHMSMinLenIdx]) {
989f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)                    parsed.getArray(parsedCount);
990f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)                    if (parsedCount == 1 && parsed[0].getType() == Formattable::kDate) {
991f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)                        return (int32_t)((int64_t)parsed[0].getDate());
992f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)                    }
993f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)                }
994f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
995f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)                // Reset ParsePosition
996f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)                pos.setIndex(start);
997f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)                pos.setErrorIndex(-1);
998f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
999f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)                // Try negative Hm
1000f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)                fGMTFormatters[kGMTNegativeHM]->parseObject(text, parsed, pos);
1001f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)                if (pos.getErrorIndex() == -1 && pos.getIndex() > start) {
1002f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)                    parsed.getArray(parsedCount);
1003f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)                    if (parsedCount == 1 && parsed[0].getType() == Formattable::kDate) {
1004f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)                        return (int32_t)(-1 * (int64_t)parsed[0].getDate());
1005f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)                    }
1006f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)                }
1007f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
1008f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)                // Reset ParsePosition
1009f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)                pos.setIndex(start);
1010f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)                pos.setErrorIndex(-1);
1011f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
1012f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)                // Try positive Hm
1013f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)                fGMTFormatters[kGMTPositiveHM]->parseObject(text, parsed, pos);
1014f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)                if (pos.getErrorIndex() == -1 && pos.getIndex() > start) {
1015f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)                    parsed.getArray(parsedCount);
1016f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)                    if (parsedCount == 1 && parsed[0].getType() == Formattable::kDate) {
1017f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)                        return (int32_t)((int64_t)parsed[0].getDate());
1018f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)                    }
1019f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)                }
1020f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
1021f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)                // Reset ParsePosition
1022f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)                pos.setIndex(start);
1023f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)                pos.setErrorIndex(-1);
1024f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)            }
1025f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)            // fall through to the default GMT parsing method
1026f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        }
1027f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    }
1028f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    return parseGMTDefault(text, pos);
1029f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)}
1030f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
1031f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)void
1032f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)SimpleDateFormat::formatGMTDefault(NumberFormat *currentNumberFormat,UnicodeString &appendTo, int32_t offset) const {
1033f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    if (offset < 0) {
1034f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        appendTo += gGmtMinus;
1035f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        offset = -offset; // suppress the '-' sign for text display.
1036f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    }else{
1037f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        appendTo += gGmtPlus;
1038f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    }
1039f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
1040f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    offset /= U_MILLIS_PER_SECOND; // now in seconds
1041f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    int32_t sec = offset % 60;
1042f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    offset /= 60;
1043f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    int32_t min = offset % 60;
1044f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    int32_t hour = offset / 60;
1045f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
1046f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
1047f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    zeroPaddingNumber(currentNumberFormat,appendTo, hour, 2, 2);
1048f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    appendTo += (UChar)0x003A /*':'*/;
1049f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    zeroPaddingNumber(currentNumberFormat,appendTo, min, 2, 2);
1050f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    if (sec != 0) {
1051f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        appendTo += (UChar)0x003A /*':'*/;
1052f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        zeroPaddingNumber(currentNumberFormat,appendTo, sec, 2, 2);
1053f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    }
1054f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)}
1055f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
1056f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)int32_t
1057f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)SimpleDateFormat::parseGMTDefault(const UnicodeString &text, ParsePosition &pos) const {
1058f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    int32_t start = pos.getIndex();
1059f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    NumberFormat *currentNumberFormat = getNumberFormatByIndex(UDAT_TIMEZONE_RFC_FIELD);
1060f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
1061f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    if (start + kUtLen + 1 >= text.length()) {
1062f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        pos.setErrorIndex(start);
1063f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        return 0;
1064f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    }
1065f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
1066f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    int32_t cur = start;
1067f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    // "GMT"
1068f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    if (text.compare(start, kGmtLen, gGmt) == 0) {
1069f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        cur += kGmtLen;
1070f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    } else if (text.compare(start, kUtLen, gUt) == 0) {
1071f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        cur += kUtLen;
1072f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    } else {
1073f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        pos.setErrorIndex(start);
1074f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        return 0;
1075f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    }
1076f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    // Sign
1077f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    UBool negative = FALSE;
1078f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    if (text.charAt(cur) == (UChar)0x002D /* minus */) {
1079f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        negative = TRUE;
1080f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    } else if (text.charAt(cur) != (UChar)0x002B /* plus */) {
1081f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        pos.setErrorIndex(cur);
1082f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        return 0;
1083f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    }
1084f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    cur++;
1085f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
1086f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    // Numbers
1087f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    int32_t numLen;
1088f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    pos.setIndex(cur);
1089f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
1090f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    Formattable number;
1091f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    parseInt(text, number, 6, pos, FALSE,currentNumberFormat);
1092f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    numLen = pos.getIndex() - cur;
1093f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
1094f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    if (numLen <= 0) {
1095f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        pos.setIndex(start);
1096f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        pos.setErrorIndex(cur);
1097f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        return 0;
1098f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    }
1099f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
1100f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    int32_t numVal = number.getLong();
1101f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
1102f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    int32_t hour = 0;
1103f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    int32_t min = 0;
1104f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    int32_t sec = 0;
1105f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
1106f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    if (numLen <= 2) {
1107f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        // H[H][:mm[:ss]]
1108f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        hour = numVal;
1109f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        cur += numLen;
1110f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        if (cur + 2 < text.length() && text.charAt(cur) == (UChar)0x003A /* colon */) {
1111f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)            cur++;
1112f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)            pos.setIndex(cur);
1113f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)            parseInt(text, number, 2, pos, FALSE,currentNumberFormat);
1114f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)            numLen = pos.getIndex() - cur;
1115f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)            if (numLen == 2) {
1116f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)                // got minute field
1117f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)                min = number.getLong();
1118f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)                cur += numLen;
1119f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)                if (cur + 2 < text.length() && text.charAt(cur) == (UChar)0x003A /* colon */) {
1120f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)                    cur++;
1121f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)                    pos.setIndex(cur);
1122f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)                    parseInt(text, number, 2, pos, FALSE,currentNumberFormat);
1123f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)                    numLen = pos.getIndex() - cur;
1124f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)                    if (numLen == 2) {
1125f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)                        // got second field
1126f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)                        sec = number.getLong();
1127f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)                    } else {
1128f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)                        // reset position
1129f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)                        pos.setIndex(cur - 1);
1130f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)                        pos.setErrorIndex(-1);
1131f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)                    }
1132f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)                }
1133f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)            } else {
1134f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)                // reset postion
1135f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)                pos.setIndex(cur - 1);
1136f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)                pos.setErrorIndex(-1);
1137f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)            }
1138f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        }
1139f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    } else if (numLen == 3 || numLen == 4) {
1140f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        // Hmm or HHmm
1141f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        hour = numVal / 100;
1142f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        min = numVal % 100;
1143f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    } else if (numLen == 5 || numLen == 6) {
1144f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        // Hmmss or HHmmss
1145f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        hour = numVal / 10000;
1146f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        min = (numVal % 10000) / 100;
1147f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        sec = numVal % 100;
1148f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    } else {
1149f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        // HHmmss followed by bogus numbers
1150f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        pos.setIndex(cur + 6);
1151f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
1152f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        int32_t shift = numLen - 6;
1153f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        while (shift > 0) {
1154f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)            numVal /= 10;
1155f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)            shift--;
1156f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        }
1157f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        hour = numVal / 10000;
1158f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        min = (numVal % 10000) / 100;
1159f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        sec = numVal % 100;
1160f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    }
1161f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
1162f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    int32_t offset = ((hour*60 + min)*60 + sec)*1000;
1163f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    if (negative) {
1164f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        offset = -offset;
1165f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    }
1166f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    return offset;
1167f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)}
1168f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
1169f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)UBool
1170f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)SimpleDateFormat::isDefaultGMTFormat() const {
1171f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    // GMT pattern
1172f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    if (fSymbols->fGmtFormat.length() == 0) {
1173f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        // No GMT pattern is set
1174f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        return TRUE;
1175f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    } else if (fSymbols->fGmtFormat.compare(gDefGmtPat, kGmtPatLen) != 0) {
1176f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        return FALSE;
1177f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    }
1178f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    // Hour patterns
1179f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    if (fSymbols->fGmtHourFormats == NULL || fSymbols->fGmtHourFormatsCount != DateFormatSymbols::GMT_HOUR_COUNT) {
1180f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        // No Hour pattern is set
1181f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        return TRUE;
1182f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    } else if ((fSymbols->fGmtHourFormats[DateFormatSymbols::GMT_NEGATIVE_HMS].compare(gDefGmtNegHmsPat, kNegHmsLen) != 0)
1183f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        || (fSymbols->fGmtHourFormats[DateFormatSymbols::GMT_NEGATIVE_HM].compare(gDefGmtNegHmPat, kNegHmLen) != 0)
1184f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        || (fSymbols->fGmtHourFormats[DateFormatSymbols::GMT_POSITIVE_HMS].compare(gDefGmtPosHmsPat, kPosHmsLen) != 0)
1185f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        || (fSymbols->fGmtHourFormats[DateFormatSymbols::GMT_POSITIVE_HM].compare(gDefGmtPosHmPat, kPosHmLen) != 0)) {
1186f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        return FALSE;
1187f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    }
1188f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    return TRUE;
1189f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)}
1190f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
1191f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)void
1192f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)SimpleDateFormat::formatRFC822TZ(UnicodeString &appendTo, int32_t offset) const {
1193f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    UChar sign = 0x002B /* '+' */;
1194f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    if (offset < 0) {
1195f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        offset = -offset;
1196f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        sign = 0x002D /* '-' */;
1197f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    }
1198f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    appendTo.append(sign);
1199f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
1200f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    int32_t offsetH = offset / U_MILLIS_PER_HOUR;
1201f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    offset = offset % U_MILLIS_PER_HOUR;
1202f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    int32_t offsetM = offset / U_MILLIS_PER_MINUTE;
1203f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    offset = offset % U_MILLIS_PER_MINUTE;
1204f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    int32_t offsetS = offset / U_MILLIS_PER_SECOND;
1205f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
1206f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    int32_t num = 0, denom = 0;
1207f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    if (offsetS == 0) {
1208f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        offset = offsetH*100 + offsetM; // HHmm
1209f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        num = offset % 10000;
1210f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        denom = 1000;
1211f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    } else {
1212f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        offset = offsetH*10000 + offsetM*100 + offsetS; // HHmmss
1213f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        num = offset % 1000000;
1214f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        denom = 100000;
1215f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    }
1216f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    while (denom >= 1) {
1217f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        UChar digit = (UChar)0x0030 + (num / denom);
1218f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        appendTo.append(digit);
1219f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        num = num % denom;
1220f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        denom /= 10;
1221f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    }
1222f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)}
1223f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
1224f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)void
1225f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)SimpleDateFormat::initGMTFormatters(UErrorCode &status) {
1226f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    if (U_FAILURE(status)) {
1227f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        return;
1228f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    }
1229f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    umtx_lock(&LOCK);
1230f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    if (fGMTFormatters == NULL) {
1231f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        fGMTFormatters = (MessageFormat**)uprv_malloc(kNumGMTFormatters * sizeof(MessageFormat*));
1232f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        if (fGMTFormatters) {
1233f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)            for (int32_t i = 0; i < kNumGMTFormatters; i++) {
1234f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)                const UnicodeString *hourPattern = NULL; //initialized it to avoid warning
1235f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)                switch (i) {
1236f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)                    case kGMTNegativeHMS:
1237f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)                        hourPattern = &(fSymbols->fGmtHourFormats[DateFormatSymbols::GMT_NEGATIVE_HMS]);
1238f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)                        break;
1239f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)                    case kGMTNegativeHM:
1240f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)                        hourPattern = &(fSymbols->fGmtHourFormats[DateFormatSymbols::GMT_NEGATIVE_HM]);
1241f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)                        break;
1242f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)                    case kGMTPositiveHMS:
1243f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)                        hourPattern = &(fSymbols->fGmtHourFormats[DateFormatSymbols::GMT_POSITIVE_HMS]);
1244f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)                        break;
1245f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)                    case kGMTPositiveHM:
1246f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)                        hourPattern = &(fSymbols->fGmtHourFormats[DateFormatSymbols::GMT_POSITIVE_HM]);
1247f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)                        break;
1248f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)                }
1249f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)                fGMTFormatters[i] = new MessageFormat(fSymbols->fGmtFormat, status);
1250f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)                GregorianCalendar *gcal = new GregorianCalendar(TimeZone::createTimeZone(UnicodeString(gEtcUTC)), status);
1251f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)                if (U_FAILURE(status)) {
1252f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)                    break;
1253f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)                }
1254f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)                SimpleDateFormat *sdf = (SimpleDateFormat*)this->clone();
1255f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)                sdf->adoptCalendar(gcal);
1256f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)                sdf->applyPattern(*hourPattern);
1257f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)                fGMTFormatters[i]->adoptFormat(0, sdf);
1258f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
1259f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)                // For parsing, we only allow Hms patterns to be equal or longer
1260f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)                // than its length with fixed minutes/seconds digits.
1261f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)                // See #6880
1262f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)                if (i == kGMTNegativeHMS || i == kGMTPositiveHMS) {
1263f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)                    UnicodeString tmp;
1264f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)                    Formattable tmpParam(60*60*1000, Formattable::kIsDate);
1265f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)                    FieldPosition fpos(0);
1266f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)                    fGMTFormatters[i]->format(&tmpParam, 1, tmp, fpos, status);
1267f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)                    if (U_FAILURE(status)) {
1268f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)                        break;
1269f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)                    }
1270f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)                    if (i == kGMTNegativeHMS) {
1271f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)                        fGMTFormatHmsMinLen[kGMTNegativeHMSMinLenIdx] = tmp.length();
1272f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)                    } else {
1273f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)                        fGMTFormatHmsMinLen[kGMTPositiveHMSMinLenIdx] = tmp.length();
1274f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)                    }
1275f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)                }
1276f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)            }
1277f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        } else {
1278f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)            status = U_MEMORY_ALLOCATION_ERROR;
1279f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        }
1280f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    }
1281f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    umtx_unlock(&LOCK);
1282f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)}
1283f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
1284f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)void
1285f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)SimpleDateFormat::initNumberFormatters(const Locale &locale,UErrorCode &status) {
1286f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    if (U_FAILURE(status)) {
1287f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        return;
1288f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    }
1289f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    if ( fDateOverride.isBogus() && fTimeOverride.isBogus() ) {
1290f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        return;
1291f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    }
1292f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    umtx_lock(&LOCK);
1293f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    if (fNumberFormatters == NULL) {
1294f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        fNumberFormatters = (NumberFormat**)uprv_malloc(UDAT_FIELD_COUNT * sizeof(NumberFormat*));
1295f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        if (fNumberFormatters) {
1296f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)            for (int32_t i = 0; i < UDAT_FIELD_COUNT; i++) {
1297f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)                fNumberFormatters[i] = fNumberFormat;
1298f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)            }
1299f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        } else {
1300f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)            status = U_MEMORY_ALLOCATION_ERROR;
1301f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        }
1302f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    }
1303f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    umtx_unlock(&LOCK);
1304f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
1305f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    processOverrideString(locale,fDateOverride,kOvrStrDate,status);
1306f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    processOverrideString(locale,fTimeOverride,kOvrStrTime,status);
1307f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
1308f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)}
1309f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
1310f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)void
1311f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)SimpleDateFormat::processOverrideString(const Locale &locale, const UnicodeString &str, int8_t type, UErrorCode &status) {
1312f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    if (str.isBogus()) {
1313f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        return;
1314f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    }
1315f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    int32_t start = 0;
1316f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    int32_t len;
1317f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    UnicodeString nsName;
1318f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    UnicodeString ovrField;
1319f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    UBool moreToProcess = TRUE;
1320f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
1321f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    while (moreToProcess) {
1322f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        int32_t delimiterPosition = str.indexOf(ULOC_KEYWORD_ITEM_SEPARATOR_UNICODE,start);
1323f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        if (delimiterPosition == -1) {
1324f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)            moreToProcess = FALSE;
1325f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)            len = str.length() - start;
1326f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        } else {
1327f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)            len = delimiterPosition - start;
1328f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        }
1329f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        UnicodeString currentString(str,start,len);
1330f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        int32_t equalSignPosition = currentString.indexOf(ULOC_KEYWORD_ASSIGN_UNICODE,0);
1331f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        if (equalSignPosition == -1) { // Simple override string such as "hebrew"
1332f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)            nsName.setTo(currentString);
1333f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)            ovrField.setToBogus();
1334f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        } else { // Field specific override string such as "y=hebrew"
1335f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)            nsName.setTo(currentString,equalSignPosition+1);
1336f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)            ovrField.setTo(currentString,0,1); // We just need the first character.
1337f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        }
1338f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
1339f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        int32_t nsNameHash = nsName.hashCode();
1340f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        // See if the numbering system is in the override list, if not, then add it.
1341f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        NSOverride *cur = fOverrideList;
1342f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        NumberFormat *nf = NULL;
1343f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        UBool found = FALSE;
1344f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        while ( cur && !found ) {
1345f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)            if ( cur->hash == nsNameHash ) {
1346f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)                nf = cur->nf;
1347f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)                found = TRUE;
1348f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)            }
1349f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)            cur = cur->next;
1350f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        }
1351f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
1352f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        if (!found) {
1353f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)           cur = (NSOverride *)uprv_malloc(sizeof(NSOverride));
1354f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)           if (cur) {
1355f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)               char kw[ULOC_KEYWORD_AND_VALUES_CAPACITY];
1356f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)               uprv_strcpy(kw,"numbers=");
1357f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)               nsName.extract(0,len,kw+8,ULOC_KEYWORD_AND_VALUES_CAPACITY-8,US_INV);
1358f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
1359f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)               Locale ovrLoc(locale.getLanguage(),locale.getCountry(),locale.getVariant(),kw);
1360f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)               nf = NumberFormat::createInstance(ovrLoc,status);
1361f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
1362f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)               // no matter what the locale's default number format looked like, we want
1363f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)               // to modify it so that it doesn't use thousands separators, doesn't always
1364f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)               // show the decimal point, and recognizes integers only when parsing
1365f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
1366f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)               if (U_SUCCESS(status)) {
1367f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)                   nf->setGroupingUsed(FALSE);
1368f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)                   DecimalFormat* decfmt = dynamic_cast<DecimalFormat*>(nf);
1369f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)                   if (decfmt != NULL) {
1370f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)                       decfmt->setDecimalSeparatorAlwaysShown(FALSE);
1371f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)                   }
1372f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)                   nf->setParseIntegerOnly(TRUE);
1373f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)                   nf->setMinimumFractionDigits(0); // To prevent "Jan 1.00, 1997.00"
1374f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
1375f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)                   cur->nf = nf;
1376f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)                   cur->hash = nsNameHash;
1377f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)                   cur->next = fOverrideList;
1378f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)                   fOverrideList = cur;
1379f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)               }
1380f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)               else {
1381f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)                   // clean up before returning
1382f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)                   if (cur != NULL) {
1383f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)                       uprv_free(cur);
1384f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)                   }
1385f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)                  return;
1386f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)               }
1387f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
1388f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)           } else {
1389f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)               status = U_MEMORY_ALLOCATION_ERROR;
1390f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)               return;
1391f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)           }
1392f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        }
1393f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
1394f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        // Now that we have an appropriate number formatter, fill in the appropriate spaces in the
1395f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        // number formatters table.
1396f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
1397f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        if (ovrField.isBogus()) {
1398f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)            switch (type) {
1399f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)                case kOvrStrDate:
1400f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)                case kOvrStrBoth: {
1401f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)                    for ( int8_t i=0 ; i<kDateFieldsCount; i++ ) {
1402f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)                        fNumberFormatters[kDateFields[i]] = nf;
1403f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)                    }
1404f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)                    if (type==kOvrStrDate) {
1405f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)                        break;
1406f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)                    }
1407f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)                }
1408f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)                case kOvrStrTime : {
1409f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)                    for ( int8_t i=0 ; i<kTimeFieldsCount; i++ ) {
1410f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)                        fNumberFormatters[kTimeFields[i]] = nf;
1411f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)                    }
1412f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)                    break;
1413f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)                }
1414f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)            }
1415f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        } else {
1416f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)           UChar ch = ovrField.charAt(0);
1417f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)           UChar *patternCharPtr = u_strchr(DateFormatSymbols::getPatternUChars(), ch);
1418f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)           UDateFormatField patternCharIndex;
1419f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
1420f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)           // if the pattern character is unrecognized, signal an error and bail out
1421f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)           if (patternCharPtr == NULL) {
1422f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)               status = U_INVALID_FORMAT_ERROR;
1423f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)               return;
1424f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)           }
1425f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)           patternCharIndex = (UDateFormatField)(patternCharPtr - DateFormatSymbols::getPatternUChars());
1426f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
1427f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)           // Set the number formatter in the table
1428f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)           fNumberFormatters[patternCharIndex] = nf;
1429f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        }
1430f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
1431f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        start = delimiterPosition + 1;
1432f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    }
1433f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)}
1434f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)//---------------------------------------------------------------------
1435f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)void
1436f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)SimpleDateFormat::subFormat(UnicodeString &appendTo,
1437f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)                            UChar ch,
1438f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)                            int32_t count,
1439f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)                            FieldPositionHandler& handler,
1440f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)                            Calendar& cal,
1441f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)                            UErrorCode& status) const
1442f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles){
1443f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    if (U_FAILURE(status)) {
1444f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        return;
1445f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    }
1446f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
1447f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    // this function gets called by format() to produce the appropriate substitution
1448f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    // text for an individual pattern symbol (e.g., "HH" or "yyyy")
1449f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
1450f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    UChar *patternCharPtr = u_strchr(DateFormatSymbols::getPatternUChars(), ch);
1451f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    UDateFormatField patternCharIndex;
1452f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    const int32_t maxIntCount = 10;
1453f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    int32_t beginOffset = appendTo.length();
1454f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    NumberFormat *currentNumberFormat;
1455f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
1456f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    UBool isHebrewCalendar = !strcmp(cal.getType(),"hebrew");
1457f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
1458f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    // if the pattern character is unrecognized, signal an error and dump out
1459f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    if (patternCharPtr == NULL)
1460f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    {
1461f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        status = U_INVALID_FORMAT_ERROR;
1462f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        return;
1463f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    }
1464f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
1465f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    patternCharIndex = (UDateFormatField)(patternCharPtr - DateFormatSymbols::getPatternUChars());
1466f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    UCalendarDateFields field = fgPatternIndexToCalendarField[patternCharIndex];
1467f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    int32_t value = cal.get(field, status);
1468f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    if (U_FAILURE(status)) {
1469f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        return;
1470f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    }
1471f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
1472f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    currentNumberFormat = getNumberFormatByIndex(patternCharIndex);
1473f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    switch (patternCharIndex) {
1474f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
1475f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    // for any "G" symbol, write out the appropriate era string
1476f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    // "GGGG" is wide era name, "GGGGG" is narrow era name, anything else is abbreviated name
1477f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    case UDAT_ERA_FIELD:
1478f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        if (count == 5)
1479f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)           _appendSymbol(appendTo, value, fSymbols->fNarrowEras, fSymbols->fNarrowErasCount);
1480f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        else if (count == 4)
1481f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)           _appendSymbol(appendTo, value, fSymbols->fEraNames, fSymbols->fEraNamesCount);
1482f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        else
1483f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)           _appendSymbol(appendTo, value, fSymbols->fEras, fSymbols->fErasCount);
1484f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        break;
1485f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
1486f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    // OLD: for "yyyy", write out the whole year; for "yy", write out the last 2 digits
1487f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    // NEW: UTS#35:
1488f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)//Year  	y  	yy  	yyy  	yyyy  	yyyyy
1489f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)//AD 1 	1 	01 	001 	0001 	00001
1490f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)//AD 12 	12 	12 	012 	0012 	00012
1491f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)//AD 123 	123 	23 	123 	0123 	00123
1492f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)//AD 1234 	1234 	34 	1234 	1234 	01234
1493f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)//AD 12345 	12345 	45 	12345 	12345 	12345
1494f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    case UDAT_YEAR_FIELD:
1495f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    case UDAT_YEAR_WOY_FIELD:
1496f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        if(count == 2)
1497f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)            zeroPaddingNumber(currentNumberFormat, appendTo, value, 2, 2);
1498f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        else
1499f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)            zeroPaddingNumber(currentNumberFormat, appendTo, value, count, maxIntCount);
1500f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        break;
1501f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
1502f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    // for "MMMM", write out the whole month name, for "MMM", write out the month
1503f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    // abbreviation, for "M" or "MM", write out the month as a number with the
1504f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    // appropriate number of digits
1505f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    // for "MMMMM", use the narrow form
1506f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    case UDAT_MONTH_FIELD:
1507f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        if ( isHebrewCalendar ) {
1508f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)           HebrewCalendar *hc = (HebrewCalendar*)&cal;
1509f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)           if (hc->isLeapYear(hc->get(UCAL_YEAR,status)) && value == 6 && count >= 3 )
1510f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)               value = 13; // Show alternate form for Adar II in leap years in Hebrew calendar.
1511f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)           if (!hc->isLeapYear(hc->get(UCAL_YEAR,status)) && value >= 6 && count < 3 )
1512f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)               value--; // Adjust the month number down 1 in Hebrew non-leap years, i.e. Adar is 6, not 7.
1513f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        }
1514f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        if (count == 5)
1515f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)            _appendSymbol(appendTo, value, fSymbols->fNarrowMonths,
1516f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)                          fSymbols->fNarrowMonthsCount);
1517f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        else if (count == 4)
1518f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)            _appendSymbol(appendTo, value, fSymbols->fMonths,
1519f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)                          fSymbols->fMonthsCount);
1520f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        else if (count == 3)
1521f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)            _appendSymbol(appendTo, value, fSymbols->fShortMonths,
1522f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)                          fSymbols->fShortMonthsCount);
1523f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        else
1524f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)            zeroPaddingNumber(currentNumberFormat,appendTo, value + 1, count, maxIntCount);
1525f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        break;
1526f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
1527f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    // for "LLLL", write out the whole month name, for "LLL", write out the month
1528f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    // abbreviation, for "L" or "LL", write out the month as a number with the
1529f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    // appropriate number of digits
1530f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    // for "LLLLL", use the narrow form
1531f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    case UDAT_STANDALONE_MONTH_FIELD:
1532f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        if (count == 5)
1533f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)            _appendSymbol(appendTo, value, fSymbols->fStandaloneNarrowMonths,
1534f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)                          fSymbols->fStandaloneNarrowMonthsCount);
1535f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        else if (count == 4)
1536f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)            _appendSymbol(appendTo, value, fSymbols->fStandaloneMonths,
1537f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)                          fSymbols->fStandaloneMonthsCount);
1538f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        else if (count == 3)
1539f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)            _appendSymbol(appendTo, value, fSymbols->fStandaloneShortMonths,
1540f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)                          fSymbols->fStandaloneShortMonthsCount);
1541f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        else
1542f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)            zeroPaddingNumber(currentNumberFormat,appendTo, value + 1, count, maxIntCount);
1543f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        break;
1544f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
1545f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    // for "k" and "kk", write out the hour, adjusting midnight to appear as "24"
1546f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    case UDAT_HOUR_OF_DAY1_FIELD:
1547f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        if (value == 0)
1548f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)            zeroPaddingNumber(currentNumberFormat,appendTo, cal.getMaximum(UCAL_HOUR_OF_DAY) + 1, count, maxIntCount);
1549f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        else
1550f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)            zeroPaddingNumber(currentNumberFormat,appendTo, value, count, maxIntCount);
1551f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        break;
1552f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
1553f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    case UDAT_FRACTIONAL_SECOND_FIELD:
1554f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        // Fractional seconds left-justify
1555f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        {
1556f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)            currentNumberFormat->setMinimumIntegerDigits((count > 3) ? 3 : count);
1557f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)            currentNumberFormat->setMaximumIntegerDigits(maxIntCount);
1558f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)            if (count == 1) {
1559f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)                value /= 100;
1560f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)            } else if (count == 2) {
1561f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)                value /= 10;
1562f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)            }
1563f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)            FieldPosition p(0);
1564f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)            currentNumberFormat->format(value, appendTo, p);
1565f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)            if (count > 3) {
1566f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)                currentNumberFormat->setMinimumIntegerDigits(count - 3);
1567f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)                currentNumberFormat->format((int32_t)0, appendTo, p);
1568f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)            }
1569f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        }
1570f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        break;
1571f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
1572f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    // for "ee" or "e", use local numeric day-of-the-week
1573f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    // for "EEEEE" or "eeeee", write out the narrow day-of-the-week name
1574f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    // for "EEEE" or "eeee", write out the wide day-of-the-week name
1575f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    // for "EEE" or "EE" or "E" or "eee", write out the abbreviated day-of-the-week name
1576f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    case UDAT_DOW_LOCAL_FIELD:
1577f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        if ( count < 3 ) {
1578f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)            zeroPaddingNumber(currentNumberFormat,appendTo, value, count, maxIntCount);
1579f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)            break;
1580f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        }
1581f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        // fall through to EEEEE-EEE handling, but for that we don't want local day-of-week,
1582f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        // we want standard day-of-week, so first fix value to work for EEEEE-EEE.
1583f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        value = cal.get(UCAL_DAY_OF_WEEK, status);
1584f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        if (U_FAILURE(status)) {
1585f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)            return;
1586f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        }
1587f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        // fall through, do not break here
1588f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    case UDAT_DAY_OF_WEEK_FIELD:
1589f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        if (count == 5)
1590f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)            _appendSymbol(appendTo, value, fSymbols->fNarrowWeekdays,
1591f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)                          fSymbols->fNarrowWeekdaysCount);
1592f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        else if (count == 4)
1593f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)            _appendSymbol(appendTo, value, fSymbols->fWeekdays,
1594f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)                          fSymbols->fWeekdaysCount);
1595f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        else
1596f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)            _appendSymbol(appendTo, value, fSymbols->fShortWeekdays,
1597f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)                          fSymbols->fShortWeekdaysCount);
1598f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        break;
1599f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
1600f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    // for "ccc", write out the abbreviated day-of-the-week name
1601f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    // for "cccc", write out the wide day-of-the-week name
1602f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    // for "ccccc", use the narrow day-of-the-week name
1603f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    case UDAT_STANDALONE_DAY_FIELD:
1604f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        if ( count < 3 ) {
1605f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)            zeroPaddingNumber(currentNumberFormat,appendTo, value, 1, maxIntCount);
1606f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)            break;
1607f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        }
1608f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        // fall through to alpha DOW handling, but for that we don't want local day-of-week,
1609f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        // we want standard day-of-week, so first fix value.
1610f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        value = cal.get(UCAL_DAY_OF_WEEK, status);
1611f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        if (U_FAILURE(status)) {
1612f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)            return;
1613f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        }
1614f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        if (count == 5)
1615f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)            _appendSymbol(appendTo, value, fSymbols->fStandaloneNarrowWeekdays,
1616f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)                          fSymbols->fStandaloneNarrowWeekdaysCount);
1617f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        else if (count == 4)
1618f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)            _appendSymbol(appendTo, value, fSymbols->fStandaloneWeekdays,
1619f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)                          fSymbols->fStandaloneWeekdaysCount);
1620f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        else // count == 3
1621f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)            _appendSymbol(appendTo, value, fSymbols->fStandaloneShortWeekdays,
1622f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)                          fSymbols->fStandaloneShortWeekdaysCount);
1623f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        break;
1624f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
1625f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    // for and "a" symbol, write out the whole AM/PM string
1626f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    case UDAT_AM_PM_FIELD:
1627f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        _appendSymbol(appendTo, value, fSymbols->fAmPms,
1628f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)                      fSymbols->fAmPmsCount);
1629f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        break;
1630f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
1631f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    // for "h" and "hh", write out the hour, adjusting noon and midnight to show up
1632f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    // as "12"
1633f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    case UDAT_HOUR1_FIELD:
1634f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        if (value == 0)
1635f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)            zeroPaddingNumber(currentNumberFormat,appendTo, cal.getLeastMaximum(UCAL_HOUR) + 1, count, maxIntCount);
1636f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        else
1637f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)            zeroPaddingNumber(currentNumberFormat,appendTo, value, count, maxIntCount);
1638f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        break;
1639f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
1640f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    // for the "z" symbols, we have to check our time zone data first.  If we have a
1641f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    // localized name for the time zone, then "zzzz" / "zzz" indicate whether
1642f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    // daylight time is in effect (long/short) and "zz" / "z" do not (long/short).
1643f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    // If we don't have a localized time zone name,
1644f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    // then the time zone shows up as "GMT+hh:mm" or "GMT-hh:mm" (where "hh:mm" is the
1645f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    // offset from GMT) regardless of how many z's were in the pattern symbol
1646f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    case UDAT_TIMEZONE_FIELD:
1647f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    case UDAT_TIMEZONE_GENERIC_FIELD:
1648f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    case UDAT_TIMEZONE_SPECIAL_FIELD:
1649f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        {
1650f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)            UnicodeString zoneString;
1651f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)            const ZoneStringFormat *zsf = fSymbols->getZoneStringFormat();
1652f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)            if (zsf) {
1653f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)                if (patternCharIndex == UDAT_TIMEZONE_FIELD) {
1654f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)                    if (count < 4) {
1655f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)                        // "z", "zz", "zzz"
1656f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)                        zsf->getSpecificShortString(cal, TRUE /*commonly used only*/,
1657f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)                            zoneString, status);
1658f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)                    } else {
1659f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)                        // "zzzz"
1660f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)                        zsf->getSpecificLongString(cal, zoneString, status);
1661f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)                    }
1662f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)                } else if (patternCharIndex == UDAT_TIMEZONE_GENERIC_FIELD) {
1663f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)                    if (count == 1) {
1664f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)                        // "v"
1665f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)                        zsf->getGenericShortString(cal, TRUE /*commonly used only*/,
1666f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)                            zoneString, status);
1667f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)                    } else if (count == 4) {
1668f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)                        // "vvvv"
1669f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)                        zsf->getGenericLongString(cal, zoneString, status);
1670f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)                    }
1671f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)                } else { // patternCharIndex == UDAT_TIMEZONE_SPECIAL_FIELD
1672f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)                    if (count == 1) {
1673f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)                        // "V"
1674f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)                        zsf->getSpecificShortString(cal, FALSE /*ignore commonly used*/,
1675f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)                            zoneString, status);
1676f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)                    } else if (count == 4) {
1677f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)                        // "VVVV"
1678f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)                        zsf->getGenericLocationString(cal, zoneString, status);
1679f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)                    }
1680f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)                }
1681f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)            }
1682f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)            if (zoneString.isEmpty()) {
1683f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)                appendGMT(currentNumberFormat,appendTo, cal, status);
1684f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)            } else {
1685f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)                appendTo += zoneString;
1686f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)            }
1687f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        }
1688f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        break;
1689f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
1690f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    case UDAT_TIMEZONE_RFC_FIELD: // 'Z' - TIMEZONE_RFC
1691f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        if (count < 4) {
1692f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)            // RFC822 format, must use ASCII digits
1693f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)            value = (cal.get(UCAL_ZONE_OFFSET, status) + cal.get(UCAL_DST_OFFSET, status));
1694f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)            formatRFC822TZ(appendTo, value);
1695f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        } else {
1696f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)            // long form, localized GMT pattern
1697f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)            appendGMT(currentNumberFormat,appendTo, cal, status);
1698f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        }
1699f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        break;
1700f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
1701f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    case UDAT_QUARTER_FIELD:
1702f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        if (count >= 4)
1703f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)            _appendSymbol(appendTo, value/3, fSymbols->fQuarters,
1704f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)                          fSymbols->fQuartersCount);
1705f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        else if (count == 3)
1706f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)            _appendSymbol(appendTo, value/3, fSymbols->fShortQuarters,
1707f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)                          fSymbols->fShortQuartersCount);
1708f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        else
1709f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)            zeroPaddingNumber(currentNumberFormat,appendTo, (value/3) + 1, count, maxIntCount);
1710f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        break;
1711f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
1712f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    case UDAT_STANDALONE_QUARTER_FIELD:
1713f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        if (count >= 4)
1714f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)            _appendSymbol(appendTo, value/3, fSymbols->fStandaloneQuarters,
1715f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)                          fSymbols->fStandaloneQuartersCount);
1716f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        else if (count == 3)
1717f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)            _appendSymbol(appendTo, value/3, fSymbols->fStandaloneShortQuarters,
1718f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)                          fSymbols->fStandaloneShortQuartersCount);
1719f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        else
1720f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)            zeroPaddingNumber(currentNumberFormat,appendTo, (value/3) + 1, count, maxIntCount);
1721f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        break;
1722f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
1723f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
1724f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    // all of the other pattern symbols can be formatted as simple numbers with
1725f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    // appropriate zero padding
1726f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    default:
1727f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        zeroPaddingNumber(currentNumberFormat,appendTo, value, count, maxIntCount);
1728f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        break;
1729f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    }
1730f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
1731f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    handler.addAttribute(fgPatternIndexToDateFormatField[patternCharIndex], beginOffset, appendTo.length());
1732f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)}
1733f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
1734f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)//----------------------------------------------------------------------
1735f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
1736f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)NumberFormat *
1737f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)SimpleDateFormat::getNumberFormatByIndex(UDateFormatField index) const {
1738f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    if (fNumberFormatters != NULL) {
1739f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        return fNumberFormatters[index];
1740f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    } else {
1741f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        return fNumberFormat;
1742f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    }
1743f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)}
1744f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
1745f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)//----------------------------------------------------------------------
1746f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)void
1747f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)SimpleDateFormat::zeroPaddingNumber(NumberFormat *currentNumberFormat,UnicodeString &appendTo,
1748f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)                                    int32_t value, int32_t minDigits, int32_t maxDigits) const
1749f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles){
1750f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    if (currentNumberFormat!=NULL) {
1751f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        FieldPosition pos(0);
1752f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
1753f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        currentNumberFormat->setMinimumIntegerDigits(minDigits);
1754f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        currentNumberFormat->setMaximumIntegerDigits(maxDigits);
1755f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        currentNumberFormat->format(value, appendTo, pos);  // 3rd arg is there to speed up processing
1756f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    }
1757f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)}
1758f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
1759f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)//----------------------------------------------------------------------
1760f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
1761f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)/**
1762f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) * Format characters that indicate numeric fields.  The character
1763f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) * at index 0 is treated specially.
1764f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) */
1765f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)static const UChar NUMERIC_FORMAT_CHARS[] = {0x4D, 0x59, 0x79, 0x75, 0x64, 0x65, 0x68, 0x48, 0x6D, 0x73, 0x53, 0x44, 0x46, 0x77, 0x57, 0x6B, 0x4B, 0x00}; /* "MYyudehHmsSDFwWkK" */
1766f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
1767f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)/**
1768f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) * Return true if the given format character, occuring count
1769f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) * times, represents a numeric field.
1770f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) */
1771f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)UBool SimpleDateFormat::isNumeric(UChar formatChar, int32_t count) {
1772f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    UnicodeString s(NUMERIC_FORMAT_CHARS);
1773f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    int32_t i = s.indexOf(formatChar);
1774f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    return (i > 0 || (i == 0 && count < 3));
1775f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)}
1776f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
1777f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)void
1778f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)SimpleDateFormat::parse(const UnicodeString& text, Calendar& cal, ParsePosition& parsePos) const
1779f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles){
1780f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    UErrorCode status = U_ZERO_ERROR;
1781f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    int32_t pos = parsePos.getIndex();
1782f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    int32_t start = pos;
1783f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
1784f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    UBool ambiguousYear[] = { FALSE };
1785f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    int32_t saveHebrewMonth = -1;
1786f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    int32_t count = 0;
1787f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
1788f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    // hack, reset tztype, cast away const
1789f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    ((SimpleDateFormat*)this)->tztype = TZTYPE_UNK;
1790f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
1791f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    // For parsing abutting numeric fields. 'abutPat' is the
1792f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    // offset into 'pattern' of the first of 2 or more abutting
1793f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    // numeric fields.  'abutStart' is the offset into 'text'
1794f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    // where parsing the fields begins. 'abutPass' starts off as 0
1795f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    // and increments each time we try to parse the fields.
1796f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    int32_t abutPat = -1; // If >=0, we are in a run of abutting numeric fields
1797f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    int32_t abutStart = 0;
1798f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    int32_t abutPass = 0;
1799f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    UBool inQuote = FALSE;
1800f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
1801f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    const UnicodeString numericFormatChars(NUMERIC_FORMAT_CHARS);
1802f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
1803f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    TimeZone *backupTZ = NULL;
1804f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    Calendar *workCal = &cal;
1805f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    if (&cal != fCalendar && uprv_strcmp(cal.getType(), fCalendar->getType()) != 0) {
1806f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        // Different calendar type
1807f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        // We use the time/zone from the input calendar, but
1808f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        // do not use the input calendar for field calculation.
1809f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        fCalendar->setTime(cal.getTime(status),status);
1810f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        if (U_FAILURE(status)) {
1811f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)            goto ExitParse;
1812f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        }
1813f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        backupTZ = fCalendar->getTimeZone().clone();
1814f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        fCalendar->setTimeZone(cal.getTimeZone());
1815f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        workCal = fCalendar;
1816f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    }
1817f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
1818f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    for (int32_t i=0; i<fPattern.length(); ++i) {
1819f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        UChar ch = fPattern.charAt(i);
1820f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
1821f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        // Handle alphabetic field characters.
1822f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        if (!inQuote && ((ch >= 0x41 && ch <= 0x5A) || (ch >= 0x61 && ch <= 0x7A))) { // [A-Za-z]
1823f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)            int32_t fieldPat = i;
1824f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
1825f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)            // Count the length of this field specifier
1826f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)            count = 1;
1827f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)            while ((i+1)<fPattern.length() &&
1828f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)                   fPattern.charAt(i+1) == ch) {
1829f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)                ++count;
1830f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)                ++i;
1831f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)            }
1832f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
1833f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)            if (isNumeric(ch, count)) {
1834f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)                if (abutPat < 0) {
1835f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)                    // Determine if there is an abutting numeric field.  For
1836f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)                    // most fields we can just look at the next characters,
1837f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)                    // but the 'm' field is either numeric or text,
1838f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)                    // depending on the count, so we have to look ahead for
1839f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)                    // that field.
1840f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)                    if ((i+1)<fPattern.length()) {
1841f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)                        UBool abutting;
1842f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)                        UChar nextCh = fPattern.charAt(i+1);
1843f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)                        int32_t k = numericFormatChars.indexOf(nextCh);
1844f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)                        if (k == 0) {
1845f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)                            int32_t j = i+2;
1846f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)                            while (j<fPattern.length() &&
1847f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)                                   fPattern.charAt(j) == nextCh) {
1848f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)                                ++j;
1849f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)                            }
1850f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)                            abutting = (j-i) < 4; // nextCount < 3
1851f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)                        } else {
1852f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)                            abutting = k > 0;
1853f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)                        }
1854f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
1855f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)                        // Record the start of a set of abutting numeric
1856f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)                        // fields.
1857f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)                        if (abutting) {
1858f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)                            abutPat = fieldPat;
1859f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)                            abutStart = pos;
1860f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)                            abutPass = 0;
1861f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)                        }
1862f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)                    }
1863f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)                }
1864f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)            } else {
1865f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)                abutPat = -1; // End of any abutting fields
1866f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)            }
1867f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
1868f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)            // Handle fields within a run of abutting numeric fields.  Take
1869f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)            // the pattern "HHmmss" as an example. We will try to parse
1870f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)            // 2/2/2 characters of the input text, then if that fails,
1871f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)            // 1/2/2.  We only adjust the width of the leftmost field; the
1872f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)            // others remain fixed.  This allows "123456" => 12:34:56, but
1873f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)            // "12345" => 1:23:45.  Likewise, for the pattern "yyyyMMdd" we
1874f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)            // try 4/2/2, 3/2/2, 2/2/2, and finally 1/2/2.
1875f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)            if (abutPat >= 0) {
1876f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)                // If we are at the start of a run of abutting fields, then
1877f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)                // shorten this field in each pass.  If we can't shorten
1878f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)                // this field any more, then the parse of this set of
1879f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)                // abutting numeric fields has failed.
1880f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)                if (fieldPat == abutPat) {
1881f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)                    count -= abutPass++;
1882f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)                    if (count == 0) {
1883f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)                        status = U_PARSE_ERROR;
1884f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)                        goto ExitParse;
1885f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)                    }
1886f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)                }
1887f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
1888f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)                pos = subParse(text, pos, ch, count,
1889f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)                               TRUE, FALSE, ambiguousYear, saveHebrewMonth, *workCal, i);
1890f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
1891f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)                // If the parse fails anywhere in the run, back up to the
1892f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)                // start of the run and retry.
1893f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)                if (pos < 0) {
1894f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)                    i = abutPat - 1;
1895f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)                    pos = abutStart;
1896f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)                    continue;
1897f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)                }
1898f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)            }
1899f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
1900f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)            // Handle non-numeric fields and non-abutting numeric
1901f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)            // fields.
1902f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)            else {
1903f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)                int32_t s = subParse(text, pos, ch, count,
1904f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)                               FALSE, TRUE, ambiguousYear, saveHebrewMonth, *workCal, i);
1905f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
1906f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)                if (s == -pos-1) {
1907f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)                    // era not present, in special cases allow this to continue
1908f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)                    s++;
1909f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
1910f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)                    if (i+1 < fPattern.length()) {
1911f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)                        // move to next pattern character
1912f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)                        UChar ch = fPattern.charAt(i+1);
1913f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
1914f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)                        // check for whitespace
1915f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)                        if (uprv_isRuleWhiteSpace(ch)) {
1916f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)                            i++;
1917f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)                            // Advance over run in pattern
1918f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)                            while ((i+1)<fPattern.length() &&
1919f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)                                   uprv_isRuleWhiteSpace(fPattern.charAt(i+1))) {
1920f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)                                ++i;
1921f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)                            }
1922f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)                        }
1923f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)                    }
1924f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)                }
1925f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)                else if (s < 0) {
1926f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)                    status = U_PARSE_ERROR;
1927f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)                    goto ExitParse;
1928f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)                }
1929f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)                pos = s;
1930f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)            }
1931f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        }
1932f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
1933f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        // Handle literal pattern characters.  These are any
1934f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        // quoted characters and non-alphabetic unquoted
1935f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        // characters.
1936f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        else {
1937f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
1938f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)            abutPat = -1; // End of any abutting fields
1939f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
1940f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)            // Handle quotes.  Two consecutive quotes is a quote
1941f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)            // literal, inside or outside of quotes.  Otherwise a
1942f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)            // quote indicates entry or exit from a quoted region.
1943f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)            if (ch == QUOTE) {
1944f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)                // Match a quote literal '' within OR outside of quotes
1945f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)                if ((i+1)<fPattern.length() && fPattern.charAt(i+1)==ch) {
1946f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)                    ++i; // Skip over doubled quote
1947f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)                    // Fall through and treat quote as a literal
1948f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)                } else {
1949f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)                    // Enter or exit quoted region
1950f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)                    inQuote = !inQuote;
1951f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)                    continue;
1952f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)                }
1953f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)            }
1954f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
1955f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)            // A run of white space in the pattern matches a run
1956f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)            // of white space in the input text.
1957f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)            if (uprv_isRuleWhiteSpace(ch)) {
1958f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)                // Advance over run in pattern
1959f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)                while ((i+1)<fPattern.length() &&
1960f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)                       uprv_isRuleWhiteSpace(fPattern.charAt(i+1))) {
1961f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)                    ++i;
1962f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)                }
1963f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
1964f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)                // Advance over run in input text
1965f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)                int32_t s = pos;
1966f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)                while (pos<text.length() &&
1967f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)                       ( u_isUWhiteSpace(text.charAt(pos)) || uprv_isRuleWhiteSpace(text.charAt(pos)))) {
1968f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)                    ++pos;
1969f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)                }
1970f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
1971f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)                // Must see at least one white space char in input
1972f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)                if (pos > s) {
1973f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)                    continue;
1974f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)                }
1975f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
1976f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
1977f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)            } else if (pos<text.length() && text.charAt(pos)==ch) {
1978f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)                // Match a literal
1979f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)                ++pos;
1980f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)                continue;
1981f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)            }
1982f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
1983f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)            // We fall through to this point if the match fails
1984f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)            status = U_PARSE_ERROR;
1985f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)            goto ExitParse;
1986f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        }
1987f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    }
1988f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
1989f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    // At this point the fields of Calendar have been set.  Calendar
1990f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    // will fill in default values for missing fields when the time
1991f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    // is computed.
1992f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
1993f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    parsePos.setIndex(pos);
1994f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
1995f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    // This part is a problem:  When we call parsedDate.after, we compute the time.
1996f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    // Take the date April 3 2004 at 2:30 am.  When this is first set up, the year
1997f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    // will be wrong if we're parsing a 2-digit year pattern.  It will be 1904.
1998f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    // April 3 1904 is a Sunday (unlike 2004) so it is the DST onset day.  2:30 am
1999f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    // is therefore an "impossible" time, since the time goes from 1:59 to 3:00 am
2000f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    // on that day.  It is therefore parsed out to fields as 3:30 am.  Then we
2001f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    // add 100 years, and get April 3 2004 at 3:30 am.  Note that April 3 2004 is
2002f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    // a Saturday, so it can have a 2:30 am -- and it should. [LIU]
2003f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    /*
2004f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        UDate parsedDate = calendar.getTime();
2005f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        if( ambiguousYear[0] && !parsedDate.after(fDefaultCenturyStart) ) {
2006f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)            calendar.add(Calendar.YEAR, 100);
2007f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)            parsedDate = calendar.getTime();
2008f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        }
2009f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    */
2010f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    // Because of the above condition, save off the fields in case we need to readjust.
2011f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    // The procedure we use here is not particularly efficient, but there is no other
2012f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    // way to do this given the API restrictions present in Calendar.  We minimize
2013f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    // inefficiency by only performing this computation when it might apply, that is,
2014f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    // when the two-digit year is equal to the start year, and thus might fall at the
2015f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    // front or the back of the default century.  This only works because we adjust
2016f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    // the year correctly to start with in other cases -- see subParse().
2017f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    if (ambiguousYear[0] || tztype != TZTYPE_UNK) // If this is true then the two-digit year == the default start year
2018f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    {
2019f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        // We need a copy of the fields, and we need to avoid triggering a call to
2020f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        // complete(), which will recalculate the fields.  Since we can't access
2021f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        // the fields[] array in Calendar, we clone the entire object.  This will
2022f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        // stop working if Calendar.clone() is ever rewritten to call complete().
2023f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        Calendar *copy;
2024f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        if (ambiguousYear[0]) {
2025f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)            copy = cal.clone();
2026f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)            // Check for failed cloning.
2027f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)            if (copy == NULL) {
2028f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)            	status = U_MEMORY_ALLOCATION_ERROR;
2029f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)            	goto ExitParse;
2030f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)            }
2031f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)            UDate parsedDate = copy->getTime(status);
2032f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)            // {sfb} check internalGetDefaultCenturyStart
2033f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)            if (fHaveDefaultCentury && (parsedDate < fDefaultCenturyStart)) {
2034f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)                // We can't use add here because that does a complete() first.
2035f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)                cal.set(UCAL_YEAR, fDefaultCenturyStartYear + 100);
2036f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)            }
2037f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)            delete copy;
2038f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        }
2039f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
2040f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        if (tztype != TZTYPE_UNK) {
2041f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)            copy = cal.clone();
2042f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)            // Check for failed cloning.
2043f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)            if (copy == NULL) {
2044f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)            	status = U_MEMORY_ALLOCATION_ERROR;
2045f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)            	goto ExitParse;
2046f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)            }
2047f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)            const TimeZone & tz = cal.getTimeZone();
2048f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)            BasicTimeZone *btz = NULL;
2049f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
2050f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)            if (dynamic_cast<const OlsonTimeZone *>(&tz) != NULL
2051f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)                || dynamic_cast<const SimpleTimeZone *>(&tz) != NULL
2052f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)                || dynamic_cast<const RuleBasedTimeZone *>(&tz) != NULL
2053f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)                || dynamic_cast<const VTimeZone *>(&tz) != NULL) {
2054f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)                btz = (BasicTimeZone*)&tz;
2055f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)            }
2056f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
2057f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)            // Get local millis
2058f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)            copy->set(UCAL_ZONE_OFFSET, 0);
2059f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)            copy->set(UCAL_DST_OFFSET, 0);
2060f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)            UDate localMillis = copy->getTime(status);
2061f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
2062f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)            // Make sure parsed time zone type (Standard or Daylight)
2063f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)            // matches the rule used by the parsed time zone.
2064f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)            int32_t raw, dst;
2065f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)            if (btz != NULL) {
2066f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)                if (tztype == TZTYPE_STD) {
2067f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)                    btz->getOffsetFromLocal(localMillis,
2068f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)                        BasicTimeZone::kStandard, BasicTimeZone::kStandard, raw, dst, status);
2069f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)                } else {
2070f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)                    btz->getOffsetFromLocal(localMillis,
2071f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)                        BasicTimeZone::kDaylight, BasicTimeZone::kDaylight, raw, dst, status);
2072f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)                }
2073f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)            } else {
2074f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)                // No good way to resolve ambiguous time at transition,
2075f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)                // but following code work in most case.
2076f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)                tz.getOffset(localMillis, TRUE, raw, dst, status);
2077f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)            }
2078f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
2079f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)            // Now, compare the results with parsed type, either standard or daylight saving time
2080f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)            int32_t resolvedSavings = dst;
2081f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)            if (tztype == TZTYPE_STD) {
2082f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)                if (dst != 0) {
2083f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)                    // Override DST_OFFSET = 0 in the result calendar
2084f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)                    resolvedSavings = 0;
2085f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)                }
2086f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)            } else { // tztype == TZTYPE_DST
2087f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)                if (dst == 0) {
2088f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)                    if (btz != NULL) {
2089f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)                        UDate time = localMillis + raw;
2090f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)                        // We use the nearest daylight saving time rule.
2091f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)                        TimeZoneTransition beforeTrs, afterTrs;
2092f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)                        UDate beforeT = time, afterT = time;
2093f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)                        int32_t beforeSav = 0, afterSav = 0;
2094f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)                        UBool beforeTrsAvail, afterTrsAvail;
2095f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
2096f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)                        // Search for DST rule before or on the time
2097f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)                        while (TRUE) {
2098f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)                            beforeTrsAvail = btz->getPreviousTransition(beforeT, TRUE, beforeTrs);
2099f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)                            if (!beforeTrsAvail) {
2100f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)                                break;
2101f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)                            }
2102f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)                            beforeT = beforeTrs.getTime() - 1;
2103f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)                            beforeSav = beforeTrs.getFrom()->getDSTSavings();
2104f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)                            if (beforeSav != 0) {
2105f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)                                break;
2106f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)                            }
2107f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)                        }
2108f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
2109f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)                        // Search for DST rule after the time
2110f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)                        while (TRUE) {
2111f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)                            afterTrsAvail = btz->getNextTransition(afterT, FALSE, afterTrs);
2112f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)                            if (!afterTrsAvail) {
2113f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)                                break;
2114f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)                            }
2115f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)                            afterT = afterTrs.getTime();
2116f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)                            afterSav = afterTrs.getTo()->getDSTSavings();
2117f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)                            if (afterSav != 0) {
2118f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)                                break;
2119f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)                            }
2120f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)                        }
2121f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
2122f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)                        if (beforeTrsAvail && afterTrsAvail) {
2123f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)                            if (time - beforeT > afterT - time) {
2124f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)                                resolvedSavings = afterSav;
2125f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)                            } else {
2126f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)                                resolvedSavings = beforeSav;
2127f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)                            }
2128f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)                        } else if (beforeTrsAvail && beforeSav != 0) {
2129f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)                            resolvedSavings = beforeSav;
2130f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)                        } else if (afterTrsAvail && afterSav != 0) {
2131f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)                            resolvedSavings = afterSav;
2132f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)                        } else {
2133f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)                            resolvedSavings = btz->getDSTSavings();
2134f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)                        }
2135f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)                    } else {
2136f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)                        resolvedSavings = tz.getDSTSavings();
2137f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)                    }
2138f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)                    if (resolvedSavings == 0) {
2139f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)                        // final fallback
2140f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)                        resolvedSavings = U_MILLIS_PER_HOUR;
2141f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)                    }
2142f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)                }
2143f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)            }
2144f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)            cal.set(UCAL_ZONE_OFFSET, raw);
2145f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)            cal.set(UCAL_DST_OFFSET, resolvedSavings);
2146f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)            delete copy;
2147f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        }
2148f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    }
2149f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)ExitParse:
2150f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    // Set the parsed result if local calendar is used
2151f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    // instead of the input calendar
2152f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    if (U_SUCCESS(status) && workCal != &cal) {
2153f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        cal.setTimeZone(workCal->getTimeZone());
2154f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        cal.setTime(workCal->getTime(status), status);
2155f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    }
2156f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
2157f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    // Restore the original time zone if required
2158f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    if (backupTZ != NULL) {
2159f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        fCalendar->adoptTimeZone(backupTZ);
2160f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    }
2161f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
2162f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    // If any Calendar calls failed, we pretend that we
2163f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    // couldn't parse the string, when in reality this isn't quite accurate--
2164f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    // we did parse it; the Calendar calls just failed.
2165f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    if (U_FAILURE(status)) {
2166f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        parsePos.setErrorIndex(pos);
2167f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        parsePos.setIndex(start);
2168f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    }
2169f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)}
2170f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
2171f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)UDate
2172f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)SimpleDateFormat::parse( const UnicodeString& text,
2173f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)                         ParsePosition& pos) const {
2174f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    // redefined here because the other parse() function hides this function's
2175f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    // cunterpart on DateFormat
2176f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    return DateFormat::parse(text, pos);
2177f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)}
2178f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
2179f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)UDate
2180f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)SimpleDateFormat::parse(const UnicodeString& text, UErrorCode& status) const
2181f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles){
2182f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    // redefined here because the other parse() function hides this function's
2183f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    // counterpart on DateFormat
2184f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    return DateFormat::parse(text, status);
2185f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)}
2186f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)//----------------------------------------------------------------------
2187f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
2188f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)int32_t SimpleDateFormat::matchQuarterString(const UnicodeString& text,
2189f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)                              int32_t start,
2190f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)                              UCalendarDateFields field,
2191f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)                              const UnicodeString* data,
2192f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)                              int32_t dataCount,
2193f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)                              Calendar& cal) const
2194f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles){
2195f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    int32_t i = 0;
2196f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    int32_t count = dataCount;
2197f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
2198f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    // There may be multiple strings in the data[] array which begin with
2199f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    // the same prefix (e.g., Cerven and Cervenec (June and July) in Czech).
2200f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    // We keep track of the longest match, and return that.  Note that this
2201f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    // unfortunately requires us to test all array elements.
2202f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    int32_t bestMatchLength = 0, bestMatch = -1;
2203f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
2204f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    // {sfb} kludge to support case-insensitive comparison
2205f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    // {markus 2002oct11} do not just use caseCompareBetween because we do not know
2206f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    // the length of the match after case folding
2207f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    // {alan 20040607} don't case change the whole string, since the length
2208f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    // can change
2209f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    // TODO we need a case-insensitive startsWith function
2210f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    UnicodeString lcase, lcaseText;
2211f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    text.extract(start, INT32_MAX, lcaseText);
2212f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    lcaseText.foldCase();
2213f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
2214f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    for (; i < count; ++i)
2215f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    {
2216f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        // Always compare if we have no match yet; otherwise only compare
2217f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        // against potentially better matches (longer strings).
2218f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
2219f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        lcase.fastCopyFrom(data[i]).foldCase();
2220f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        int32_t length = lcase.length();
2221f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
2222f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        if (length > bestMatchLength &&
2223f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)            lcaseText.compareBetween(0, length, lcase, 0, length) == 0)
2224f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        {
2225f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)            bestMatch = i;
2226f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)            bestMatchLength = length;
2227f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        }
2228f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    }
2229f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    if (bestMatch >= 0)
2230f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    {
2231f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        cal.set(field, bestMatch * 3);
2232f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
2233f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        // Once we have a match, we have to determine the length of the
2234f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        // original source string.  This will usually be == the length of
2235f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        // the case folded string, but it may differ (e.g. sharp s).
2236f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        lcase.fastCopyFrom(data[bestMatch]).foldCase();
2237f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
2238f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        // Most of the time, the length will be the same as the length
2239f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        // of the string from the locale data.  Sometimes it will be
2240f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        // different, in which case we will have to figure it out by
2241f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        // adding a character at a time, until we have a match.  We do
2242f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        // this all in one loop, where we try 'len' first (at index
2243f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        // i==0).
2244f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        int32_t len = data[bestMatch].length(); // 99+% of the time
2245f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        int32_t n = text.length() - start;
2246f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        for (i=0; i<=n; ++i) {
2247f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)            int32_t j=i;
2248f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)            if (i == 0) {
2249f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)                j = len;
2250f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)            } else if (i == len) {
2251f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)                continue; // already tried this when i was 0
2252f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)            }
2253f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)            text.extract(start, j, lcaseText);
2254f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)            lcaseText.foldCase();
2255f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)            if (lcase == lcaseText) {
2256f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)                return start + j;
2257f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)            }
2258f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        }
2259f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    }
2260f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
2261f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    return -start;
2262f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)}
2263f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
2264f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)//----------------------------------------------------------------------
2265f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
2266f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)int32_t SimpleDateFormat::matchString(const UnicodeString& text,
2267f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)                              int32_t start,
2268f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)                              UCalendarDateFields field,
2269f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)                              const UnicodeString* data,
2270f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)                              int32_t dataCount,
2271f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)                              Calendar& cal) const
2272f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles){
2273f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    int32_t i = 0;
2274f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    int32_t count = dataCount;
2275f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
2276f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    if (field == UCAL_DAY_OF_WEEK) i = 1;
2277f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
2278f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    // There may be multiple strings in the data[] array which begin with
2279f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    // the same prefix (e.g., Cerven and Cervenec (June and July) in Czech).
2280f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    // We keep track of the longest match, and return that.  Note that this
2281f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    // unfortunately requires us to test all array elements.
2282f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    int32_t bestMatchLength = 0, bestMatch = -1;
2283f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
2284f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    // {sfb} kludge to support case-insensitive comparison
2285f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    // {markus 2002oct11} do not just use caseCompareBetween because we do not know
2286f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    // the length of the match after case folding
2287f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    // {alan 20040607} don't case change the whole string, since the length
2288f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    // can change
2289f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    // TODO we need a case-insensitive startsWith function
2290f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    UnicodeString lcase, lcaseText;
2291f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    text.extract(start, INT32_MAX, lcaseText);
2292f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    lcaseText.foldCase();
2293f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
2294f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    for (; i < count; ++i)
2295f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    {
2296f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        // Always compare if we have no match yet; otherwise only compare
2297f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        // against potentially better matches (longer strings).
2298f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
2299f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        lcase.fastCopyFrom(data[i]).foldCase();
2300f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        int32_t length = lcase.length();
2301f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
2302f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        if (length > bestMatchLength &&
2303f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)            lcaseText.compareBetween(0, length, lcase, 0, length) == 0)
2304f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        {
2305f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)            bestMatch = i;
2306f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)            bestMatchLength = length;
2307f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        }
2308f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    }
2309f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    if (bestMatch >= 0)
2310f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    {
2311f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        // Adjustment for Hebrew Calendar month Adar II
2312f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        if (!strcmp(cal.getType(),"hebrew") && field==UCAL_MONTH && bestMatch==13) {
2313f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)            cal.set(field,6);
2314f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        }
2315f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        else {
2316f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)            cal.set(field, bestMatch);
2317f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        }
2318f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
2319f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        // Once we have a match, we have to determine the length of the
2320f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        // original source string.  This will usually be == the length of
2321f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        // the case folded string, but it may differ (e.g. sharp s).
2322f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        lcase.fastCopyFrom(data[bestMatch]).foldCase();
2323f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
2324f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        // Most of the time, the length will be the same as the length
2325f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        // of the string from the locale data.  Sometimes it will be
2326f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        // different, in which case we will have to figure it out by
2327f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        // adding a character at a time, until we have a match.  We do
2328f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        // this all in one loop, where we try 'len' first (at index
2329f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        // i==0).
2330f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        int32_t len = data[bestMatch].length(); // 99+% of the time
2331f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        int32_t n = text.length() - start;
2332f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        for (i=0; i<=n; ++i) {
2333f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)            int32_t j=i;
2334f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)            if (i == 0) {
2335f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)                j = len;
2336f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)            } else if (i == len) {
2337f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)                continue; // already tried this when i was 0
2338f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)            }
2339f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)            text.extract(start, j, lcaseText);
2340f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)            lcaseText.foldCase();
2341f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)            if (lcase == lcaseText) {
2342f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)                return start + j;
2343f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)            }
2344f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        }
2345f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    }
2346f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
2347f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    return -start;
2348f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)}
2349f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
2350f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)//----------------------------------------------------------------------
2351f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
2352f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)void
2353f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)SimpleDateFormat::set2DigitYearStart(UDate d, UErrorCode& status)
2354f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles){
2355f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    parseAmbiguousDatesAsAfter(d, status);
2356f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)}
2357f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
2358f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)/**
2359f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) * Private member function that converts the parsed date strings into
2360f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) * timeFields. Returns -start (for ParsePosition) if failed.
2361f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) * @param text the time text to be parsed.
2362f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) * @param start where to start parsing.
2363f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) * @param ch the pattern character for the date field text to be parsed.
2364f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) * @param count the count of a pattern character.
2365f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) * @return the new start position if matching succeeded; a negative number
2366f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) * indicating matching failure, otherwise.
2367f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) */
2368f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)int32_t SimpleDateFormat::subParse(const UnicodeString& text, int32_t& start, UChar ch, int32_t count,
2369f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)                           UBool obeyCount, UBool allowNegative, UBool ambiguousYear[], int32_t& saveHebrewMonth, Calendar& cal,
2370f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)                           int32_t patLoc) const
2371f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles){
2372f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    Formattable number;
2373f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    int32_t value = 0;
2374f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    int32_t i;
2375f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    int32_t ps = 0;
2376f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    ParsePosition pos(0);
2377f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    UDateFormatField patternCharIndex;
2378f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    NumberFormat *currentNumberFormat;
2379f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    UnicodeString temp;
2380f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    UChar *patternCharPtr = u_strchr(DateFormatSymbols::getPatternUChars(), ch);
2381f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
2382f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)#if defined (U_DEBUG_CAL)
2383f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    //fprintf(stderr, "%s:%d - [%c]  st=%d \n", __FILE__, __LINE__, (char) ch, start);
2384f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)#endif
2385f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
2386f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    if (patternCharPtr == NULL) {
2387f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        return -start;
2388f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    }
2389f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
2390f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    patternCharIndex = (UDateFormatField)(patternCharPtr - DateFormatSymbols::getPatternUChars());
2391f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    currentNumberFormat = getNumberFormatByIndex(patternCharIndex);
2392f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    UCalendarDateFields field = fgPatternIndexToCalendarField[patternCharIndex];
2393f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
2394f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    // If there are any spaces here, skip over them.  If we hit the end
2395f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    // of the string, then fail.
2396f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    for (;;) {
2397f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        if (start >= text.length()) {
2398f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)            return -start;
2399f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        }
2400f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        UChar32 c = text.char32At(start);
2401f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        if (!u_isUWhiteSpace(c) || !uprv_isRuleWhiteSpace(c)) {
2402f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)            break;
2403f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        }
2404f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        start += UTF_CHAR_LENGTH(c);
2405f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    }
2406f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    pos.setIndex(start);
2407f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
2408f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    // We handle a few special cases here where we need to parse
2409f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    // a number value.  We handle further, more generic cases below.  We need
2410f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    // to handle some of them here because some fields require extra processing on
2411f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    // the parsed value.
2412f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    if (patternCharIndex == UDAT_HOUR_OF_DAY1_FIELD ||
2413f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        patternCharIndex == UDAT_HOUR1_FIELD ||
2414f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        (patternCharIndex == UDAT_DOW_LOCAL_FIELD && count <= 2) ||
2415f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        (patternCharIndex == UDAT_STANDALONE_DAY_FIELD && count <= 2) ||
2416f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        (patternCharIndex == UDAT_MONTH_FIELD && count <= 2) ||
2417f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        (patternCharIndex == UDAT_STANDALONE_MONTH_FIELD && count <= 2) ||
2418f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        (patternCharIndex == UDAT_QUARTER_FIELD && count <= 2) ||
2419f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        (patternCharIndex == UDAT_STANDALONE_QUARTER_FIELD && count <= 2) ||
2420f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        patternCharIndex == UDAT_YEAR_FIELD ||
2421f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        patternCharIndex == UDAT_YEAR_WOY_FIELD ||
2422f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        patternCharIndex == UDAT_FRACTIONAL_SECOND_FIELD)
2423f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    {
2424f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        int32_t parseStart = pos.getIndex();
2425f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        // It would be good to unify this with the obeyCount logic below,
2426f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        // but that's going to be difficult.
2427f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        const UnicodeString* src;
2428f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
2429f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        if (obeyCount) {
2430f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)            if ((start+count) > text.length()) {
2431f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)                return -start;
2432f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)            }
2433f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
2434f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)            text.extractBetween(0, start + count, temp);
2435f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)            src = &temp;
2436f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        } else {
2437f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)            src = &text;
2438f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        }
2439f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
2440f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        parseInt(*src, number, pos, allowNegative,currentNumberFormat);
2441f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
2442f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        if (pos.getIndex() == parseStart)
2443f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)            return -start;
2444f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        value = number.getLong();
2445f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
2446f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        // suffix processing
2447f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        int32_t txtLoc = pos.getIndex();
2448f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        if (value <0 ) {
2449f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)            txtLoc = checkIntSuffix(text, txtLoc, patLoc+1, TRUE);
2450f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)            if (txtLoc != pos.getIndex()) {
2451f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)                value *= -1;
2452f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)            }
2453f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        }
2454f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        else {
2455f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)            txtLoc = checkIntSuffix(text, txtLoc, patLoc+1, FALSE);
2456f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        }
2457f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        pos.setIndex(txtLoc);
2458f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
2459f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    }
2460f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
2461f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    switch (patternCharIndex) {
2462f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    case UDAT_ERA_FIELD:
2463f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        if (count == 5) {
2464f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)            ps = matchString(text, start, UCAL_ERA, fSymbols->fNarrowEras, fSymbols->fNarrowErasCount, cal);
2465f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        }
2466f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        if (count == 4) {
2467f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)            ps = matchString(text, start, UCAL_ERA, fSymbols->fEraNames, fSymbols->fEraNamesCount, cal);
2468f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        }
2469f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        else {
2470f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)            ps = matchString(text, start, UCAL_ERA, fSymbols->fEras, fSymbols->fErasCount, cal);
2471f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        }
2472f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
2473f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        // check return position, if it equals -start, then matchString error
2474f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        // special case the return code so we don't necessarily fail out until we
2475f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        // verify no year information also
2476f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        if (ps == -start)
2477f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)            ps--;
2478f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
2479f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        return ps;
2480f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
2481f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    case UDAT_YEAR_FIELD:
2482f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        // If there are 3 or more YEAR pattern characters, this indicates
2483f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        // that the year value is to be treated literally, without any
2484f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        // two-digit year adjustments (e.g., from "01" to 2001).  Otherwise
2485f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        // we made adjustments to place the 2-digit year in the proper
2486f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        // century, for parsed strings from "00" to "99".  Any other string
2487f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        // is treated literally:  "2250", "-1", "1", "002".
2488f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        if (count <= 2 && (pos.getIndex() - start) == 2
2489f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)            && u_isdigit(text.charAt(start))
2490f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)            && u_isdigit(text.charAt(start+1)))
2491f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        {
2492f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)            // Assume for example that the defaultCenturyStart is 6/18/1903.
2493f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)            // This means that two-digit years will be forced into the range
2494f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)            // 6/18/1903 to 6/17/2003.  As a result, years 00, 01, and 02
2495f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)            // correspond to 2000, 2001, and 2002.  Years 04, 05, etc. correspond
2496f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)            // to 1904, 1905, etc.  If the year is 03, then it is 2003 if the
2497f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)            // other fields specify a date before 6/18, or 1903 if they specify a
2498f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)            // date afterwards.  As a result, 03 is an ambiguous year.  All other
2499f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)            // two-digit years are unambiguous.
2500f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)          if(fHaveDefaultCentury) { // check if this formatter even has a pivot year
2501f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)              int32_t ambiguousTwoDigitYear = fDefaultCenturyStartYear % 100;
2502f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)              ambiguousYear[0] = (value == ambiguousTwoDigitYear);
2503f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)              value += (fDefaultCenturyStartYear/100)*100 +
2504f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)                (value < ambiguousTwoDigitYear ? 100 : 0);
2505f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)            }
2506f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        }
2507f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        cal.set(UCAL_YEAR, value);
2508f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
2509f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        // Delayed checking for adjustment of Hebrew month numbers in non-leap years.
2510f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        if (saveHebrewMonth >= 0) {
2511f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)            HebrewCalendar *hc = (HebrewCalendar*)&cal;
2512f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)            if (!hc->isLeapYear(value) && saveHebrewMonth >= 6) {
2513f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)               cal.set(UCAL_MONTH,saveHebrewMonth);
2514f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)            } else {
2515f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)               cal.set(UCAL_MONTH,saveHebrewMonth-1);
2516f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)            }
2517f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)            saveHebrewMonth = -1;
2518f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        }
2519f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        return pos.getIndex();
2520f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
2521f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    case UDAT_YEAR_WOY_FIELD:
2522f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        // Comment is the same as for UDAT_Year_FIELDs - look above
2523f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        if (count <= 2 && (pos.getIndex() - start) == 2
2524f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)            && u_isdigit(text.charAt(start))
2525f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)            && u_isdigit(text.charAt(start+1))
2526f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)            && fHaveDefaultCentury )
2527f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        {
2528f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)            int32_t ambiguousTwoDigitYear = fDefaultCenturyStartYear % 100;
2529f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)            ambiguousYear[0] = (value == ambiguousTwoDigitYear);
2530f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)            value += (fDefaultCenturyStartYear/100)*100 +
2531f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)                (value < ambiguousTwoDigitYear ? 100 : 0);
2532f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        }
2533f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        cal.set(UCAL_YEAR_WOY, value);
2534f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        return pos.getIndex();
2535f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
2536f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    case UDAT_MONTH_FIELD:
2537f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        if (count <= 2) // i.e., M or MM.
2538f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        {
2539f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)            // When parsing month numbers from the Hebrew Calendar, we might need to adjust the month depending on whether
2540f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)            // 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
2541f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)            // the year is parsed.
2542f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)            if (!strcmp(cal.getType(),"hebrew")) {
2543f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)                HebrewCalendar *hc = (HebrewCalendar*)&cal;
2544f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)                if (cal.isSet(UCAL_YEAR)) {
2545f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)                   UErrorCode status = U_ZERO_ERROR;
2546f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)                   if (!hc->isLeapYear(hc->get(UCAL_YEAR,status)) && value >= 6) {
2547f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)                       cal.set(UCAL_MONTH, value);
2548f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)                   } else {
2549f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)                       cal.set(UCAL_MONTH, value - 1);
2550f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)                   }
2551f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)                } else {
2552f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)                    saveHebrewMonth = value;
2553f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)                }
2554f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)            } else {
2555f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)                // Don't want to parse the month if it is a string
2556f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)                // while pattern uses numeric style: M or MM.
2557f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)                // [We computed 'value' above.]
2558f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)                cal.set(UCAL_MONTH, value - 1);
2559f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)            }
2560f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)            return pos.getIndex();
2561f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        } else {
2562f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)            // count >= 3 // i.e., MMM or MMMM
2563f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)            // Want to be able to parse both short and long forms.
2564f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)            // Try count == 4 first:
2565f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)            int32_t newStart = 0;
2566f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
2567f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)            if ((newStart = matchString(text, start, UCAL_MONTH,
2568f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)                                      fSymbols->fMonths, fSymbols->fMonthsCount, cal)) > 0)
2569f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)                return newStart;
2570f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)            else // count == 4 failed, now try count == 3
2571f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)                return matchString(text, start, UCAL_MONTH,
2572f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)                                   fSymbols->fShortMonths, fSymbols->fShortMonthsCount, cal);
2573f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        }
2574f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
2575f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    case UDAT_STANDALONE_MONTH_FIELD:
2576f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        if (count <= 2) // i.e., L or LL.
2577f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        {
2578f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)            // Don't want to parse the month if it is a string
2579f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)            // while pattern uses numeric style: M or MM.
2580f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)            // [We computed 'value' above.]
2581f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)            cal.set(UCAL_MONTH, value - 1);
2582f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)            return pos.getIndex();
2583f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        } else {
2584f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)            // count >= 3 // i.e., LLL or LLLL
2585f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)            // Want to be able to parse both short and long forms.
2586f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)            // Try count == 4 first:
2587f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)            int32_t newStart = 0;
2588f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
2589f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)            if ((newStart = matchString(text, start, UCAL_MONTH,
2590f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)                                      fSymbols->fStandaloneMonths, fSymbols->fStandaloneMonthsCount, cal)) > 0)
2591f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)                return newStart;
2592f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)            else // count == 4 failed, now try count == 3
2593f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)                return matchString(text, start, UCAL_MONTH,
2594f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)                                   fSymbols->fStandaloneShortMonths, fSymbols->fStandaloneShortMonthsCount, cal);
2595f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        }
2596f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
2597f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    case UDAT_HOUR_OF_DAY1_FIELD:
2598f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        // [We computed 'value' above.]
2599f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        if (value == cal.getMaximum(UCAL_HOUR_OF_DAY) + 1)
2600f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)            value = 0;
2601f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        cal.set(UCAL_HOUR_OF_DAY, value);
2602f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        return pos.getIndex();
2603f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
2604f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    case UDAT_FRACTIONAL_SECOND_FIELD:
2605f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        // Fractional seconds left-justify
2606f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        i = pos.getIndex() - start;
2607f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        if (i < 3) {
2608f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)            while (i < 3) {
2609f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)                value *= 10;
2610f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)                i++;
2611f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)            }
2612f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        } else {
2613f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)            int32_t a = 1;
2614f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)            while (i > 3) {
2615f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)                a *= 10;
2616f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)                i--;
2617f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)            }
2618f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)            value = (value + (a>>1)) / a;
2619f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        }
2620f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        cal.set(UCAL_MILLISECOND, value);
2621f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        return pos.getIndex();
2622f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
2623f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    case UDAT_DOW_LOCAL_FIELD:
2624f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        if (count <= 2) // i.e., e or ee
2625f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        {
2626f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)            // [We computed 'value' above.]
2627f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)            cal.set(UCAL_DOW_LOCAL, value);
2628f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)            return pos.getIndex();
2629f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        }
2630f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        // else for eee-eeeee fall through to handling of EEE-EEEEE
2631f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        // fall through, do not break here
2632f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    case UDAT_DAY_OF_WEEK_FIELD:
2633f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        {
2634f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)            // Want to be able to parse both short and long forms.
2635f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)            // Try count == 4 (EEEE) first:
2636f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)            int32_t newStart = 0;
2637f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)            if ((newStart = matchString(text, start, UCAL_DAY_OF_WEEK,
2638f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)                                      fSymbols->fWeekdays, fSymbols->fWeekdaysCount, cal)) > 0)
2639f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)                return newStart;
2640f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)            // EEEE failed, now try EEE
2641f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)            else if ((newStart = matchString(text, start, UCAL_DAY_OF_WEEK,
2642f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)                                   fSymbols->fShortWeekdays, fSymbols->fShortWeekdaysCount, cal)) > 0)
2643f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)                return newStart;
2644f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)            // EEE failed, now try EEEEE
2645f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)            else
2646f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)                return matchString(text, start, UCAL_DAY_OF_WEEK,
2647f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)                                   fSymbols->fNarrowWeekdays, fSymbols->fNarrowWeekdaysCount, cal);
2648f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        }
2649f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
2650f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    case UDAT_STANDALONE_DAY_FIELD:
2651f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        {
2652f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)            if (count <= 2) // c or cc
2653f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)            {
2654f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)                // [We computed 'value' above.]
2655f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)                cal.set(UCAL_DOW_LOCAL, value);
2656f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)                return pos.getIndex();
2657f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)            }
2658f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)            // Want to be able to parse both short and long forms.
2659f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)            // Try count == 4 (cccc) first:
2660f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)            int32_t newStart = 0;
2661f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)            if ((newStart = matchString(text, start, UCAL_DAY_OF_WEEK,
2662f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)                                      fSymbols->fStandaloneWeekdays, fSymbols->fStandaloneWeekdaysCount, cal)) > 0)
2663f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)                return newStart;
2664f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)            else // cccc failed, now try ccc
2665f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)                return matchString(text, start, UCAL_DAY_OF_WEEK,
2666f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)                                   fSymbols->fStandaloneShortWeekdays, fSymbols->fStandaloneShortWeekdaysCount, cal);
2667f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        }
2668f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
2669f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    case UDAT_AM_PM_FIELD:
2670f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        return matchString(text, start, UCAL_AM_PM, fSymbols->fAmPms, fSymbols->fAmPmsCount, cal);
2671f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
2672f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    case UDAT_HOUR1_FIELD:
2673f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        // [We computed 'value' above.]
2674f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        if (value == cal.getLeastMaximum(UCAL_HOUR)+1)
2675f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)            value = 0;
2676f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        cal.set(UCAL_HOUR, value);
2677f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        return pos.getIndex();
2678f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
2679f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    case UDAT_QUARTER_FIELD:
2680f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        if (count <= 2) // i.e., Q or QQ.
2681f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        {
2682f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)            // Don't want to parse the month if it is a string
2683f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)            // while pattern uses numeric style: Q or QQ.
2684f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)            // [We computed 'value' above.]
2685f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)            cal.set(UCAL_MONTH, (value - 1) * 3);
2686f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)            return pos.getIndex();
2687f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        } else {
2688f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)            // count >= 3 // i.e., QQQ or QQQQ
2689f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)            // Want to be able to parse both short and long forms.
2690f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)            // Try count == 4 first:
2691f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)            int32_t newStart = 0;
2692f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
2693f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)            if ((newStart = matchQuarterString(text, start, UCAL_MONTH,
2694f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)                                      fSymbols->fQuarters, fSymbols->fQuartersCount, cal)) > 0)
2695f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)                return newStart;
2696f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)            else // count == 4 failed, now try count == 3
2697f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)                return matchQuarterString(text, start, UCAL_MONTH,
2698f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)                                   fSymbols->fShortQuarters, fSymbols->fShortQuartersCount, cal);
2699f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        }
2700f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
2701f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    case UDAT_STANDALONE_QUARTER_FIELD:
2702f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        if (count <= 2) // i.e., q or qq.
2703f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        {
2704f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)            // Don't want to parse the month if it is a string
2705f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)            // while pattern uses numeric style: q or q.
2706f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)            // [We computed 'value' above.]
2707f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)            cal.set(UCAL_MONTH, (value - 1) * 3);
2708f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)            return pos.getIndex();
2709f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        } else {
2710f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)            // count >= 3 // i.e., qqq or qqqq
2711f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)            // Want to be able to parse both short and long forms.
2712f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)            // Try count == 4 first:
2713f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)            int32_t newStart = 0;
2714f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
2715f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)            if ((newStart = matchQuarterString(text, start, UCAL_MONTH,
2716f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)                                      fSymbols->fStandaloneQuarters, fSymbols->fStandaloneQuartersCount, cal)) > 0)
2717f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)                return newStart;
2718f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)            else // count == 4 failed, now try count == 3
2719f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)                return matchQuarterString(text, start, UCAL_MONTH,
2720f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)                                   fSymbols->fStandaloneShortQuarters, fSymbols->fStandaloneShortQuartersCount, cal);
2721f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        }
2722f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
2723f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    case UDAT_TIMEZONE_FIELD:
2724f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    case UDAT_TIMEZONE_RFC_FIELD:
2725f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    case UDAT_TIMEZONE_GENERIC_FIELD:
2726f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    case UDAT_TIMEZONE_SPECIAL_FIELD:
2727f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        {
2728f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)            int32_t offset = 0;
2729f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)            UBool parsed = FALSE;
2730f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
2731f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)            // Step 1
2732f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)            // Check if this is a long GMT offset string (either localized or default)
2733f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)            offset = parseGMT(text, pos);
2734f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)            if (pos.getIndex() - start > 0) {
2735f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)                parsed = TRUE;
2736f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)            }
2737f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)            if (!parsed) {
2738f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)                // Step 2
2739f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)                // Check if this is an RFC822 time zone offset.
2740f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)                // ICU supports the standard RFC822 format [+|-]HHmm
2741f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)                // and its extended form [+|-]HHmmSS.
2742f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)                do {
2743f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)                    int32_t sign = 0;
2744f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)                    UChar signChar = text.charAt(start);
2745f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)                    if (signChar == (UChar)0x002B /* '+' */) {
2746f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)                        sign = 1;
2747f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)                    } else if (signChar == (UChar)0x002D /* '-' */) {
2748f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)                        sign = -1;
2749f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)                    } else {
2750f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)                        // Not an RFC822 offset string
2751f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)                        break;
2752f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)                    }
2753f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
2754f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)                    // Parse digits
2755f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)                    int32_t orgPos = start + 1;
2756f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)                    pos.setIndex(orgPos);
2757f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)                    parseInt(text, number, 6, pos, FALSE,currentNumberFormat);
2758f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)                    int32_t numLen = pos.getIndex() - orgPos;
2759f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)                    if (numLen <= 0) {
2760f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)                        break;
2761f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)                    }
2762f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
2763f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)                    // Followings are possible format (excluding sign char)
2764f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)                    // HHmmSS
2765f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)                    // HmmSS
2766f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)                    // HHmm
2767f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)                    // Hmm
2768f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)                    // HH
2769f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)                    // H
2770f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)                    int32_t val = number.getLong();
2771f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)                    int32_t hour = 0, min = 0, sec = 0;
2772f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)                    switch(numLen) {
2773f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)                    case 1: // H
2774f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)                    case 2: // HH
2775f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)                        hour = val;
2776f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)                        break;
2777f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)                    case 3: // Hmm
2778f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)                    case 4: // HHmm
2779f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)                        hour = val / 100;
2780f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)                        min = val % 100;
2781f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)                        break;
2782f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)                    case 5: // Hmmss
2783f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)                    case 6: // HHmmss
2784f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)                        hour = val / 10000;
2785f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)                        min = (val % 10000) / 100;
2786f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)                        sec = val % 100;
2787f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)                        break;
2788f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)                    }
2789f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)                    if (hour > 23 || min > 59 || sec > 59) {
2790f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)                        // Invalid value range
2791f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)                        break;
2792f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)                    }
2793f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)                    offset = (((hour * 60) + min) * 60 + sec) * 1000 * sign;
2794f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)                    parsed = TRUE;
2795f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)                } while (FALSE);
2796f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
2797f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)                if (!parsed) {
2798f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)                    // Failed to parse.  Reset the position.
2799f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)                    pos.setIndex(start);
2800f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)                }
2801f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)            }
2802f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
2803f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)            if (parsed) {
2804f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)                // offset was successfully parsed as either a long GMT string or RFC822 zone offset
2805f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)                // string.  Create normalized zone ID for the offset.
2806f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
2807f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)                UnicodeString tzID(gGmt);
2808f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)                formatRFC822TZ(tzID, offset);
2809f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)                //TimeZone *customTZ = TimeZone::createTimeZone(tzID);
2810f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)                TimeZone *customTZ = new SimpleTimeZone(offset, tzID);    // faster than TimeZone::createTimeZone
2811f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)                cal.adoptTimeZone(customTZ);
2812f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
2813f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)                return pos.getIndex();
2814f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)            }
2815f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
2816f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)            // Step 3
2817f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)            // At this point, check for named time zones by looking through
2818f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)            // the locale data from the DateFormatZoneData strings.
2819f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)            // Want to be able to parse both short and long forms.
2820f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)            // optimize for calendar's current time zone
2821f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)            const ZoneStringFormat *zsf = fSymbols->getZoneStringFormat();
2822f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)            if (zsf) {
2823f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)                UErrorCode status = U_ZERO_ERROR;
2824f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)                const ZoneStringInfo *zsinfo = NULL;
2825f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)                int32_t matchLen;
2826f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
2827f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)                switch (patternCharIndex) {
2828f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)                    case UDAT_TIMEZONE_FIELD: // 'z'
2829f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)                        if (count < 4) {
2830f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)                            zsinfo = zsf->findSpecificShort(text, start, matchLen, status);
2831f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)                        } else {
2832f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)                            zsinfo = zsf->findSpecificLong(text, start, matchLen, status);
2833f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)                        }
2834f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)                        break;
2835f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)                    case UDAT_TIMEZONE_GENERIC_FIELD: // 'v'
2836f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)                        if (count == 1) {
2837f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)                            zsinfo = zsf->findGenericShort(text, start, matchLen, status);
2838f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)                        } else if (count == 4) {
2839f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)                            zsinfo = zsf->findGenericLong(text, start, matchLen, status);
2840f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)                        }
2841f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)                        break;
2842f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)                    case UDAT_TIMEZONE_SPECIAL_FIELD: // 'V'
2843f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)                        if (count == 1) {
2844f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)                            zsinfo = zsf->findSpecificShort(text, start, matchLen, status);
2845f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)                        } else if (count == 4) {
2846f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)                            zsinfo = zsf->findGenericLocation(text, start, matchLen, status);
2847f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)                        }
2848f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)                        break;
2849f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)                    default:
2850f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)                        break;
2851f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)                }
2852f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
2853f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)                if (U_SUCCESS(status) && zsinfo != NULL) {
2854f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)                    if (zsinfo->isStandard()) {
2855f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)                        ((SimpleDateFormat*)this)->tztype = TZTYPE_STD;
2856f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)                    } else if (zsinfo->isDaylight()) {
2857f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)                        ((SimpleDateFormat*)this)->tztype = TZTYPE_DST;
2858f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)                    }
2859f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)                    UnicodeString tzid;
2860f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)                    zsinfo->getID(tzid);
2861f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
2862f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)                    UnicodeString current;
2863f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)                    cal.getTimeZone().getID(current);
2864f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)                    if (tzid != current) {
2865f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)                        TimeZone *tz = TimeZone::createTimeZone(tzid);
2866f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)                        cal.adoptTimeZone(tz);
2867f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)                    }
2868f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)                    return start + matchLen;
2869f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)                }
2870f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)            }
2871f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)            // Step 4
2872f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)            // Final attempt - is this standalone GMT/UT/UTC?
2873f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)            int32_t gmtLen = 0;
2874f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)            if (text.compare(start, kGmtLen, gGmt) == 0) {
2875f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)                gmtLen = kGmtLen;
2876f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)            } else if (text.compare(start, kUtcLen, gUtc) == 0) {
2877f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)                gmtLen = kUtcLen;
2878f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)            } else if (text.compare(start, kUtLen, gUt) == 0) {
2879f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)                gmtLen = kUtLen;
2880f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)            }
2881f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)            if (gmtLen > 0) {
2882f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)                TimeZone *tz = TimeZone::createTimeZone(UnicodeString("Etc/GMT"));
2883f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)                cal.adoptTimeZone(tz);
2884f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)                return start + gmtLen;
2885f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)            }
2886f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
2887f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)            // complete failure
2888f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)            return -start;
2889f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        }
2890f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
2891f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    default:
2892f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        // Handle "generic" fields
2893f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        int32_t parseStart = pos.getIndex();
2894f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        const UnicodeString* src;
2895f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        if (obeyCount) {
2896f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)            if ((start+count) > text.length()) {
2897f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)                return -start;
2898f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)            }
2899f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)            text.extractBetween(0, start + count, temp);
2900f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)            src = &temp;
2901f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        } else {
2902f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)            src = &text;
2903f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        }
2904f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        parseInt(*src, number, pos, allowNegative,currentNumberFormat);
2905f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        if (pos.getIndex() != parseStart) {
2906f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)            cal.set(field, number.getLong());
2907f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)            return pos.getIndex();
2908f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        }
2909f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        return -start;
2910f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    }
2911f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)}
2912f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
2913f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)/**
2914f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) * Parse an integer using fNumberFormat.  This method is semantically
2915f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) * const, but actually may modify fNumberFormat.
2916f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) */
2917f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)void SimpleDateFormat::parseInt(const UnicodeString& text,
2918f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)                                Formattable& number,
2919f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)                                ParsePosition& pos,
2920f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)                                UBool allowNegative,
2921f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)                                NumberFormat *fmt) const {
2922f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    parseInt(text, number, -1, pos, allowNegative,fmt);
2923f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)}
2924f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
2925f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)/**
2926f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) * Parse an integer using fNumberFormat up to maxDigits.
2927f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) */
2928f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)void SimpleDateFormat::parseInt(const UnicodeString& text,
2929f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)                                Formattable& number,
2930f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)                                int32_t maxDigits,
2931f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)                                ParsePosition& pos,
2932f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)                                UBool allowNegative,
2933f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)                                NumberFormat *fmt) const {
2934f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    UnicodeString oldPrefix;
2935f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    DecimalFormat* df = NULL;
2936f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    if (!allowNegative && (df = dynamic_cast<DecimalFormat*>(fmt)) != NULL) {
2937f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        df->getNegativePrefix(oldPrefix);
2938f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        df->setNegativePrefix(SUPPRESS_NEGATIVE_PREFIX);
2939f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    }
2940f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    int32_t oldPos = pos.getIndex();
2941f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    fmt->parse(text, number, pos);
2942f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    if (df != NULL) {
2943f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        df->setNegativePrefix(oldPrefix);
2944f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    }
2945f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
2946f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    if (maxDigits > 0) {
2947f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        // adjust the result to fit into
2948f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        // the maxDigits and move the position back
2949f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        int32_t nDigits = pos.getIndex() - oldPos;
2950f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        if (nDigits > maxDigits) {
2951f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)            int32_t val = number.getLong();
2952f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)            nDigits -= maxDigits;
2953f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)            while (nDigits > 0) {
2954f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)                val /= 10;
2955f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)                nDigits--;
2956f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)            }
2957f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)            pos.setIndex(oldPos + maxDigits);
2958f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)            number.setLong(val);
2959f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        }
2960f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    }
2961f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)}
2962f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
2963f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)//----------------------------------------------------------------------
2964f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
2965f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)void SimpleDateFormat::translatePattern(const UnicodeString& originalPattern,
2966f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)                                        UnicodeString& translatedPattern,
2967f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)                                        const UnicodeString& from,
2968f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)                                        const UnicodeString& to,
2969f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)                                        UErrorCode& status)
2970f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles){
2971f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)  // run through the pattern and convert any pattern symbols from the version
2972f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)  // in "from" to the corresponding character ion "to".  This code takes
2973f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)  // quoted strings into account (it doesn't try to translate them), and it signals
2974f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)  // an error if a particular "pattern character" doesn't appear in "from".
2975f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)  // Depending on the values of "from" and "to" this can convert from generic
2976f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)  // to localized patterns or localized to generic.
2977f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)  if (U_FAILURE(status))
2978f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    return;
2979f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
2980f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)  translatedPattern.remove();
2981f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)  UBool inQuote = FALSE;
2982f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)  for (int32_t i = 0; i < originalPattern.length(); ++i) {
2983f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    UChar c = originalPattern[i];
2984f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    if (inQuote) {
2985f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)      if (c == QUOTE)
2986f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    inQuote = FALSE;
2987f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    }
2988f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    else {
2989f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)      if (c == QUOTE)
2990f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    inQuote = TRUE;
2991f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)      else if ((c >= 0x0061 /*'a'*/ && c <= 0x007A) /*'z'*/
2992f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)           || (c >= 0x0041 /*'A'*/ && c <= 0x005A /*'Z'*/)) {
2993f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    int32_t ci = from.indexOf(c);
2994f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    if (ci == -1) {
2995f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)      status = U_INVALID_FORMAT_ERROR;
2996f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)      return;
2997f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    }
2998f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    c = to[ci];
2999f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)      }
3000f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    }
3001f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    translatedPattern += c;
3002f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)  }
3003f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)  if (inQuote) {
3004f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    status = U_INVALID_FORMAT_ERROR;
3005f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    return;
3006f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)  }
3007f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)}
3008f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
3009f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)//----------------------------------------------------------------------
3010f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
3011f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)UnicodeString&
3012f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)SimpleDateFormat::toPattern(UnicodeString& result) const
3013f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles){
3014f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    result = fPattern;
3015f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    return result;
3016f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)}
3017f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
3018f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)//----------------------------------------------------------------------
3019f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
3020f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)UnicodeString&
3021f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)SimpleDateFormat::toLocalizedPattern(UnicodeString& result,
3022f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)                                     UErrorCode& status) const
3023f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles){
3024f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    translatePattern(fPattern, result, DateFormatSymbols::getPatternUChars(), fSymbols->fLocalPatternChars, status);
3025f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    return result;
3026f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)}
3027f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
3028f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)//----------------------------------------------------------------------
3029f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
3030f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)void
3031f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)SimpleDateFormat::applyPattern(const UnicodeString& pattern)
3032f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles){
3033f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    fPattern = pattern;
3034f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)}
3035f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
3036f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)//----------------------------------------------------------------------
3037f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
3038f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)void
3039f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)SimpleDateFormat::applyLocalizedPattern(const UnicodeString& pattern,
3040f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)                                        UErrorCode &status)
3041f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles){
3042f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    translatePattern(pattern, fPattern, fSymbols->fLocalPatternChars, DateFormatSymbols::getPatternUChars(), status);
3043f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)}
3044f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
3045f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)//----------------------------------------------------------------------
3046f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
3047f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)const DateFormatSymbols*
3048f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)SimpleDateFormat::getDateFormatSymbols() const
3049f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles){
3050f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    return fSymbols;
3051f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)}
3052f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
3053f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)//----------------------------------------------------------------------
3054f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
3055f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)void
3056f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)SimpleDateFormat::adoptDateFormatSymbols(DateFormatSymbols* newFormatSymbols)
3057f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles){
3058f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    delete fSymbols;
3059f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    fSymbols = newFormatSymbols;
3060f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)}
3061f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
3062f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)//----------------------------------------------------------------------
3063f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)void
3064f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)SimpleDateFormat::setDateFormatSymbols(const DateFormatSymbols& newFormatSymbols)
3065f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles){
3066f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    delete fSymbols;
3067f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    fSymbols = new DateFormatSymbols(newFormatSymbols);
3068f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)}
3069f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
3070f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
3071f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)//----------------------------------------------------------------------
3072f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
3073f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
3074f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)void SimpleDateFormat::adoptCalendar(Calendar* calendarToAdopt)
3075f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles){
3076f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)  UErrorCode status = U_ZERO_ERROR;
3077f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)  DateFormat::adoptCalendar(calendarToAdopt);
3078f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)  delete fSymbols;
3079f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)  fSymbols=NULL;
3080f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)  initializeSymbols(fLocale, fCalendar, status);  // we need new symbols
3081f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)  initializeDefaultCentury();  // we need a new century (possibly)
3082f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)}
3083f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
3084f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
3085f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)//----------------------------------------------------------------------
3086f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
3087f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
3088f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)UBool
3089f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)SimpleDateFormat::isFieldUnitIgnored(UCalendarDateFields field) const {
3090f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    return isFieldUnitIgnored(fPattern, field);
3091f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)}
3092f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
3093f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
3094f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)UBool
3095f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)SimpleDateFormat::isFieldUnitIgnored(const UnicodeString& pattern,
3096f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)                                     UCalendarDateFields field) {
3097f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    int32_t fieldLevel = fgCalendarFieldToLevel[field];
3098f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    int32_t level;
3099f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    UChar ch;
3100f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    UBool inQuote = FALSE;
3101f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    UChar prevCh = 0;
3102f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    int32_t count = 0;
3103f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
3104f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    for (int32_t i = 0; i < pattern.length(); ++i) {
3105f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        ch = pattern[i];
3106f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        if (ch != prevCh && count > 0) {
3107f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)            level = fgPatternCharToLevel[prevCh - PATTERN_CHAR_BASE];
3108f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)            // the larger the level, the smaller the field unit.
3109f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)            if ( fieldLevel <= level ) {
3110f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)                return FALSE;
3111f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)            }
3112f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)            count = 0;
3113f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        }
3114f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        if (ch == QUOTE) {
3115f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)            if ((i+1) < pattern.length() && pattern[i+1] == QUOTE) {
3116f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)                ++i;
3117f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)            } else {
3118f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)                inQuote = ! inQuote;
3119f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)            }
3120f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        }
3121f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        else if ( ! inQuote && ((ch >= 0x0061 /*'a'*/ && ch <= 0x007A /*'z'*/)
3122f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)                    || (ch >= 0x0041 /*'A'*/ && ch <= 0x005A /*'Z'*/))) {
3123f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)            prevCh = ch;
3124f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)            ++count;
3125f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        }
3126f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    }
3127f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    if ( count > 0 ) {
3128f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        // last item
3129f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        level = fgPatternCharToLevel[prevCh - PATTERN_CHAR_BASE];
3130f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)            if ( fieldLevel <= level ) {
3131f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)                return FALSE;
3132f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)            }
3133f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    }
3134f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    return TRUE;
3135f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)}
3136f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
3137f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)//----------------------------------------------------------------------
3138f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
3139f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)const Locale&
3140f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)SimpleDateFormat::getSmpFmtLocale(void) const {
3141f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    return fLocale;
3142f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)}
3143f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
3144f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)//----------------------------------------------------------------------
3145f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
3146f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)int32_t
3147f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)SimpleDateFormat::checkIntSuffix(const UnicodeString& text, int32_t start,
3148f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)                                 int32_t patLoc, UBool isNegative) const {
3149f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    // local variables
3150f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    UnicodeString suf;
3151f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    int32_t patternMatch;
3152f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    int32_t textPreMatch;
3153f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    int32_t textPostMatch;
3154f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
3155f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    // check that we are still in range
3156f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    if ( (start > text.length()) ||
3157f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)         (start < 0) ||
3158f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)         (patLoc < 0) ||
3159f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)         (patLoc > fPattern.length())) {
3160f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        // out of range, don't advance location in text
3161f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        return start;
3162f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    }
3163f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
3164f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    // get the suffix
3165f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    DecimalFormat* decfmt = dynamic_cast<DecimalFormat*>(fNumberFormat);
3166f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    if (decfmt != NULL) {
3167f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        if (isNegative) {
3168f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)            suf = decfmt->getNegativeSuffix(suf);
3169f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        }
3170f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        else {
3171f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)            suf = decfmt->getPositiveSuffix(suf);
3172f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        }
3173f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    }
3174f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
3175f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    // check for suffix
3176f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    if (suf.length() <= 0) {
3177f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        return start;
3178f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    }
3179f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
3180f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    // check suffix will be encountered in the pattern
3181f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    patternMatch = compareSimpleAffix(suf,fPattern,patLoc);
3182f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
3183f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    // check if a suffix will be encountered in the text
3184f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    textPreMatch = compareSimpleAffix(suf,text,start);
3185f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
3186f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    // check if a suffix was encountered in the text
3187f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    textPostMatch = compareSimpleAffix(suf,text,start-suf.length());
3188f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
3189f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    // check for suffix match
3190f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    if ((textPreMatch >= 0) && (patternMatch >= 0) && (textPreMatch == patternMatch)) {
3191f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        return start;
3192f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    }
3193f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    else if ((textPostMatch >= 0) && (patternMatch >= 0) && (textPostMatch == patternMatch)) {
3194f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        return  start - suf.length();
3195f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    }
3196f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
3197f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    // should not get here
3198f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    return start;
3199f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)}
3200f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
3201f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)//----------------------------------------------------------------------
3202f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
3203f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)int32_t
3204f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)SimpleDateFormat::compareSimpleAffix(const UnicodeString& affix,
3205f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)                   const UnicodeString& input,
3206f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)                   int32_t pos) const {
3207f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    int32_t start = pos;
3208f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    for (int32_t i=0; i<affix.length(); ) {
3209f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        UChar32 c = affix.char32At(i);
3210f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        int32_t len = U16_LENGTH(c);
3211f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        if (uprv_isRuleWhiteSpace(c)) {
3212f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)            // We may have a pattern like: \u200F \u0020
3213f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)            //        and input text like: \u200F \u0020
3214f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)            // Note that U+200F and U+0020 are RuleWhiteSpace but only
3215f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)            // U+0020 is UWhiteSpace.  So we have to first do a direct
3216f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)            // match of the run of RULE whitespace in the pattern,
3217f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)            // then match any extra characters.
3218f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)            UBool literalMatch = FALSE;
3219f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)            while (pos < input.length() &&
3220f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)                   input.char32At(pos) == c) {
3221f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)                literalMatch = TRUE;
3222f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)                i += len;
3223f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)                pos += len;
3224f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)                if (i == affix.length()) {
3225f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)                    break;
3226f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)                }
3227f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)                c = affix.char32At(i);
3228f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)                len = U16_LENGTH(c);
3229f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)                if (!uprv_isRuleWhiteSpace(c)) {
3230f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)                    break;
3231f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)                }
3232f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)            }
3233f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
3234f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)            // Advance over run in pattern
3235f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)            i = skipRuleWhiteSpace(affix, i);
3236f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
3237f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)            // Advance over run in input text
3238f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)            // Must see at least one white space char in input,
3239f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)            // unless we've already matched some characters literally.
3240f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)            int32_t s = pos;
3241f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)            pos = skipUWhiteSpace(input, pos);
3242f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)            if (pos == s && !literalMatch) {
3243f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)                return -1;
3244f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)            }
3245f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
3246f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)            // If we skip UWhiteSpace in the input text, we need to skip it in the pattern.
3247f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)            // Otherwise, the previous lines may have skipped over text (such as U+00A0) that
3248f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)            // is also in the affix.
3249f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)            i = skipUWhiteSpace(affix, i);
3250f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        } else {
3251f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)            if (pos < input.length() &&
3252f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)                input.char32At(pos) == c) {
3253f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)                i += len;
3254f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)                pos += len;
3255f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)            } else {
3256f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)                return -1;
3257f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)            }
3258f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        }
3259f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    }
3260f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    return pos - start;
3261f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)}
3262f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
3263f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)//----------------------------------------------------------------------
3264f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
3265f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)int32_t
3266f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)SimpleDateFormat::skipRuleWhiteSpace(const UnicodeString& text, int32_t pos) const {
3267f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    while (pos < text.length()) {
3268f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        UChar32 c = text.char32At(pos);
3269f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        if (!uprv_isRuleWhiteSpace(c)) {
3270f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)            break;
3271f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        }
3272f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        pos += U16_LENGTH(c);
3273f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    }
3274f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    return pos;
3275f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)}
3276f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
3277f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)//----------------------------------------------------------------------
3278f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
3279f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)int32_t
3280f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)SimpleDateFormat::skipUWhiteSpace(const UnicodeString& text, int32_t pos) const {
3281f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    while (pos < text.length()) {
3282f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        UChar32 c = text.char32At(pos);
3283f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        if (!u_isUWhiteSpace(c)) {
3284f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)            break;
3285f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        }
3286f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        pos += U16_LENGTH(c);
3287f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    }
3288f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    return pos;
3289f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)}
3290f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
3291f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)U_NAMESPACE_END
3292f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
3293f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)#endif /* #if !UCONFIG_NO_FORMATTING */
3294f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
3295f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)//eof
3296