From: Peter Edberg Date: Tue, 16 Oct 2012 06:57:48 +0000 (+0000) Subject: ICU-9656 (J) Change RelativeDateFormat to keep 2 patterns (not formatters), and for... X-Git-Tag: milestone-59-0-1~3409 X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=5eb6e0c01c4289717c657e2b36474d58d882d570;p=icu ICU-9656 (J) Change RelativeDateFormat to keep 2 patterns (not formatters), and for fmt glue them (with substitutions) and apply to single formatter X-SVN-Rev: 32641 --- diff --git a/icu4j/main/classes/core/src/com/ibm/icu/impl/RelativeDateFormat.java b/icu4j/main/classes/core/src/com/ibm/icu/impl/RelativeDateFormat.java index 2d7baf5ccd8..72dfeb98198 100644 --- a/icu4j/main/classes/core/src/com/ibm/icu/impl/RelativeDateFormat.java +++ b/icu4j/main/classes/core/src/com/ibm/icu/impl/RelativeDateFormat.java @@ -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; diff --git a/icu4j/main/shared/data/testdata.jar b/icu4j/main/shared/data/testdata.jar index 0884fb4d7d6..b91cfd904ce 100755 --- a/icu4j/main/shared/data/testdata.jar +++ b/icu4j/main/shared/data/testdata.jar @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:dd3d0c8605fa6c0d04086fbdbaf8392f13a37e07c5d8f1f0d90e4e9df567c04e -size 722457 +oid sha256:96ceef2e7397c583c580cc63c5c428a74cee3dd0c87fff95a8eea2fbe9559b8d +size 723668 diff --git a/icu4j/main/tests/core/src/com/ibm/icu/dev/test/format/DataDrivenFormatTest.java b/icu4j/main/tests/core/src/com/ibm/icu/dev/test/format/DataDrivenFormatTest.java index ffc2e37b90c..e42d88d1588 100644 --- a/icu4j/main/tests/core/src/com/ibm/icu/dev/test/format/DataDrivenFormatTest.java +++ b/icu4j/main/tests/core/src/com/ibm/icu/dev/test/format/DataDrivenFormatTest.java @@ -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