]> granicus.if.org Git - icu/commitdiff
ICU-9256 (J) For he@calendar=hebrew, offset the years within the current millenium...
authorPeter Edberg <pedberg@unicode.org>
Mon, 27 Aug 2012 18:29:50 +0000 (18:29 +0000)
committerPeter Edberg <pedberg@unicode.org>
Mon, 27 Aug 2012 18:29:50 +0000 (18:29 +0000)
X-SVN-Rev: 32239

icu4j/main/classes/core/src/com/ibm/icu/text/SimpleDateFormat.java
icu4j/main/tests/core/src/com/ibm/icu/dev/test/format/DateFormatTest.java

index bb428b150e50fcc8f0c9e6eff08cda58840905bd..9ae2e63a22a1bade340be4ce9597a90bfd39acd2 100644 (file)
@@ -283,6 +283,10 @@ public class SimpleDateFormat extends DateFormat {
         -1, 20, -1,  70, -1, 10, 0, 20, -1,  10, 0, -1, -1, -1, -1, -1
     };
 
+    // When calendar uses hebr numbering (i.e. he@calendar=hebrew),
+    // offset the years within the current millenium down to 1-999
+    private static final int HEBREW_CAL_CUR_MILLENIUM_START_YEAR = 5000;
+    private static final int HEBREW_CAL_CUR_MILLENIUM_END_YEAR = 6000;
 
     /**
      * The version of the serialized data on the stream.  Possible values:
@@ -1061,6 +1065,10 @@ public class SimpleDateFormat extends DateFormat {
             // else fall through to numeric year handling, do not break here 
         case 1: // 'y' - YEAR
         case 18: // 'Y' - YEAR_WOY
+            if ( override != null && (override.compareTo("hebr") == 0 || override.indexOf("y=hebr") >= 0) &&
+                    value > HEBREW_CAL_CUR_MILLENIUM_START_YEAR && value < HEBREW_CAL_CUR_MILLENIUM_END_YEAR ) {
+                value -= HEBREW_CAL_CUR_MILLENIUM_START_YEAR;
+            }
             /* According to the specification, if the number of pattern letters ('y') is 2,
              * the year is truncated to 2 digits; otherwise it is interpreted as a number.
              * But the original code process 'y', 'yy', 'yyy' in the same way. and process
@@ -2236,7 +2244,9 @@ public class SimpleDateFormat extends DateFormat {
                 // is treated literally:  "2250", "-1", "1", "002".
                 /* 'yy' is the only special case, 'y' is interpreted as number. [Richard/GCL]*/
                 /* Skip this for Chinese calendar, moved from ChineseDateFormat */
