ICU-10103 Merging all maint-50 changes up to 50.1.1 (r32977) and the latest tzdata (2013b) + necessary test code patch (r33396) to eclpse-icu50 stream.

X-SVN-Rev: 33525
This commit is contained in:
Yoshito Umaoka 2013-04-13 03:56:55 +00:00
parent 0403e5f47c
commit 8364ea737b
21 changed files with 318 additions and 108 deletions

View file

@ -4,6 +4,6 @@
#*******************************************************************************
api.report.version = 50
api.report.prev.version = 49
release.file.ver = 50_1
release.file.ver = 50_1_1
api.doc.version = 50

View file

@ -1,8 +1,8 @@
#*******************************************************************************
#* Copyright (C) 2010-2012, International Business Machines Corporation and *
#* Copyright (C) 2010-2013, International Business Machines Corporation and *
#* others. All Rights Reserved. *
#*******************************************************************************
icu4j.plugin.impl.version.string=50.1.0
icu4j.plugin.impl.version.string=50.1.1
copyright.eclipse=Licensed Materials - Property of IBM \n (C) Copyright IBM Corp. 2000, 2012. All Rights Reserved. \n IBM is a registered trademark of IBM Corp.
icu4j.data.version.number=50
icu4j.eclipse.build.version.string=50.1.0.v20121116
icu4j.eclipse.build.version.string=50.1.1.v20130412

View file

@ -8,7 +8,7 @@
<body lang="EN-US">
<h2>About This Content</h2>
<p>November 16, 2012</p>
<p>April 12, 2013</p>
<h3>License</h3>
<p>The Eclipse Foundation makes available all content in this plug-in (&quot;Content&quot;). Unless otherwise
@ -31,13 +31,13 @@ and such source code may be obtained at <a href="http://www.eclipse.org/">http:/
for informational purposes only, and you should look to the Redistributor's license for
terms and conditions of use.</p>
<p><strong>ICU4J 50.1.0.v20121116 plug-in</strong> <br/><br/>
<p><strong>ICU4J 50.1.1.v20130412 plug-in</strong> <br/><br/>
The plug-in includes software (&quot;ICU4J&quot;) developed by International Business Machines
Corporation and others.
<br/><br/>
ICU4J is:
<blockquote>
Copyright (c) 1995-2012 International Business Machines Corporation and others<br/>
Copyright (c) 1995-2013 International Business Machines Corporation and others<br/>
All rights reserved.
</blockquote>
<p>

View file

@ -8,7 +8,7 @@
<body lang="EN-US">
<h2>About This Content</h2>
<p>November 16, 2012</p>
<p>April 12, 2013</p>
<h3>License</h3>
<p>The Eclipse Foundation makes available all content in this plug-in (&quot;Content&quot;). Unless otherwise
@ -31,13 +31,13 @@ and such source code may be obtained at <a href="http://www.eclipse.org/">http:/
for informational purposes only, and you should look to the Redistributor's license for
terms and conditions of use.</p>
<p><strong>ICU4J 50.1.0.v20121116 base plug-in</strong> <br/><br/>
<p><strong>ICU4J 50.1.1.v20130412 base plug-in</strong> <br/><br/>
The plug-in includes software (&quot;ICU4J&quot;) developed by International Business Machines
Corporation and others.
<br/><br/>
ICU4J is:
<blockquote>
Copyright (c) 1995-2012 International Business Machines Corporation and others<br/>
Copyright (c) 1995-2013 International Business Machines Corporation and others<br/>
All rights reserved.
</blockquote>
<p>

View file

