]> granicus.if.org Git - icu/commitdiff
ICU-9656 (J) Change RelativeDateFormat to keep 2 patterns (not formatters), and for...
authorPeter Edberg <pedberg@unicode.org>
Tue, 16 Oct 2012 06:57:48 +0000 (06:57 +0000)
committerPeter Edberg <pedberg@unicode.org>
Tue, 16 Oct 2012 06:57:48 +0000 (06:57 +0000)
X-SVN-Rev: 32641

icu4j/main/classes/core/src/com/ibm/icu/impl/RelativeDateFormat.java
icu4j/main/shared/data/testdata.jar
icu4j/main/tests/core/src/com/ibm/icu/dev/test/format/DataDrivenFormatTest.java

index 2d7baf5ccd8f568015517210ee5cd6aafb14e526..72dfeb981986660082e3d1b88ab11ccb90d369f8 100644 (file)
@@ -1,6 +1,6 @@
 /*
  *******************************************************************************
- * Copyright (C) 2007-2011, International Business Machines Corporation and    *
+ * Copyright (C) 2007-2012, International Business Machines Corporation and    *
  * others. All Rights Reserved.                                                *
  *******************************************************************************
  */
@@ -16,6 +16,7 @@ import java.util.TreeSet;
 
 import com.ibm.icu.text.DateFormat;
 import com.ibm.icu.text.MessageFormat;
+import com.ibm.icu.text.SimpleDateFormat;
 import com.ibm.icu.util.Calendar;
 import com.ibm.icu.util.TimeZone;
 import com.ibm.icu.util.ULocale;
