ICU-7074 merge r26770 hebrew

X-SVN-Rev: 26771
diff --git a/source/i18n/smpdtfmt.cpp b/source/i18n/smpdtfmt.cpp
index c88638f..6772969 100644
--- a/source/i18n/smpdtfmt.cpp
+++ b/source/i18n/smpdtfmt.cpp
@@ -1785,6 +1785,7 @@
     int32_t start = pos;
 
     UBool ambiguousYear[] = { FALSE };
+    int32_t saveHebrewMonth = -1;
     int32_t count = 0;
 
     // hack, reset tztype, cast away const
@@ -1888,7 +1889,7 @@
                 }
 
                 pos = subParse(text, pos, ch, count,
-                               TRUE, FALSE, ambiguousYear, *workCal, i);
+                               TRUE, FALSE, ambiguousYear, saveHebrewMonth, *workCal, i);
 
                 // If the parse fails anywhere in the run, back up to the
                 // start of the run and retry.
@@ -1903,7 +1904,7 @@
             // fields.
             else {
                 int32_t s = subParse(text, pos, ch, count,
-                               FALSE, TRUE, ambiguousYear, *workCal, i);
+                               FALSE, TRUE, ambiguousYear, saveHebrewMonth, *workCal, i);
 
                 if (s < 0) {
                     status = U_PARSE_ERROR;
@@ -2347,7 +2348,7 @@
  * indicating matching failure, otherwise.
  */
 int32_t SimpleDateFormat::subParse(const UnicodeString& text, int32_t& start, UChar ch, int32_t count,
-                           UBool obeyCount, UBool allowNegative, UBool ambiguousYear[], Calendar& cal,
+                           UBool obeyCount, UBool allowNegative, UBool ambiguousYear[], int32_t& saveHebrewMonth, Calendar& cal,
                            int32_t patLoc) const
 {
     Formattable number;
@@ -2357,7 +2358,6 @@
     UDateFormatField patternCharIndex;
     NumberFormat *currentNumberFormat;
     UnicodeString temp;
-    static UBool DelayedHebrewMonthCheck = FALSE;
     UChar *patternCharPtr = u_strchr(DateFormatSymbols::getPatternUChars(), ch);
 
 #if defined (U_DEBUG_CAL)
@@ -2479,13 +2479,14 @@
         cal.set(UCAL_YEAR, value);
 
         // Delayed checking for adjustment of Hebrew month numbers in non-leap years.  
-        if (DelayedHebrewMonthCheck) {
+        if (saveHebrewMonth >= 0) {
             HebrewCalendar *hc = (HebrewCalendar*)&cal;
-            UErrorCode status = U_ZERO_ERROR;
-            if (!hc->isLeapYear(value)) {
-               cal.add(UCAL_MONTH,1,status);
+            if (!hc->isLeapYear(value) && saveHebrewMonth >= 6) {
+               cal.set(UCAL_MONTH,saveHebrewMonth);
+            } else {
+               cal.set(UCAL_MONTH,saveHebrewMonth-1);
             }
-            DelayedHebrewMonthCheck = FALSE;
+            saveHebrewMonth = -1;
         }
         return pos.getIndex();
 
@@ -2507,23 +2508,26 @@
     case UDAT_MONTH_FIELD:
         if (count <= 2) // i.e., M or MM.
         {
-            // Don't want to parse the month if it is a string
-            // while pattern uses numeric style: M or MM.
-            // [We computed 'value' above.]
-            cal.set(UCAL_MONTH, value - 1);
             // When parsing month numbers from the Hebrew Calendar, we might need to adjust the month depending on whether
             // 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
             // the year is parsed.
-            if (!strcmp(cal.getType(),"hebrew") && value >= 6) {
+            if (!strcmp(cal.getType(),"hebrew")) {
                 HebrewCalendar *hc = (HebrewCalendar*)&cal;
                 if (cal.isSet(UCAL_YEAR)) {
                    UErrorCode status = U_ZERO_ERROR;
-                   if (!hc->isLeapYear(hc->get(UCAL_YEAR,status))) {
+                   if (!hc->isLeapYear(hc->get(UCAL_YEAR,status)) && value >= 6) {
                        cal.set(UCAL_MONTH, value);
+                   } else {
+                       cal.set(UCAL_MONTH, value - 1);
                    }
                 } else {
-                    DelayedHebrewMonthCheck = TRUE;
+                    saveHebrewMonth = value;
                 } 
+            } else {
+                // Don't want to parse the month if it is a string
+                // while pattern uses numeric style: M or MM.
+                // [We computed 'value' above.]
+                cal.set(UCAL_MONTH, value - 1);
             }
             return pos.getIndex();
         } else {
diff --git a/source/i18n/unicode/smpdtfmt.h b/source/i18n/unicode/smpdtfmt.h
index 2fed42d..6abb1be 100644
--- a/source/i18n/unicode/smpdtfmt.h
+++ b/source/i18n/unicode/smpdtfmt.h
@@ -846,13 +846,14 @@
      * @param count the count of a pattern character.
      * @param obeyCount if true then the count is strictly obeyed.
      * @param ambiguousYear If true then the two-digit year == the default start year.
+     * @param saveHebrewMonth Used to hang onto month until year is known.
      * @param cal a Calendar set to the date and time to be formatted
      *            into a date/time string.
      * @return the new start position if matching succeeded; a negative number
      * indicating matching failure, otherwise.
      */
     int32_t subParse(const UnicodeString& text, int32_t& start, UChar ch, int32_t count,
-                     UBool obeyCount, UBool allowNegative, UBool ambiguousYear[], Calendar& cal,
+                     UBool obeyCount, UBool allowNegative, UBool ambiguousYear[], int32_t& saveHebrewMonth, Calendar& cal,
                      int32_t patLoc) const;
 
     void parseInt(const UnicodeString& text,