mirror of
https://github.com/unicode-org/icu.git
synced 2025-04-13 08:53:20 +00:00
ICU-8279 TimeZone API - getRegion in ICU4C
X-SVN-Rev: 29459
This commit is contained in:
parent
48f462c307
commit
7c93a6eeac
5 changed files with 146 additions and 10 deletions
icu4c/source
|
@ -1,6 +1,6 @@
|
|||
/*
|
||||
*******************************************************************************
|
||||
* Copyright (C) 1997-2010, International Business Machines Corporation and *
|
||||
* Copyright (C) 1997-2011, International Business Machines Corporation and *
|
||||
* others. All Rights Reserved. *
|
||||
*******************************************************************************
|
||||
*
|
||||
|
@ -39,6 +39,7 @@
|
|||
|
||||
#include "unicode/utypes.h"
|
||||
#include "unicode/ustring.h"
|
||||
#include "ustr_imp.h"
|
||||
|
||||
#ifdef U_DEBUG_TZ
|
||||
# include <stdio.h>
|
||||
|
@ -103,6 +104,7 @@ static char gStrBuf[256];
|
|||
static const UChar WORLD[] = {0x30, 0x30, 0x31, 0x00}; /* "001" */
|
||||
|
||||
static const UChar GMT_ID[] = {0x47, 0x4D, 0x54, 0x00}; /* "GMT" */
|
||||
static const UChar UNKNOWN_ZONE_ID[] = {0x45, 0x74, 0x63, 0x2F, 0x55, 0x6E, 0x6B, 0x6E, 0x6F, 0x77, 0x6E, 0x00}; /* "Etc/Unknown" */
|
||||
static const UChar Z_STR[] = {0x7A, 0x00}; /* "z" */
|
||||
static const UChar ZZZZ_STR[] = {0x7A, 0x7A, 0x7A, 0x7A, 0x00}; /* "zzzz" */
|
||||
static const UChar Z_UC_STR[] = {0x5A, 0x00}; /* "Z" */
|
||||
|
@ -112,6 +114,7 @@ static const UChar VVVV_STR[] = {0x76, 0x76, 0x76, 0x76, 0x00}; /* "vvvv
|
|||
static const UChar V_UC_STR[] = {0x56, 0x00}; /* "V" */
|
||||
static const UChar VVVV_UC_STR[] = {0x56, 0x56, 0x56, 0x56, 0x00}; /* "VVVV" */
|
||||
static const int32_t GMT_ID_LENGTH = 3;
|
||||
static const int32_t UNKNOWN_ZONE_ID_LENGTH = 11;
|
||||
|
||||
static UMTX LOCK;
|
||||
static UMTX TZSET_LOCK;
|
||||
|
@ -942,7 +945,7 @@ TimeZone::dereferOlsonLink(const UnicodeString& id) {
|
|||
|
||||
const UChar*
|
||||
TimeZone::getRegion(const UnicodeString& id) {
|
||||
const UChar *result = WORLD;
|
||||
const UChar *result = NULL;
|
||||
UErrorCode ec = U_ZERO_ERROR;
|
||||
UResourceBundle *rb = ures_openDirect(NULL, kZONEINFO, &ec);
|
||||
|
||||
|
@ -963,6 +966,38 @@ TimeZone::getRegion(const UnicodeString& id) {
|
|||
return result;
|
||||
}
|
||||
|
||||
// ---------------------------------------
|
||||
int32_t
|
||||
TimeZone::getRegion(const UnicodeString& id, char *region, int32_t capacity, UErrorCode& status)
|
||||
{
|
||||
int32_t resultLen = 0;
|
||||
*region = 0;
|
||||
if (U_FAILURE(status)) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
const UChar *uregion = NULL;
|
||||
// "Etc/Unknown" is not a system zone ID,
|
||||
// but in the zone data
|
||||
if (id.compare(UNKNOWN_ZONE_ID, UNKNOWN_ZONE_ID_LENGTH) != 0) {
|
||||
uregion = getRegion(id);
|
||||
}
|
||||
if (uregion == NULL) {
|
||||
status = U_ILLEGAL_ARGUMENT_ERROR;
|
||||
return 0;
|
||||
}
|
||||
resultLen = u_strlen(uregion);
|
||||
// A region code is represented by invariant characters
|
||||
u_UCharsToChars(uregion, region, uprv_min(resultLen, capacity));
|
||||
|
||||
if (capacity < resultLen) {
|
||||
status = U_BUFFER_OVERFLOW_ERROR;
|
||||
return resultLen;
|
||||
}
|
||||
|
||||
return u_terminateChars(region, capacity, resultLen, &status);
|
||||
}
|
||||
|
||||
// ---------------------------------------
|
||||
|
||||
|
||||
|
|
|
@ -640,6 +640,26 @@ public:
|
|||
*/
|
||||
virtual int32_t getDSTSavings() const;
|
||||
|
||||
/**
|
||||
* Gets the region code associated with the given
|
||||
* system time zone ID. The region code is either ISO 3166
|
||||
* 2-letter country code or UN M.49 3-digit area code.
|
||||
* When the time zone is not associated with a specific location,
|
||||
* for example - "Etc/UTC", "EST5EDT", then this method returns
|
||||
* "001" (UN M.49 area code for World).
|
||||
*
|
||||
* @param id The system time zone ID.
|
||||
* @param region Output buffer for receiving the region code.
|
||||
* @param capacity The size of the output buffer.
|
||||
* @param status Receives the status. When the given time zone ID
|
||||
* is not a known system time zone ID,
|
||||
* U_ILLEGAL_ARGUMENT_ERROR is set.
|
||||
* @return The length of the output region code.
|
||||
* @draft ICU 4.8
|
||||
*/
|
||||
static int32_t U_EXPORT2 getRegion(const UnicodeString& id,
|
||||
char *region, int32_t capacity, UErrorCode& status);
|
||||
|
||||
protected:
|
||||
|
||||
/**
|
||||
|
@ -680,6 +700,7 @@ protected:
|
|||
*/
|
||||
static UResourceBundle* loadRule(const UResourceBundle* top, const UnicodeString& ruleid, UResourceBundle* oldbundle, UErrorCode&status);
|
||||
|
||||
|
||||
private:
|
||||
friend class ZoneMeta;
|
||||
|
||||
|
@ -697,7 +718,8 @@ private:
|
|||
static const UChar* dereferOlsonLink(const UnicodeString& id);
|
||||
|
||||
/**
|
||||
* Returns the region code associated with the given zone.
|
||||
* Returns the region code associated with the given zone,
|
||||
* or NULL if the zone is not known.
|
||||
* @param id zone id string
|
||||
* @return the region associated with the given zone
|
||||
*/
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
/*
|
||||
*******************************************************************************
|
||||
* Copyright (C) 2007-2010, International Business Machines Corporation and *
|
||||
* Copyright (C) 2007-2011, International Business Machines Corporation and *
|
||||
* others. All Rights Reserved. *
|
||||
*******************************************************************************
|
||||
*/
|
||||
|
@ -274,7 +274,7 @@ ZoneMeta::getCanonicalSystemID(const UnicodeString &tzid, UnicodeString &systemI
|
|||
UnicodeString& U_EXPORT2
|
||||
ZoneMeta::getCanonicalCountry(const UnicodeString &tzid, UnicodeString &canonicalCountry) {
|
||||
const UChar *region = TimeZone::getRegion(tzid);
|
||||
if (u_strcmp(gWorld, region) != 0) {
|
||||
if (region != NULL && u_strcmp(gWorld, region) != 0) {
|
||||
canonicalCountry.setTo(region, -1);
|
||||
} else {
|
||||
canonicalCountry.remove();
|
||||
|
@ -286,8 +286,8 @@ UnicodeString& U_EXPORT2
|
|||
ZoneMeta::getSingleCountry(const UnicodeString &tzid, UnicodeString &country) {
|
||||
// Get canonical country for the zone
|
||||
const UChar *region = TimeZone::getRegion(tzid);
|
||||
if (u_strcmp(gWorld, region) == 0) {
|
||||
// special case - "001"
|
||||
if (region == NULL || u_strcmp(gWorld, region) == 0) {
|
||||
// special case - unknown or "001"
|
||||
country.remove();
|
||||
return country;
|
||||
}
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
/***********************************************************************
|
||||
* COPYRIGHT:
|
||||
* Copyright (c) 1997-2010, International Business Machines Corporation
|
||||
* Copyright (c) 1997-2011, International Business Machines Corporation
|
||||
* and others. All Rights Reserved.
|
||||
***********************************************************************/
|
||||
|
||||
|
@ -61,6 +61,7 @@ void TimeZoneTest::runIndexedTest( int32_t index, UBool exec, const char* &name,
|
|||
CASE(15, TestFebruary);
|
||||
CASE(16, TestCanonicalID);
|
||||
CASE(17, TestDisplayNamesMeta);
|
||||
CASE(18, TestGetRegion);
|
||||
default: name = ""; break;
|
||||
}
|
||||
}
|
||||
|
@ -1976,4 +1977,80 @@ void TimeZoneTest::TestDisplayNamesMeta() {
|
|||
}
|
||||
}
|
||||
|
||||
void TimeZoneTest::TestGetRegion()
|
||||
{
|
||||
static const struct {
|
||||
const char *id;
|
||||
const char *region;
|
||||
} data[] = {
|
||||
{"America/Los_Angeles", "US"},
|
||||
{"America/Indianapolis", "US"}, // CLDR canonical, Olson backward
|
||||
{"America/Indiana/Indianapolis", "US"}, // CLDR alias
|
||||
{"Mexico/General", "MX"}, // Link America/Mexico_City, Olson backward
|
||||
{"Etc/UTC", "001"},
|
||||
{"EST5EDT", "001"},
|
||||
{"PST", "US"}, // Link America/Los_Angeles
|
||||
{"Europe/Helsinki", "FI"},
|
||||
{"Europe/Mariehamn", "AX"}, // Link Europe/Helsinki, but in zone.tab
|
||||
{"Asia/Riyadh", "SA"},
|
||||
{"Asia/Riyadh87", "001"}, // this should be "SA" actually, but not in zone.tab
|
||||
{"Etc/Unknown", 0}, // CLDR canonical, but not a sysmte zone ID
|
||||
{"bogus", 0}, // bogus
|
||||
{"GMT+08:00", 0}, // a custom ID, not a system zone ID
|
||||
{0, 0}
|
||||
};
|
||||
|
||||
int32_t i;
|
||||
char region[4];
|
||||
UErrorCode sts;
|
||||
for (i = 0; data[i].id; i++) {
|
||||
sts = U_ZERO_ERROR;
|
||||
TimeZone::getRegion(data[i].id, region, sizeof(region), sts);
|
||||
if (U_SUCCESS(sts)) {
|
||||
if (data[i].region == 0) {
|
||||
errln((UnicodeString)"Fail: getRegion(\"" + data[i].id + "\") returns "
|
||||
+ region + " [expected: U_ILLEGAL_ARGUMENT_ERROR]");
|
||||
} else if (uprv_strcmp(region, data[i].region) != 0) {
|
||||
errln((UnicodeString)"Fail: getRegion(\"" + data[i].id + "\") returns "
|
||||
+ region + " [expected: " + data[i].region + "]");
|
||||
}
|
||||
} else if (sts == U_ILLEGAL_ARGUMENT_ERROR) {
|
||||
if (data[i].region != 0) {
|
||||
errln((UnicodeString)"Fail: getRegion(\"" + data[i].id
|
||||
+ "\") returns error status U_ILLEGAL_ARGUMENT_ERROR [expected: "
|
||||
+ data[i].region + "]");
|
||||
}
|
||||
} else {
|
||||
errln((UnicodeString)"Fail: getRegion(\"" + data[i].id
|
||||
+ "\") returns an unexpected error status");
|
||||
}
|
||||
}
|
||||
|
||||
// Extra test cases for short buffer
|
||||
int32_t len;
|
||||
char region2[2];
|
||||
sts = U_ZERO_ERROR;
|
||||
|
||||
len = TimeZone::getRegion("America/New_York", region2, sizeof(region2), sts);
|
||||
if (sts != U_STRING_NOT_TERMINATED_WARNING) {
|
||||
errln("Expected U_STRING_NOT_TERMINATED_WARNING");
|
||||
}
|
||||
if (len != 2) { // length of "US"
|
||||
errln("Incorrect result length");
|
||||
}
|
||||
if (uprv_strncmp(region2, "US", 2) != 0) {
|
||||
errln("Incorrect result");
|
||||
}
|
||||
|
||||
char region1[1];
|
||||
sts = U_ZERO_ERROR;
|
||||
|
||||
len = TimeZone::getRegion("America/Chicago", region1, sizeof(region1), sts);
|
||||
if (sts != U_BUFFER_OVERFLOW_ERROR) {
|
||||
errln("Expected U_BUFFER_OVERFLOW_ERROR");
|
||||
}
|
||||
if (len != 2) { // length of "US"
|
||||
errln("Incorrect result length");
|
||||
}
|
||||
}
|
||||
#endif /* #if !UCONFIG_NO_FORMATTING */
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
|
||||
/********************************************************************
|
||||
* Copyright (c) 1997-2010, International Business Machines
|
||||
* Copyright (c) 1997-2011, International Business Machines
|
||||
* Corporation and others. All Rights Reserved.
|
||||
********************************************************************/
|
||||
|
||||
|
@ -89,9 +89,11 @@ public:
|
|||
void TestFebruary(void);
|
||||
|
||||
void TestCanonicalID(void);
|
||||
|
||||
|
||||
virtual void TestDisplayNamesMeta();
|
||||
|
||||
void TestGetRegion(void);
|
||||
|
||||
static const UDate INTERVAL;
|
||||
|
||||
private:
|
||||
|
|
Loading…
Add table
Reference in a new issue