ICU-8638 milestone:4.8.1 #8657 #8589 #8593

X-SVN-Rev: 30367
This commit is contained in:
Steven R. Loomis 2011-07-15 18:09:43 +00:00
parent 31369abbcb
commit 05870d9516
5 changed files with 71 additions and 18 deletions

View file

@ -1067,7 +1067,15 @@ RuleBasedNumberFormat::format(double number,
UnicodeString& toAppendTo,
FieldPosition& /* pos */) const
{
if (defaultRuleSet) defaultRuleSet->format(number, toAppendTo, toAppendTo.length());
// Special case for NaN; adapted from what DecimalFormat::_format( double number,...) does.
if (uprv_isNaN(number)) {
DecimalFormatSymbols* decFmtSyms = getDecimalFormatSymbols(); // RuleBasedNumberFormat internal
if (decFmtSyms) {
toAppendTo += decFmtSyms->getConstSymbol(DecimalFormatSymbols::kNaNSymbol);
}
} else if (defaultRuleSet) {
defaultRuleSet->format(number, toAppendTo, toAppendTo.length());
}
return toAppendTo;
}

View file

@ -740,13 +740,22 @@ TimeZoneGenericNames::getPartialLocationName(const UnicodeString& tzCanonicalID,
UnicodeString location;
UnicodeString usCountryCode;
ZoneMeta::getSingleCountry(tzCanonicalID, usCountryCode);
ZoneMeta::getCanonicalCountry(tzCanonicalID, usCountryCode);
if (!usCountryCode.isEmpty()) {
char countryCode[ULOC_COUNTRY_CAPACITY];
U_ASSERT(usCountryCode.length() < ULOC_COUNTRY_CAPACITY);
int32_t ccLen = usCountryCode.extract(0, usCountryCode.length(), countryCode, sizeof(countryCode), US_INV);
countryCode[ccLen] = 0;
fLocaleDisplayNames->regionDisplayName(countryCode, location);
UnicodeString regionalGolden;
fTimeZoneNames->getReferenceZoneID(mzID, countryCode, regionalGolden);
if (tzCanonicalID == regionalGolden) {
// Use country name
fLocaleDisplayNames->regionDisplayName(countryCode, location);
} else {
// Otherwise, use exemplar city name
fTimeZoneNames->getExemplarLocationName(tzCanonicalID, location);
}
} else {
fTimeZoneNames->getExemplarLocationName(tzCanonicalID, location);
if (location.isEmpty()) {

View file

@ -1,6 +1,6 @@
/*
*
* (C) Copyright IBM Corp. 1998-2010 - All Rights Reserved
* (C) Copyright IBM Corp. 1998-2011 - All Rights Reserved
*
*/
@ -45,8 +45,8 @@ class U_LAYOUT_API LESwaps /* not : public UObject because all methods are stati
public:
/**
* This method does the byte swap required on little endian platforms
* to correctly access a (16-bit) word.
* Reads a big-endian 16-bit word and returns a native-endian value.
* No-op on a big-endian platform, byte-swaps on a little-endian platform.
*
* @param value - the word to be byte swapped
*
@ -56,12 +56,19 @@ public:
*/
static le_uint16 swapWord(le_uint16 value)
{
return (le_uint16)((value << 8) | (value >> 8));
#if (defined(U_IS_BIG_ENDIAN) && U_IS_BIG_ENDIAN) || (defined(BYTE_ORDER) && defined(BIG_ENDIAN)) || defined(__BIG_ENDIAN__)
// Fastpath when we know that the platform is big-endian.
return value;
#else
// Reads a big-endian value on any platform.
const le_uint8 *p = reinterpret_cast<const le_uint8 *>(&value);
return (le_uint16)((p[0] << 8) | p[1]);
#endif
};
/**
* This method does the byte swapping required on little endian platforms
* to correctly access a (32-bit) long.
* Reads a big-endian 32-bit word and returns a native-endian value.
* No-op on a big-endian platform, byte-swaps on a little-endian platform.
*
* @param value - the long to be byte swapped
*
@ -71,11 +78,14 @@ public:
*/
static le_uint32 swapLong(le_uint32 value)
{
return (le_uint32)(
(value << 24) |
((value << 8) & 0xff0000) |
((value >> 8) & 0xff00) |
(value >> 24));
#if (defined(U_IS_BIG_ENDIAN) && U_IS_BIG_ENDIAN) || (defined(BYTE_ORDER) && defined(BIG_ENDIAN)) || defined(__BIG_ENDIAN__)
// Fastpath when we know that the platform is big-endian.
return value;
#else
// Reads a big-endian value on any platform.
const le_uint8 *p = reinterpret_cast<const le_uint8 *>(&value);
return (le_uint32)((p[0] << 24) | (p[1] << 16) | (p[2] << 8) | p[3]);
#endif
};
private:

View file

@ -1768,6 +1768,23 @@ static void TestRBNFFormat() {
test_fmt(formats[i], (UBool)(i == 0));
}
#define FORMAT_BUF_CAPACITY 64
{
UChar fmtbuf[FORMAT_BUF_CAPACITY];
int32_t len;
double nanvalue = uprv_getNaN();
status = U_ZERO_ERROR;
len = unum_formatDouble(formats[1], nanvalue, fmtbuf, FORMAT_BUF_CAPACITY, NULL, &status);
if (U_FAILURE(status)) {
log_err_status(status, "unum_formatDouble NAN failed with %s\n", u_errorName(status));
} else {
UChar nansym[] = { 0x4E, 0x61, 0x4E, 0 }; /* NaN */
if ( len != 3 || u_strcmp(fmtbuf, nansym) != 0 ) {
log_err("unum_formatDouble NAN produced wrong answer for en_US\n");
}
}
}
for (i = 0; i < COUNT; ++i) {
unum_close(formats[i]);
}

View file

@ -3050,12 +3050,21 @@ void DateFormatTest::TestTimeZoneDisplayName()
{ "ti", "Asia/Calcutta", "2004-07-15T00:00:00Z", "zzzz", "GMT+05:30", "+5:30" },
{ "ti", "Asia/Calcutta", "2004-07-15T00:00:00Z", "v", "(IN)", "Alna/Calcutta" },
{ "ti", "Asia/Calcutta", "2004-07-15T00:00:00Z", "vvvv", "(IN)", "Asia/Calcutta" },
// Ticket#8589 Partial location name to use country name if the zone is the golden
// zone for the time zone's country.
{ "en_MX", "America/Chicago", "1995-07-15T00:00:00Z", "vvvv", "Central Time (United States)", "America/Chicago"},
{ NULL, NULL, NULL, NULL, NULL, NULL },
};
UErrorCode status = U_ZERO_ERROR;
Calendar *cal = GregorianCalendar::createInstance(status);
if (failure(status, "GregorianCalendar::createInstance", TRUE)) return;
SimpleDateFormat testfmt(UnicodeString("yyyy-MM-dd'T'HH:mm:ss'Z'"), status);
if (failure(status, "SimpleDateFormat constructor", TRUE)) return;
testfmt.setTimeZone(*TimeZone::getGMT());
for (int i = 0; fallbackTests[i][0]; i++) {
const char **testLine = fallbackTests[i];
UnicodeString info[5];
@ -3067,10 +3076,10 @@ void DateFormatTest::TestTimeZoneDisplayName()
TimeZone *tz = TimeZone::createTimeZone(info[1]);
if (strcmp(testLine[2], "2004-07-15T00:00:00Z") == 0) {
cal->set(2004,6,15,0,0,0);
} else {
cal->set(2004,0,15,0,0,0);
UDate d = testfmt.parse(testLine[2], status);
cal->setTime(d, status);
if (U_FAILURE(status)) {
errln(UnicodeString("Failed to set date: ") + testLine[2]);
}
SimpleDateFormat fmt(info[3], Locale(testLine[0]),status);