@ -277,7 +277,8 @@ public class FilteredNormalizer2 extends Normalizer2 {
norm2.append(first, prefix);
}
} else {
StringBuilder middle=new StringBuilder(first.subSequence(suffixStart, 0x7fffffff));
StringBuilder middle=new StringBuilder(
first.subSequence(suffixStart, first.length()));
if(doNormalize) {
norm2.normalizeSecondAndAppend(middle, prefix);
} else {
@ -287,7 +288,7 @@ public class FilteredNormalizer2 extends Normalizer2 {
}
}
if(prefixLimit<second.length()) {
CharSequence rest=second.subSequence(prefixLimit, 0x7fffffff);
CharSequence rest=second.subSequence(prefixLimit, second.length());
if(doNormalize) {
normalize(rest, first, UnicodeSet.SpanCondition.NOT_CONTAINED);
} else {

View file

@ -1640,33 +1640,9 @@ public class SimpleDateFormat extends DateFormat {
} else {
// Handle literal pattern text literal
numericFieldStart = -1;
String patl = (String)items[i];
int plen = patl.length();
int tlen = text.length();
int idx = 0;
while (idx < plen && pos < tlen) {
char pch = patl.charAt(idx);
char ich = text.charAt(pos);
if (PatternProps.isWhiteSpace(pch)
&& PatternProps.isWhiteSpace(ich)) {
// White space characters found in both patten and input.
// Skip contiguous white spaces.
while ((idx + 1) < plen &&
PatternProps.isWhiteSpace(patl.charAt(idx + 1))) {
++idx;
}
while ((pos + 1) < tlen &&
PatternProps.isWhiteSpace(text.charAt(pos + 1))) {
++pos;
}
} else if (pch != ich) {
break;
}
++idx;
++pos;
}
if (idx != plen) {
boolean[] complete = new boolean[1];
pos = matchLiteral(text, pos, items, i, complete);
if (!complete[0]) {
// Set the position of mismatch
parsePos.setIndex(start);
parsePos.setErrorIndex(pos);
@ -1678,6 +1654,18 @@ public class SimpleDateFormat extends DateFormat {
}
++i;
}
// Special hack for trailing "." after non-numeric field.
if (pos < text.length()) {
char extra = text.charAt(pos);
if (extra == '.' && isLenient() && items.length != 0) {
// only do if the last field is not numeric
Object lastItem = items[items.length - 1];
if (lastItem instanceof PatternItem && !((PatternItem)lastItem).isNumeric) {
pos++; // skip the extra "."
}
}
}
// At this point the fields of Calendar have been set. Calendar
// will fill in default values for missing fields when the time
@ -1854,6 +1842,88 @@ public class SimpleDateFormat extends DateFormat {
}
}
/**
* Matches text (starting at pos) with patl. Returns the new pos, and sets complete[0]
* if it matched the entire text. Whitespace sequences are treated as singletons.
* <p>If isLenient and if we fail to match the first time, some special hacks are put into place.
* <ul><li>we are between date and time fields, then one or more whitespace characters
* in the text are accepted instead.</li>
* <ul><li>we are after a non-numeric field, and the text starts with a ".", we skip it.</li>
* </ul>
* @param text
* @param pos
* @param patternLiteral
* @param complete
* @return
*/
private int matchLiteral(String text, int pos, Object[] items, int itemIndex, boolean[] complete) {
int originalPos = pos;
String patternLiteral = (String)items[itemIndex];
int plen = patternLiteral.length();
int tlen = text.length();
int idx = 0;
while (idx < plen && pos < tlen) {
char pch = patternLiteral.charAt(idx);
char ich = text.charAt(pos);
if (PatternProps.isWhiteSpace(pch)
&& PatternProps.isWhiteSpace(ich)) {
// White space characters found in both patten and input.
// Skip contiguous white spaces.
while ((idx + 1) < plen &&
PatternProps.isWhiteSpace(patternLiteral.charAt(idx + 1))) {
++idx;
}
while ((pos + 1) < tlen &&
PatternProps.isWhiteSpace(text.charAt(pos + 1))) {
++pos;
}
} else if (pch != ich) {
if (ich == '.' && pos == originalPos && 0 < itemIndex && isLenient()) {
Object before = items[itemIndex-1];
if (before instanceof PatternItem) {
boolean isNumeric = ((PatternItem) before).isNumeric;
if (!isNumeric) {
++pos; // just update pos
continue;
}
}
}
break;
}
++idx;
++pos;
}
complete[0] = idx == plen;
if (complete[0] == false && isLenient() && 0 < itemIndex && itemIndex < items.length - 1) {
// If fully lenient, accept " "* for any text between a date and a time field
// We don't go more lenient, because we don't want to accept "12/31" for "12:31".
// People may be trying to parse for a date, then for a time.
if (originalPos < tlen) {
Object before = items[itemIndex-1];
Object after = items[itemIndex+1];
if (before instanceof PatternItem && after instanceof PatternItem) {
char beforeType = ((PatternItem) before).type;
char afterType = ((PatternItem) after).type;
if (DATE_PATTERN_TYPE.contains(beforeType) != DATE_PATTERN_TYPE.contains(afterType)) {
int newPos = originalPos;
while (true) {
char ich = text.charAt(newPos);
if (!PatternProps.isWhiteSpace(ich)) {
break;
}
++newPos;
}
complete[0] = newPos > originalPos;
pos = newPos;
}
}
}
}
return pos;
}
static final UnicodeSet DATE_PATTERN_TYPE = new UnicodeSet("[GyYuUQqMLlwWd]").freeze();
/**
* Attempt to match the text at a given position against an array of
* strings. Since multiple strings in the array may match (for
@ -1910,6 +1980,7 @@ public class SimpleDateFormat extends DateFormat {
// unfortunately requires us to test all array elements.
int bestMatchLength = 0, bestMatch = -1;
int isLeapMonth = 0;
int matchLength = 0;
for (; i<count; ++i)
{
@ -1917,20 +1988,20 @@ public class SimpleDateFormat extends DateFormat {
// Always compare if we have no match yet; otherwise only compare
// against potentially better matches (longer strings).
if (length > bestMatchLength &&
text.regionMatches(true, start, data[i], 0, length))
(matchLength = regionMatchesWithOptionalDot(text, start, data[i], length)) >= 0)
{
bestMatch = i;
bestMatchLength = length;
bestMatchLength = matchLength;
isLeapMonth = 0;
}
if (monthPattern != null) {
String leapMonthName = MessageFormat.format(monthPattern, data[i]);
length = leapMonthName.length();
if (length > bestMatchLength &&
text.regionMatches(true, start, leapMonthName, 0, length))
(matchLength = regionMatchesWithOptionalDot(text, start, leapMonthName, length)) >= 0)
{
bestMatch = i;
bestMatchLength = length;
bestMatchLength = matchLength;
isLeapMonth = 1;
}
}
@ -1949,6 +2020,19 @@ public class SimpleDateFormat extends DateFormat {
return -start;
}
private int regionMatchesWithOptionalDot(String text, int start, String data, int length) {
boolean matches = text.regionMatches(true, start, data, 0, length);
if (matches) {
return length;
}
if (data.length() > 0 && data.charAt(data.length()-1) == '.') {
if (text.regionMatches(true, start, data, 0, length-1)) {
return length - 1;
}
}
return -1;
}
/**
* Attempt to match the text at a given position against an array of quarter
* strings. Since multiple strings in the array may match (for
@ -1976,14 +2060,16 @@ public class SimpleDateFormat extends DateFormat {
// We keep track of the longest match, and return that. Note that this
// unfortunately requires us to test all array elements.
int bestMatchLength = 0, bestMatch = -1;
int matchLength = 0;
for (; i<count; ++i) {
int length = data[i].length();
// Always compare if we have no match yet; otherwise only compare
// against potentially better matches (longer strings).
if (length > bestMatchLength &&
text.regionMatches(true, start, data[i], 0, length)) {
(matchLength = regionMatchesWithOptionalDot(text, start, data[i], length)) >= 0) {
bestMatch = i;
bestMatchLength = length;
bestMatchLength = matchLength;
}
}

View file

@ -29,6 +29,7 @@ import com.ibm.icu.text.CurrencyDisplayNames;
import com.ibm.icu.text.CurrencyMetaInfo;
import com.ibm.icu.text.CurrencyMetaInfo.CurrencyDigits;
import com.ibm.icu.text.CurrencyMetaInfo.CurrencyFilter;
import com.ibm.icu.text.CurrencyMetaInfo.CurrencyInfo;
import com.ibm.icu.util.ULocale.Category;
/**
@ -159,9 +160,8 @@ public class Currency extends MeasureUnit implements Serializable {
* @stable ICU 4.0
*/
public static String[] getAvailableCurrencyCodes(ULocale loc, Date d) {
CurrencyMetaInfo info = CurrencyMetaInfo.getInstance();
CurrencyFilter filter = CurrencyFilter.onDate(d).withRegion(loc.getCountry());
List<String> list = info.currencies(filter);
List<String> list = getTenderCurrencies(filter);
// Note: Prior to 4.4 the spec didn't say that we return null if there are no results, but
// the test assumed it did. Kept the behavior and amended the spec.
if (list.isEmpty()) {
@ -356,7 +356,6 @@ public class Currency extends MeasureUnit implements Serializable {
return EMPTY_STRING_ARRAY;
}
CurrencyMetaInfo info = CurrencyMetaInfo.getInstance();
if (!commonlyUsed) {
// Behavior change from 4.3.3, no longer sort the currencies
return getAvailableCurrencyCodes().toArray(new String[0]);
@ -377,7 +376,7 @@ public class Currency extends MeasureUnit implements Serializable {
// currencies are in region's preferred order when we're filtering on region, which
// matches our spec
List<String> result = info.currencies(filter);
List<String> result = getTenderCurrencies(filter);
// No fallback anymore (change from 4.3.3)
if (result.size() == 0) {
@ -836,16 +835,16 @@ public class Currency extends MeasureUnit implements Serializable {
private static SoftReference<List<String>> ALL_CODES;
/*
* Returns an unmodifiable String list including all known currency codes
* Returns an unmodifiable String list including all known tender currency codes.
*/
private static synchronized List<String> getAvailableCurrencyCodes() {
List<String> all = (ALL_CODES == null) ? null : ALL_CODES.get();
if (all == null) {
CurrencyMetaInfo info = CurrencyMetaInfo.getInstance();
// Filter out non-tender currencies which have "from" date set to 9999-12-31
// CurrencyFilter has "to" value set to 9998-12-31 in order to exclude them
CurrencyFilter filter = CurrencyFilter.onDateRange(null, new Date(253373299200000L));
all = Collections.unmodifiableList(info.currencies(filter));
//CurrencyFilter filter = CurrencyFilter.onDateRange(null, new Date(253373299200000L));
CurrencyFilter filter = CurrencyFilter.all();
all = Collections.unmodifiableList(getTenderCurrencies(filter));
ALL_CODES = new SoftReference<List<String>>(all);
}
return all;
@ -894,5 +893,24 @@ public class Currency extends MeasureUnit implements Serializable {
List<String> allActive = info.currencies(CurrencyFilter.onDateRange(from, to));
return allActive.contains(code);
}
/**
* Returns the list of remaining tender currencies after a filter is applied.
* @param filter the filter to apply to the tender currencies
* @return a list of tender currencies
*/
private static List<String> getTenderCurrencies(CurrencyFilter filter) {
CurrencyMetaInfo info = CurrencyMetaInfo.getInstance();
List<CurrencyInfo> infoList = info.currencyInfo(filter);
List<String> list = new ArrayList<String>();
for (CurrencyInfo currencyInfo : infoList) {
// Non-tender currencies always have a from of MIN_VALUE and a to of MAX_VALUE, so
// exclude them.
if (currencyInfo.from != Long.MIN_VALUE || currencyInfo.to != Long.MAX_VALUE) {
list.add(currencyInfo.code);
}
}
return list;
}
}
//eof

View file

@ -45,13 +45,14 @@ public final class LocaleData {
/**
* EXType for {@link #getExemplarSet(int, int)}.
* @stable ICU 3.4
* @stable ICU 4.4
*/
public static final int ES_INDEX = 2;
/**
* EXType for {@link #getExemplarSet(int, int)}.
* @stable ICU 3.4
* Note: This type is no longer supported.
* @stable ICU 4.4
*/
public static final int ES_CURRENCY = 3;
@ -156,7 +157,7 @@ public final class LocaleData {
* IGNORE_SPACE bit is always set, regardless of the
* value of 'options'.
* @param extype The type of exemplar set to be retrieved,
* ES_STANDARD, ES_INDEX, ES_CURRENCY, or ES_AUXILIARY
* ES_STANDARD, ES_INDEX, ES_AUXILIARY, or ES_PUNCTUATION
* @return The set of exemplar characters for the given locale.
* @stable ICU 3.4
*/
@ -167,6 +168,11 @@ public final class LocaleData {
"ExemplarCharactersPunctuation"
};
if (extype == ES_CURRENCY) {
// currency symbol exemplar is no longer available
return new UnicodeSet();
}
try{
ICUResourceBundle stringBundle = (ICUResourceBundle) bundle.get(exemplarSetTypes[extype]);
@ -195,7 +201,7 @@ public final class LocaleData {
}
}
static final Pattern US_SYNTAX = Pattern.compile(" ([\\-\\&\\{\\}\\[\\]])");
static final Pattern US_SYNTAX = Pattern.compile(" ([\\-\\&\\{\\}\\[\\]\\\\])");
/**
* Gets the LocaleData object associated with the ULocale specified in locale

View file

@ -502,8 +502,8 @@ public final class VersionInfo implements Comparable<VersionInfo>
UNICODE_6_1 = getInstance(6, 1, 0, 0);
UNICODE_6_2 = getInstance(6, 2, 0, 0);
ICU_VERSION = getInstance(50, 1, 0, 0);
ICU_DATA_VERSION = getInstance(50, 1, 0, 0);
ICU_VERSION = getInstance(50, 1, 1, 0);
ICU_DATA_VERSION = getInstance(50, 1, 1, 0);
UNICODE_VERSION = UNICODE_6_2;
UCOL_RUNTIME_VERSION = getInstance(7);

View file

@ -147,30 +147,7 @@ public class ICUCurrencyMetaInfo extends CurrencyMetaInfo {
return defaultValue;
}
int[] values = b.getIntVector();
long time = ((long) values[0] << 32) | (((long) values[1]) & MASK);
// TODO: remove once errors in CLDR data are fixed. Or push this into ICU data generation.
// The CLDR data parses month as minutes. We should be getting minutes = 0, so if we detect
// that the minute value is nonzero, this means we have bad data and the minute value is really
// the month value.
GregorianCalendar cal = new GregorianCalendar();
cal.setTimeZone(TimeZone.getTimeZone("GMT"));
cal.setTimeInMillis(time);
int minute = cal.get(Calendar.MINUTE);
if (minute != 0) {
cal.set(Calendar.MINUTE, 0);
cal.set(Calendar.MONTH, minute - 1); // months are 1-based
time = cal.getTimeInMillis();
}
// TODO: generate in CLDR data rather than here, remove endOfDay flag.
if (endOfDay) {
cal.set(Calendar.HOUR_OF_DAY, 23);
cal.set(Calendar.MINUTE, 59);
cal.set(Calendar.SECOND, 59);
cal.set(Calendar.MILLISECOND, 999);
time = cal.getTimeInMillis();
}
return time;
return ((long) values[0] << 32) | (((long) values[1]) & MASK);
}
// Utility, just because I don't like the n^2 behavior of using list.contains to build a

View file

@ -5,7 +5,7 @@
# Version numbers, etc.
icu4j.spec.version = 50
icu4j.impl.version = 50.1
icu4j.impl.version = 50.1.1
icu4j.data.version = 50
current.year = 2012
default.exec.env = J2SE-1.5

View file

@ -1,3 +1,3 @@
version https://git-lfs.github.com/spec/v1
oid sha256:19fa12350328b27b171707d59e01934aac487c83617ecab4b8105c564dd86229
size 9758143
oid sha256:c6dfb005d2ad7f4272663dbdc3b3ffc6210a8941e34cd245dfcd53171ea227dd
size 9758191

View file

@ -1,3 +1,3 @@
version https://git-lfs.github.com/spec/v1
oid sha256:d07f11389437204991c5f91ae4d4fec8a782334020d93a01f8a4a93db0655098
size 98283
oid sha256:95032cc8131740775898478637058ddce1c619aeb7c6777d54336d9978c21904
size 98787

View file

@ -1,3 +1,3 @@
version https://git-lfs.github.com/spec/v1
oid sha256:b2409c6f35959bfea4fbdb09a5144ca672308434f91965e29cbef46296619b93
size 723661
oid sha256:bf6180a3cd404399287e993a5c2a46c63b8b2817dcfa88a2b8813d23a4247d98
size 723668

View file

@ -1,6 +1,6 @@
/*
*******************************************************************************
* Copyright (C) 2001-2012, International Business Machines Corporation and *
* Copyright (C) 2001-2013, International Business Machines Corporation and *
* others. All Rights Reserved. *
*******************************************************************************
*/
@ -17,10 +17,12 @@ import java.text.CharacterIterator;
import java.text.FieldPosition;
import java.text.ParseException;
import java.text.ParsePosition;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Date;
import java.util.EnumSet;
import java.util.Iterator;
import java.util.List;
import java.util.Locale;
import java.util.Map;
import java.util.ResourceBundle;
@ -1751,7 +1753,7 @@ public class DateFormatTest extends com.ibm.icu.dev.test.TestFmwk {
final String[] strings = {"Mar 15", "Mar 15 1997", "asdf", "3/1/97 1:23:", "3/1/00 1:23:45 AM"};
int strings_length = strings.length;
DateFormat full = DateFormat.getDateTimeInstance(DateFormat.LONG, DateFormat.LONG, Locale.US);
String expected = "March 1, 2000 1:23:45 AM ";
String expected = "March 1, 2000 at 1:23:45 AM ";
for (int i = 0; i < strings_length; ++i) {
final String text = strings[i];
for (int j = 0; j < looks_length; ++j) {
@ -1770,8 +1772,10 @@ public class DateFormatTest extends com.ibm.icu.dev.test.TestFmwk {
String format;
format = full.format(when);
logln(prefix + "OK: " + format);
if (!format.substring(0, expected.length()).equals(expected))
errln("FAIL: Expected " + expected);
if (!format.substring(0, expected.length()).equals(expected)) {
errln("FAIL: Expected <" + expected + ">, but got <"
+ format.substring(0, expected.length()) + ">");
}
}
} catch(java.text.ParseException e) {
logln(e.getMessage());
@ -1842,7 +1846,7 @@ public class DateFormatTest extends com.ibm.icu.dev.test.TestFmwk {
String result = ((DateFormat) dateParse).format(date);
logln("Parsed \"" + s + "\" using \"" + dateParse.toPattern() + "\" to: " + result);
if (expected == null)
errln("FAIL: Expected parse failure");
errln("FAIL: Expected parse failure for <" + result + ">");
else
if (!result.equals(expected))
errln("FAIL: Expected " + expected);
@ -3667,7 +3671,7 @@ public class DateFormatTest extends com.ibm.icu.dev.test.TestFmwk {
GregorianCalendar gcal = new GregorianCalendar(tz);
gcal.clear();
gcal.set(1910, Calendar.JANUARY, 1, 12, 00); // offset 8:05:52
gcal.set(1910, Calendar.JANUARY, 1, 12, 00); // offset 8:05:57
d1 = gcal.getTime();
gcal.clear();
@ -3677,7 +3681,7 @@ public class DateFormatTest extends com.ibm.icu.dev.test.TestFmwk {
gcal.clear();
gcal.set(1970, Calendar.JANUARY, 1, 12, 00);
dexp2 = gcal.getTime();
dexp1 = new Date(dexp2.getTime() - (5*60 + 52)*1000); // subtract 5m52s
dexp1 = new Date(dexp2.getTime() - (5*60 + 57)*1000); // subtract 5m57s
DateFormat fmt = DateFormat.getTimeInstance(DateFormat.FULL, new ULocale("zh"));
fmt.setTimeZone(tz);
@ -4182,6 +4186,57 @@ public class DateFormatTest extends com.ibm.icu.dev.test.TestFmwk {
}
}
}
static Date TEST_DATE = new Date(2012-1900, 1-1, 15); // January 15, 2012
public void TestDotAndAtLeniency() {
for (ULocale locale : Arrays.asList(ULocale.ENGLISH, ULocale.FRENCH)) {
List<Object[]> tests = new ArrayList();
for (int dateStyle = DateFormat.FULL; dateStyle <= DateFormat.SHORT; ++dateStyle) {
DateFormat dateFormat = DateFormat.getDateInstance(dateStyle, locale);
for (int timeStyle = DateFormat.FULL; timeStyle <= DateFormat.SHORT; ++timeStyle) {
DateFormat format = DateFormat.getDateTimeInstance(dateStyle, timeStyle, locale);
DateFormat timeFormat = DateFormat.getTimeInstance(timeStyle, locale);
String formattedString = format.format(TEST_DATE);
tests.add(new Object[]{format, formattedString});
formattedString = dateFormat.format(TEST_DATE) + " " + timeFormat.format(TEST_DATE);
tests.add(new Object[]{format, formattedString});
if (formattedString.contains("n ")) { // will add "." after the end of text ending in 'n', like Jan.
tests.add(new Object[]{format, formattedString.replace("n ", "n. ") + "."});
}
if (formattedString.contains(". ")) { // will subtract "." at the end of strings.
tests.add(new Object[]{format, formattedString.replace(". ", " ")});
}
}
}
for (Object[] test : tests) {
DateFormat format = (DateFormat) test[0];
String formattedString = (String) test[1];
if (!showParse(format, formattedString)) {
// showParse(format, formattedString); // for debugging
}
}
}
}
private boolean showParse(DateFormat format, String formattedString) {
ParsePosition parsePosition = new ParsePosition(0);
parsePosition.setIndex(0);
Date parsed = format.parse(formattedString, parsePosition);
boolean ok = TEST_DATE.equals(parsed) && parsePosition.getIndex() == formattedString.length();
if (ok) {
logln(format + "\t" + formattedString);
} else {
errln(format + "\t" + formattedString);
}
return ok;
}
}

View file

@ -1,6 +1,6 @@
/*
*******************************************************************************
* Copyright (C) 1996-2011, International Business Machines Corporation and
* Copyright (C) 1996-2012, International Business Machines Corporation and
* others. All Rights Reserved.
*******************************************************************************
*/
@ -2651,6 +2651,26 @@ public class BasicTest extends TestFmwk {
}
}
public void TestFilteredAppend() {
Normalizer2 nfcNorm2=Normalizer2.getNFCInstance();
UnicodeSet filter=new UnicodeSet("[^\u00a0-\u00ff\u0310-\u031f]");
FilteredNormalizer2 fn2=new FilteredNormalizer2(nfcNorm2, filter);
// Append two strings that each contain a character outside the filter set.
StringBuilder sb = new StringBuilder("a\u0313a");
String second = "\u0301\u0313";
assertEquals("append()", "a\u0313á\u0313", fn2.append(sb, second).toString());
// Same, and also normalize the second string.
sb.replace(0, 0x7fffffff, "a\u0313a");
assertEquals(
"normalizeSecondAndAppend()",
"a\u0313á\u0313", fn2.normalizeSecondAndAppend(sb, second).toString());
// Normalizer2.normalize(String) uses spanQuickCheckYes() and normalizeSecondAndAppend().
assertEquals("normalize()", "a\u0313á\u0313", fn2.normalize("a\u0313a\u0301\u0313"));
}
public void TestGetEasyToUseInstance() {
// Test input string:
// U+00A0 -> <noBreak> 0020

View file

@ -1,6 +1,6 @@
/**
*******************************************************************************
* Copyright (C) 2000-2012, International Business Machines Corporation and *
* Copyright (C) 2000-2013, International Business Machines Corporation and *
* others. All Rights Reserved. *
*******************************************************************************
*/
@ -1483,6 +1483,7 @@ public class TimeZoneTest extends TestFmwk
{"Antarctica/South_Pole", "Antarctica/McMurdo"},
{"Atlantic/Jan_Mayen", "Europe/Oslo"},
{"Arctic/Longyearbyen", "Europe/Oslo"},
{"Europe/Busingen", "Europe/Zurich"},
{"Europe/Guernsey", "Europe/London"},
{"Europe/Isle_of_Man", "Europe/London"},
{"Europe/Jersey", "Europe/London"},

View file

@ -7,7 +7,7 @@
package com.ibm.icu.dev.test.util;
public class DebugUtilitiesData extends Object {
public static final String ICU4C_VERSION="50.1";
public static final String ICU4C_VERSION="50.1.1";
public static final int UDebugEnumType = 0;
public static final int UCalendarDateFields = 1;
public static final int UCalendarMonths = 2;

View file

@ -1,6 +1,6 @@
/*
*******************************************************************************
* Copyright (C) 2003-2010, International Business Machines Corporation and *
* Copyright (C) 2003-2012, International Business Machines Corporation and *
* others. All Rights Reserved. *
*******************************************************************************
*/
@ -275,6 +275,52 @@ public class LocaleDataTest extends TestFmwk{
assertTrue("case-folded is sometimes a strict superset, and sometimes equal",
equalCount > 0 && equalCount < availableLocales.length * 2);
}
// Test case created for checking type coverage of static getExemplarSet method.
// See #9785, #9794 and #9795
public void TestExemplarSetTypes() {
final String[] testLocales = {
"am", // No auxiliary / index exemplars as of ICU 50
"en",
"th", // #9785
"foo", // Bogus locale
};
final int[] testTypes = {
LocaleData.ES_STANDARD,
LocaleData.ES_AUXILIARY,
LocaleData.ES_INDEX,
LocaleData.ES_CURRENCY,
LocaleData.ES_PUNCTUATION,
};
final String[] testTypeNames = {
"ES_STANDARD",
"ES_AUXILIARY",
"ES_INDEX",
"ES_CURRENCY",
"ES_PUNCTUATION",
};
for (String locstr : testLocales) {
ULocale loc = new ULocale(locstr);
for (int i = 0; i < testTypes.length; i++) {
try {
UnicodeSet set = LocaleData.getExemplarSet(loc, 0, testTypes[i]);
if (set == null) {
// Not sure null is really OK (#9795)
logln(loc + "(" + testTypeNames[i] + ") returned null");
} else if (set.isEmpty()) {
// This is probably reasonable when data is absent
logln(loc + "(" + testTypeNames[i] + ") returned an empty set");
}
} catch (Exception e) {
errln(loc + "(" + testTypeNames[i] + ") Exception:" + e.getMessage());
}
}
}
}
public void TestCoverage(){
LocaleData ld = LocaleData.getInstance();
boolean t = ld.getNoSubstitute();

View file

@ -11,7 +11,7 @@
<groupId>com.ibm.icu</groupId>
<artifactId>icu4j</artifactId>
<version>50.1</version>
<version>50.1.1</version>
<name>ICU4J</name>
<description>

View file

@ -14,8 +14,8 @@ h4.doc { text-decoration: underline }
<body style="background-color: rgb(255, 255, 255);" lang="EN-US"
link="#0000ff" vlink="#800080">
<h2>International Components for Unicode for Java (ICU4J)</h2>
<h3>Read Me for ICU4J 50 (50.1)</h3>
(Last Update: 2012-Nov-02)
<h3>Read Me for ICU4J 50 (50.1.1)</h3>
(Last Update: 2012-Dec-14)
<hr size="2" width="100%">
<p><b>Note:</b> This is major release of ICU4J. It contains bug fixes and adds implementations
@ -1006,9 +1006,9 @@ ICU4J data is built by ICU4C tools. Please see "icu4j-readme.txt" in <I>$icu4c_r
<h5> Generating Data from CLDR </h5>
<I> Note: This procedure assumes that all 3 sources are present</I>
<ol>
<li>Checkout or download CLDR version 'release-22-1'</li>
<li>Checkout ICU4C with tag 'release-50-1'</li>
<li>Checkout ICU4J with tag 'release-50-1'</li>
<li>Checkout or download CLDR version 'release-22-1-1'</li>
<li>Checkout ICU4C with tag 'release-50-1-1'</li>
<li>Checkout ICU4J with tag 'release-50-1-1'</li>
<li>cd to <I>$icu4c_root</I>/source/data directory</li>
<li>Follow the instructions in <I>$icu4c_root</I>/source/data/cldr-icu-readme.txt</li>
<li>Rebuild ICU4C with the newly generated data.</li>
@ -1020,7 +1020,7 @@ ICU4J data is built by ICU4C tools. Please see "icu4j-readme.txt" in <I>$icu4c_r
</ol>
<h3 class="doc"><a name="timezone"></a>About ICU4J Time Zone</h3>
<p>ICU4J 50.1 includes time zone data version 2012h, which is the latest one as of
<p>ICU4J 50.1.1 includes time zone data version 2012j, which is the latest one as of
the release date. However, time zone data is frequently updated in response
to changes made by local governments around the world. If you need to update
the time zone data, please refer the ICU user guide topic