@@ -55,18 +56,33 @@ public class RelativeDateFormat extends DateFormat {
         fLocale = locale;
         fTimeStyle = timeStyle;
         fDateStyle = dateStyle;
-        
-        if(fDateStyle != DateFormat.NONE) {
+
+        if (fDateStyle != DateFormat.NONE) {
             int newStyle = fDateStyle & ~DateFormat.RELATIVE;
-            fDateFormat = DateFormat.getDateInstance(newStyle, locale);
+            DateFormat df = DateFormat.getDateInstance(newStyle, locale);
+            if (df instanceof SimpleDateFormat) {
+                fDateTimeFormat = (SimpleDateFormat)df;
+            } else {
+                throw new IllegalArgumentException("Can't create SimpleDateFormat for date style");
+            }
+            fDatePattern = fDateTimeFormat.toPattern();
+            if (fTimeStyle != DateFormat.NONE) {
+                newStyle = fTimeStyle & ~DateFormat.RELATIVE;
+                df = DateFormat.getTimeInstance(newStyle, locale);
+                if (df instanceof SimpleDateFormat) {
+                    fTimePattern = ((SimpleDateFormat)df).toPattern();
+                }
+            }
         } else {
-            fDateFormat = null;
-        }
-        if(fTimeStyle != DateFormat.NONE) {
+            // does not matter whether timeStyle is UDAT_NONE, we need something for fDateTimeFormat
             int newStyle = fTimeStyle & ~DateFormat.RELATIVE;
-            fTimeFormat = DateFormat.getTimeInstance(newStyle, locale);
-        } else {
-            fTimeFormat = null;
+            DateFormat df = DateFormat.getTimeInstance(newStyle, locale);
+            if (df instanceof SimpleDateFormat) {
+                fDateTimeFormat = (SimpleDateFormat)df;
+            } else {
+                throw new IllegalArgumentException("Can't create SimpleDateFormat for time style");
+            }
+            fTimePattern = fDateTimeFormat.toPattern();
         }
 
         initializeCalendar(null, fLocale);
@@ -85,38 +101,50 @@ public class RelativeDateFormat extends DateFormat {
     public StringBuffer format(Calendar cal, StringBuffer toAppendTo,
             FieldPosition fieldPosition) {
 
-        String dayString = null;
+        String relativeDayString = null;
         if (fDateStyle != DateFormat.NONE) {
             // calculate the difference, in days, between 'cal' and now.
             int dayDiff = dayDifference(cal);
 
             // look up string
-            dayString = getStringForDay(dayDiff);
+            relativeDayString = getStringForDay(dayDiff);
         }
-        if (fTimeStyle == DateFormat.NONE) {
-            if (dayString != null) {
-                toAppendTo.append(dayString);
-            } else if (fDateStyle != DateFormat.NONE) {
-                fDateFormat.format(cal, toAppendTo, fieldPosition);
-            }
-        } else {
-            if (dayString == null && fDateStyle != DateFormat.NONE) {
-                dayString = fDateFormat.format(cal, new StringBuffer(), fieldPosition).toString();
+
+        if (fDateTimeFormat != null && (fDatePattern != null || fTimePattern != null)) {
+            // The new way
+            if (fDatePattern == null) {
+                // must have fTimePattern
+                fDateTimeFormat.applyPattern(fTimePattern);
+                fDateTimeFormat.format(cal, toAppendTo, fieldPosition);
+            } else if (fTimePattern == null) {
+                // must have fDatePattern
+                if (relativeDayString != null) {
+                    toAppendTo.append(relativeDayString);
+                } else {
+                    fDateTimeFormat.applyPattern(fDatePattern);
+                    fDateTimeFormat.format(cal, toAppendTo, fieldPosition);
+                }
+            } else {
+                String datePattern = fDatePattern; // default;
+                if (relativeDayString != null) {
+                    // Need to quote the relativeDayString to make it a legal date pattern
+                    datePattern = "'" + relativeDayString.replace("'", "''") + "'";
+                }
+                StringBuffer combinedPattern = new StringBuffer("");
+                fCombinedFormat.format(new Object[] {fTimePattern, datePattern}, combinedPattern, new FieldPosition(0));
+                fDateTimeFormat.applyPattern(combinedPattern.toString());
+                fDateTimeFormat.format(cal, toAppendTo, fieldPosition);
             }
-            FieldPosition timePos = new FieldPosition(fieldPosition.getField());
-            String timeString = fTimeFormat.format(cal, new StringBuffer(), timePos).toString();
-            fCombinedFormat.format(new Object[] {dayString, timeString}, toAppendTo, new FieldPosition(0));
-            int offset;
-            if (fieldPosition.getEndIndex() > 0 && (offset = toAppendTo.toString().indexOf(dayString)) >= 0 ) {
-                // fieldPosition.getField() was found in dayString, offset start & end based on final position of dayString
-                fieldPosition.setBeginIndex( fieldPosition.getBeginIndex() + offset );
-                fieldPosition.setEndIndex( fieldPosition.getEndIndex() + offset );
-            } else if (timePos.getEndIndex() > 0 && (offset = toAppendTo.toString().indexOf(timeString)) >= 0) {
-                // fieldPosition.getField() was found in timeString, offset start & end based on final position of timeString
-                fieldPosition.setBeginIndex( timePos.getBeginIndex() + offset );
-                fieldPosition.setEndIndex( timePos.getEndIndex() + offset );
+        } else if (fDateFormat != null) {
+            // A subset of the old way, for serialization compatibility
+            // (just do the date part)
+            if (relativeDayString != null) {
+                toAppendTo.append(relativeDayString);
+            } else {
+                fDateFormat.format(cal, toAppendTo, fieldPosition);
             }
         }
+
         return toAppendTo;
     }
 
@@ -127,9 +155,12 @@ public class RelativeDateFormat extends DateFormat {
         throw new UnsupportedOperationException("Relative Date parse is not implemented yet");
     }
 
-    private DateFormat fDateFormat; // the held date format
-    private DateFormat fTimeFormat; // the held time format
+    private DateFormat fDateFormat; // now unused, keep for serialization compatibility
+    private DateFormat fTimeFormat; // now unused, keep for serialization compatibility
     private MessageFormat fCombinedFormat; //  the {0} {1} format. 
+    private SimpleDateFormat fDateTimeFormat = null; // the held date/time formatter
+    private String fDatePattern = null;
+    private String fTimePattern = null;
 
     int fDateStyle;
     int fTimeStyle;
index 0884fb4d7d6859f38655fad7af3355033fb3a867..b91cfd904ced5f6df4e4e80522524f084c7064de 100755 (executable)
@@ -1,3 +1,3 @@
 version https://git-lfs.github.com/spec/v1
-oid sha256:dd3d0c8605fa6c0d04086fbdbaf8392f13a37e07c5d8f1f0d90e4e9df567c04e
-size 722457
+oid sha256:96ceef2e7397c583c580cc63c5c428a74cee3dd0c87fff95a8eea2fbe9559b8d
+size 723668
index ffc2e37b90cdd8554f5c98d4fe0fd1a111dddd02..e42d88d1588a0bfd4e7429f0a1c3501888e26775 100644 (file)
@@ -1,6 +1,6 @@
 /*
  *******************************************************************************
- * Copyright (C) 2007-2008, International Business Machines Corporation and         *
+ * Copyright (C) 2007-2012, International Business Machines Corporation and         *
  * others. All Rights Reserved.                                                *
  *******************************************************************************
  */
@@ -19,6 +19,7 @@ import com.ibm.icu.dev.test.util.DateTimeStyleSet;
 import com.ibm.icu.text.DateFormat;
 import com.ibm.icu.text.SimpleDateFormat;
 import com.ibm.icu.util.Calendar;
+import com.ibm.icu.util.TimeZone;
 import com.ibm.icu.util.ULocale;
 
 /**
@@ -80,6 +81,7 @@ public class DataDrivenFormatTest extends ModuleTest {
             String caseString = "["+testData.getName()+"#"+n+(fmt?"format":"parse")+"]";
             
             String locale = currentCase.getString("locale");
+            String zone = currentCase.getString("zone");
             String spec = currentCase.getString("spec");
             String date = currentCase.getString("date");
             String str = currentCase.getString("str");
@@ -106,6 +108,12 @@ public class DataDrivenFormatTest extends ModuleTest {
             }
 
             Calendar cal = Calendar.getInstance(loc);
+
+            if (zone.length() > 0) {
+                TimeZone tz = TimeZone.getFrozenTimeZone(zone);
+                cal.setTimeZone(tz);
+                format.setTimeZone(tz);
+            }
             
             // parse 'date' - either 'MILLIS=12345' or  a CalendarFieldsSet
             if(date.startsWith(kMILLIS)) {
@@ -125,7 +133,11 @@ public class DataDrivenFormatTest extends ModuleTest {
                 /// perform op on 'to calendar'
                 for (int q=0; q<addSet.fieldCount(); q++) {
                     if (addSet.isSet(q)) {
-                         cal.add(q,addSet.get(q));
+                        if (q == Calendar.DATE) {
+                            cal.add(q,addSet.get(q));
+                        } else {
+                            cal.set(q,addSet.get(q));
+                        }
                     }
                 }