-                if (count == 2 && (pos.getIndex() - start) == 2 && !cal.getType().equals("chinese")
+                if ( override != null && (override.compareTo("hebr") == 0 || override.indexOf("y=hebr") >= 0) && value < 1000 ) {
+                    value += HEBREW_CAL_CUR_MILLENIUM_START_YEAR;
+                } else if (count == 2 && (pos.getIndex() - start) == 2 && !cal.getType().equals("chinese")
                     && UCharacter.isDigit(text.charAt(start))
                     && UCharacter.isDigit(text.charAt(start+1)))
                     {
index ec0b63c7e8485a3d269b0b30b72d0b371b5f0f15..1cbd204e0ff7b41c4e5b41851eb7d3447be7dab3 100644 (file)
@@ -3997,6 +3997,78 @@ public class DateFormatTest extends com.ibm.icu.dev.test.TestFmwk {
         }
     }
     
+    public void TestNonGregoFmtParse() {
+        class CalAndFmtTestItem {
+            public int year;
+            public int month;
+            public int day;
+            public int hour;
+            public int minute;
+            public String formattedDate;
+             // Simple constructor
+            public CalAndFmtTestItem(int yr, int mo, int da, int hr, int mi, String fd) {
+                year = yr;
+                month = mo;
+                day = da;
+                hour = hr;
+                minute = mi;
+                formattedDate = fd;
+            }
+        };
+        // test items for he@calendar=hebrew, long date format
+        final CalAndFmtTestItem[] cafti_he_hebrew_long = {
+            //                       yr  mo  da  hr  mi  formattedDate
+            new CalAndFmtTestItem( 4999, 12, 29, 12,  0, "\u05DB\u05F4\u05D8 \u05D1\u05D0\u05DC\u05D5\u05DC \u05D3\u05F3\u05EA\u05EA\u05E7\u05E6\u05F4\u05D8" ),
+            new CalAndFmtTestItem( 5100,  0,  1, 12,  0, "\u05D0\u05F3 \u05D1\u05EA\u05E9\u05E8\u05D9 \u05E7\u05F3" ),
+            new CalAndFmtTestItem( 5774,  5,  1, 12,  0, "\u05D0\u05F3 \u05D1\u05D0\u05D3\u05E8 \u05D0\u05F3 \u05EA\u05E9\u05E2\u05F4\u05D3" ),
+            new CalAndFmtTestItem( 5999, 12, 29, 12,  0, "\u05DB\u05F4\u05D8 \u05D1\u05D0\u05DC\u05D5\u05DC \u05EA\u05EA\u05E7\u05E6\u05F4\u05D8" ),
+            new CalAndFmtTestItem( 6100,  0,  1, 12,  0, "\u05D0\u05F3 \u05D1\u05EA\u05E9\u05E8\u05D9 \u05D5\u05F3\u05E7\u05F3" ),
+        };
+        class TestNonGregoItem {
+            public String locale;
+            public int style;
+            public CalAndFmtTestItem[] caftItems;
+             // Simple constructor
+            public TestNonGregoItem(String loc, int styl, CalAndFmtTestItem[] items) {
+                locale = loc;
+                style = styl;
+                caftItems = items;
+            }
+        };
+        final TestNonGregoItem[] items = {
+            new TestNonGregoItem( "he@calendar=hebrew", DateFormat.LONG, cafti_he_hebrew_long ),
+        };
+        for (TestNonGregoItem item: items) {
+            ULocale locale = new ULocale(item.locale);
+            DateFormat dfmt = DateFormat.getDateInstance(item.style, locale);
+            Calendar cal = dfmt.getCalendar();
+
+            for (CalAndFmtTestItem caftItem: item.caftItems) {
+                cal.clear();
+                cal.set(caftItem.year, caftItem.month, caftItem.day, caftItem.hour, caftItem.minute, 0);
+                StringBuffer result = new StringBuffer();
+                FieldPosition fpos = new FieldPosition(0);
+                dfmt.format(cal, result, fpos);
+                if (result.toString().compareTo(caftItem.formattedDate) != 0) {
+                    errln("FAIL: date format for locale " + item.locale +  ", style " + item.style +
+                            ", expected \"" + caftItem.formattedDate + "\", got \"" + result + "\"");
+                } else {
+                    // formatted OK, try parse
+                    ParsePosition ppos = new ParsePosition(0);
+                    dfmt.parse(result.toString(), cal, ppos);
+                    int year = cal.get(Calendar.YEAR);
+                    int month = cal.get(Calendar.MONTH);
+                    int day = cal.get(Calendar.DATE);
+                    if ( ppos.getIndex() < result.length() || year != caftItem.year || month != caftItem.month || day != caftItem.day) {
+                        errln("FAIL: date parse for locale " + item.locale +  ", style " + item.style +
+                                ", string \"" + result + "\", expected " + caftItem.year+"-"+caftItem.month+"-"+caftItem.day +
+                                ", got pos " + ppos.getIndex() + " "+year+"-"+month+"-"+day );
+                    }
+                }
+            }
+        }
+    }
+
     public void TestTwoDigitWOY() { // See ICU Ticket #8514
         String dateText = new String("98MON01");
         
@@ -4062,9 +4134,9 @@ public class DateFormatTest extends com.ibm.icu.dev.test.TestFmwk {
             StringBuffer result1 = new StringBuffer();
             FieldPosition fpos1 = new FieldPosition(0);
             sdfmt.format(cal, contextValues, result1, fpos1);
-                       if (result1.toString().compareTo(item.expectedFormat) != 0) {
-                               errln("FAIL: format (per-call context) for locale " + item.locale +  ", capitalizationContext " + item.capitalizationContext +
-                                               ", expected \"" + item.expectedFormat + "\", got \"" + result1 + "\"");
+            if (result1.toString().compareTo(item.expectedFormat) != 0) {
+                errln("FAIL: format (per-call context) for locale " + item.locale +  ", capitalizationContext " + item.capitalizationContext +
+                        ", expected \"" + item.expectedFormat + "\", got \"" + result1 + "\"");
             }
 
             // now try setting default context & standard format call
@@ -4072,16 +4144,16 @@ public class DateFormatTest extends com.ibm.icu.dev.test.TestFmwk {
             StringBuffer result2 = new StringBuffer();
             FieldPosition fpos2 = new FieldPosition(0);
             sdfmt.format(cal, result2, fpos2);
-                       if (result2.toString().compareTo(item.expectedFormat) != 0) {
-                               errln("FAIL: format (default context) for locale " + item.locale +  ", capitalizationContext " + item.capitalizationContext +
-                                               ", expected \"" + item.expectedFormat + "\", got \"" + result2 + "\"");
+            if (result2.toString().compareTo(item.expectedFormat) != 0) {
+                errln("FAIL: format (default context) for locale " + item.locale +  ", capitalizationContext " + item.capitalizationContext +
+                        ", expected \"" + item.expectedFormat + "\", got \"" + result2 + "\"");
             }
 
             // now read back default context, make sure it is what we set
             SimpleDateFormat.ContextValue capitalizationContext = sdfmt.getDefaultContext(SimpleDateFormat.ContextType.CAPITALIZATION);
             if (capitalizationContext != item.capitalizationContext) {
-                               errln("FAIL: getDefaultContext for locale " + item.locale +  ", capitalizationContext " + item.capitalizationContext +
-                                               ", but got context " + capitalizationContext);
+                errln("FAIL: getDefaultContext for locale " + item.locale +  ", capitalizationContext " + item.capitalizationContext +
+                        ", but got context " + capitalizationContext);
             }
         }
     }