mirror of
https://github.com/unicode-org/icu.git
synced 2025-04-08 06:53:45 +00:00
ICU-6072 Add DateFormatSymbols support for NarrowEras, use it to format & parse with GGGGG
X-SVN-Rev: 24709
This commit is contained in:
parent
3f1ae1d226
commit
1e9adc5dc1
6 changed files with 151 additions and 14 deletions
|
@ -177,7 +177,6 @@ UOBJECT_DEFINE_RTTI_IMPLEMENTATION(DateFormatSymbols)
|
|||
* with a locale and calendar
|
||||
*/
|
||||
static const char gErasTag[]="eras";
|
||||
static const char gAbbreviatedTag[] = "abbreviated";
|
||||
static const char gMonthNamesTag[]="monthNames";
|
||||
static const char gDayNamesTag[]="dayNames";
|
||||
static const char gNamesWideTag[]="wide";
|
||||
|
@ -310,6 +309,7 @@ void
|
|||
DateFormatSymbols::copyData(const DateFormatSymbols& other) {
|
||||
assignArray(fEras, fErasCount, other.fEras, other.fErasCount);
|
||||
assignArray(fEraNames, fEraNamesCount, other.fEraNames, other.fEraNamesCount);
|
||||
assignArray(fNarrowEras, fNarrowErasCount, other.fNarrowEras, other.fNarrowErasCount);
|
||||
assignArray(fMonths, fMonthsCount, other.fMonths, other.fMonthsCount);
|
||||
assignArray(fShortMonths, fShortMonthsCount, other.fShortMonths, other.fShortMonthsCount);
|
||||
assignArray(fNarrowMonths, fNarrowMonthsCount, other.fNarrowMonths, other.fNarrowMonthsCount);
|
||||
|
@ -371,6 +371,7 @@ void DateFormatSymbols::dispose()
|
|||
{
|
||||
if (fEras) delete[] fEras;
|
||||
if (fEraNames) delete[] fEraNames;
|
||||
if (fNarrowEras) delete[] fNarrowEras;
|
||||
if (fMonths) delete[] fMonths;
|
||||
if (fShortMonths) delete[] fShortMonths;
|
||||
if (fNarrowMonths) delete[] fNarrowMonths;
|
||||
|
@ -447,6 +448,7 @@ DateFormatSymbols::operator==(const DateFormatSymbols& other) const
|
|||
}
|
||||
if (fErasCount == other.fErasCount &&
|
||||
fEraNamesCount == other.fEraNamesCount &&
|
||||
fNarrowErasCount == other.fNarrowErasCount &&
|
||||
fMonthsCount == other.fMonthsCount &&
|
||||
fShortMonthsCount == other.fShortMonthsCount &&
|
||||
fNarrowMonthsCount == other.fNarrowMonthsCount &&
|
||||
|
@ -470,6 +472,7 @@ DateFormatSymbols::operator==(const DateFormatSymbols& other) const
|
|||
// Now compare the arrays themselves
|
||||
if (arrayCompare(fEras, other.fEras, fErasCount) &&
|
||||
arrayCompare(fEraNames, other.fEraNames, fEraNamesCount) &&
|
||||
arrayCompare(fNarrowEras, other.fNarrowEras, fNarrowErasCount) &&
|
||||
arrayCompare(fMonths, other.fMonths, fMonthsCount) &&
|
||||
arrayCompare(fShortMonths, other.fShortMonths, fShortMonthsCount) &&
|
||||
arrayCompare(fNarrowMonths, other.fNarrowMonths, fNarrowMonthsCount) &&
|
||||
|
@ -526,6 +529,13 @@ DateFormatSymbols::getEraNames(int32_t &count) const
|
|||
return fEraNames;
|
||||
}
|
||||
|
||||
const UnicodeString*
|
||||
DateFormatSymbols::getNarrowEras(int32_t &count) const
|
||||
{
|
||||
count = fNarrowErasCount;
|
||||
return fNarrowEras;
|
||||
}
|
||||
|
||||
const UnicodeString*
|
||||
DateFormatSymbols::getMonths(int32_t &count) const
|
||||
{
|
||||
|
@ -734,6 +744,20 @@ DateFormatSymbols::setEraNames(const UnicodeString* eraNamesArray, int32_t count
|
|||
fEraNamesCount = count;
|
||||
}
|
||||
|
||||
void
|
||||
DateFormatSymbols::setNarrowEras(const UnicodeString* narrowErasArray, int32_t count)
|
||||
{
|
||||
// delete the old list if we own it
|
||||
if (fNarrowEras)
|
||||
delete[] fNarrowEras;
|
||||
|
||||
// we always own the new list, which we create here (we duplicate rather
|
||||
// than adopting the list passed in)
|
||||
fNarrowEras = newUnicodeStringArray(count);
|
||||
uprv_arrayCopy(narrowErasArray,fNarrowEras, count);
|
||||
fNarrowErasCount = count;
|
||||
}
|
||||
|
||||
void
|
||||
DateFormatSymbols::setMonths(const UnicodeString* monthsArray, int32_t count)
|
||||
{
|
||||
|
@ -1167,6 +1191,8 @@ DateFormatSymbols::initializeData(const Locale& locale, const char *type, UError
|
|||
fErasCount = 0;
|
||||
fEraNames = NULL;
|
||||
fEraNamesCount = 0;
|
||||
fNarrowEras = NULL;
|
||||
fNarrowErasCount = 0;
|
||||
fMonths = NULL;
|
||||
fMonthsCount=0;
|
||||
fShortMonths = NULL;
|
||||
|
@ -1235,12 +1261,19 @@ DateFormatSymbols::initializeData(const Locale& locale, const char *type, UError
|
|||
|
||||
// load the first data item
|
||||
UResourceBundle *erasMain = calData.getByKey(gErasTag, status);
|
||||
UResourceBundle *eras = ures_getByKeyWithFallback(erasMain, gAbbreviatedTag, NULL, &status);
|
||||
UResourceBundle *eras = ures_getByKeyWithFallback(erasMain, gNamesAbbrTag, NULL, &status);
|
||||
UErrorCode oldStatus = status;
|
||||
UResourceBundle *eraNames = ures_getByKeyWithFallback(erasMain, gNamesWideTag, NULL, &status);
|
||||
if ( status == U_MISSING_RESOURCE_ERROR ) { // Workaround because eras/wide was omitted from CLDR 1.3
|
||||
status = oldStatus;
|
||||
eraNames = ures_getByKeyWithFallback(erasMain, gAbbreviatedTag, NULL, &status);
|
||||
eraNames = ures_getByKeyWithFallback(erasMain, gNamesAbbrTag, NULL, &status);
|
||||
}
|
||||
// current ICU4J falls back to abbreviated if narrow eras are missing, so we will too
|
||||
oldStatus = status;
|
||||
UResourceBundle *narrowEras = ures_getByKeyWithFallback(erasMain, gNamesNarrowTag, NULL, &status);
|
||||
if ( status == U_MISSING_RESOURCE_ERROR ) {
|
||||
status = oldStatus;
|
||||
narrowEras = ures_getByKeyWithFallback(erasMain, gNamesAbbrTag, NULL, &status);
|
||||
}
|
||||
|
||||
UResourceBundle *lsweekdaysData = NULL; // Data closed by calData
|
||||
|
@ -1264,6 +1297,7 @@ DateFormatSymbols::initializeData(const Locale& locale, const char *type, UError
|
|||
|
||||
initField(&fEras, fErasCount, (const UChar *)gLastResortEras, kEraNum, kEraLen, status);
|
||||
initField(&fEraNames, fEraNamesCount, (const UChar *)gLastResortEras, kEraNum, kEraLen, status);
|
||||
initField(&fNarrowEras, fNarrowErasCount, (const UChar *)gLastResortEras, kEraNum, kEraLen, status);
|
||||
initField(&fMonths, fMonthsCount, (const UChar *)gLastResortMonthNames, kMonthNum, kMonthLen, status);
|
||||
initField(&fShortMonths, fShortMonthsCount, (const UChar *)gLastResortMonthNames, kMonthNum, kMonthLen, status);
|
||||
initField(&fNarrowMonths, fNarrowMonthsCount, (const UChar *)gLastResortMonthNames, kMonthNum, kMonthLen, status);
|
||||
|
@ -1296,6 +1330,7 @@ DateFormatSymbols::initializeData(const Locale& locale, const char *type, UError
|
|||
|
||||
initField(&fEras, fErasCount, eras, status);
|
||||
initField(&fEraNames, fEraNamesCount, eraNames, status);
|
||||
initField(&fNarrowEras, fNarrowErasCount, narrowEras, status);
|
||||
|
||||
initField(&fMonths, fMonthsCount, calData.getByKey2(gMonthNamesTag, gNamesWideTag, status), status);
|
||||
initField(&fShortMonths, fShortMonthsCount, calData.getByKey2(gMonthNamesTag, gNamesAbbrTag, status), status);
|
||||
|
@ -1521,6 +1556,7 @@ DateFormatSymbols::initializeData(const Locale& locale, const char *type, UError
|
|||
cleanup:
|
||||
ures_close(eras);
|
||||
ures_close(eraNames);
|
||||
ures_close(narrowEras);
|
||||
ures_close(zoneStringsArray);
|
||||
ures_close(localeBundle);
|
||||
}
|
||||
|
|
|
@ -1046,9 +1046,11 @@ SimpleDateFormat::subFormat(UnicodeString &appendTo,
|
|||
switch (patternCharIndex) {
|
||||
|
||||
// for any "G" symbol, write out the appropriate era string
|
||||
// "GGGG" is wide era name, anything else is abbreviated name
|
||||
// "GGGG" is wide era name, "GGGGG" is narrow era name, anything else is abbreviated name
|
||||
case UDAT_ERA_FIELD:
|
||||
if (count >= 4)
|
||||
if (count == 5)
|
||||
_appendSymbol(appendTo, value, fSymbols->fNarrowEras, fSymbols->fNarrowErasCount);
|
||||
else if (count == 4)
|
||||
_appendSymbol(appendTo, value, fSymbols->fEraNames, fSymbols->fEraNamesCount);
|
||||
else
|
||||
_appendSymbol(appendTo, value, fSymbols->fEras, fSymbols->fErasCount);
|
||||
|
@ -1925,6 +1927,9 @@ int32_t SimpleDateFormat::subParse(const UnicodeString& text, int32_t& start, UC
|
|||
|
||||
switch (patternCharIndex) {
|
||||
case UDAT_ERA_FIELD:
|
||||
if (count == 5) {
|
||||
return matchString(text, start, UCAL_ERA, fSymbols->fNarrowEras, fSymbols->fNarrowErasCount, cal);
|
||||
}
|
||||
if (count == 4) {
|
||||
return matchString(text, start, UCAL_ERA, fSymbols->fEraNames, fSymbols->fEraNamesCount, cal);
|
||||
}
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
/*
|
||||
********************************************************************************
|
||||
* Copyright (C) 1997-2007, International Business Machines
|
||||
* Copyright (C) 1997-2008, International Business Machines
|
||||
* Corporation and others. All Rights Reserved.
|
||||
********************************************************************************
|
||||
*
|
||||
|
@ -180,7 +180,7 @@ public:
|
|||
UBool operator!=(const DateFormatSymbols& other) const { return !operator==(other); }
|
||||
|
||||
/**
|
||||
* Gets era strings. For example: "AD" and "BC".
|
||||
* Gets abbreviated era strings. For example: "AD" and "BC".
|
||||
*
|
||||
* @param count Filled in with length of the array.
|
||||
* @return the era strings.
|
||||
|
@ -189,7 +189,7 @@ public:
|
|||
const UnicodeString* getEras(int32_t& count) const;
|
||||
|
||||
/**
|
||||
* Sets era strings. For example: "AD" and "BC".
|
||||
* Sets abbreviated era strings. For example: "AD" and "BC".
|
||||
* @param eras Array of era strings (DateFormatSymbols retains ownership.)
|
||||
* @param count Filled in with length of the array.
|
||||
* @stable ICU 2.0
|
||||
|
@ -213,6 +213,23 @@ public:
|
|||
*/
|
||||
void setEraNames(const UnicodeString* eraNames, int32_t count);
|
||||
|
||||
/**
|
||||
* Gets narrow era strings. For example: A" and "D".
|
||||
*
|
||||
* @param count Filled in with length of the array.
|
||||
* @return the narrow era strings.
|
||||
* @draft ICU 4.2
|
||||
*/
|
||||
const UnicodeString* getNarrowEras(int32_t& count) const;
|
||||
|
||||
/**
|
||||
* Sets narrow era strings. For example: "A" and "B".
|
||||
* @param narrowEras Array of narrow era strings (DateFormatSymbols retains ownership.)
|
||||
* @param count Filled in with length of the array.
|
||||
* @draft ICU 4.2
|
||||
*/
|
||||
void setNarrowEras(const UnicodeString* narrowEras, int32_t count);
|
||||
|
||||
/**
|
||||
* Gets month strings. For example: "January", "February", etc.
|
||||
* @param count Filled in with length of the array.
|
||||
|
@ -453,7 +470,7 @@ private:
|
|||
friend class DateFormatSymbolsSingleSetter; // see udat.cpp
|
||||
|
||||
/**
|
||||
* Era strings. For example: "AD" and "BC".
|
||||
* Abbreviated era strings. For example: "AD" and "BC".
|
||||
*/
|
||||
UnicodeString* fEras;
|
||||
int32_t fErasCount;
|
||||
|
@ -464,6 +481,12 @@ private:
|
|||
UnicodeString* fEraNames;
|
||||
int32_t fEraNamesCount;
|
||||
|
||||
/**
|
||||
* Narrow era strings. For example: "A" and "B".
|
||||
*/
|
||||
UnicodeString* fNarrowEras;
|
||||
int32_t fNarrowErasCount;
|
||||
|
||||
/**
|
||||
* Month strings. For example: "January", "February", etc.
|
||||
*/
|
||||
|
|
|
@ -39,7 +39,8 @@ void addDateForRgrTest(TestNode** root)
|
|||
addTest(root, &Test4061287, "tsformat/cdtrgtst/Test4061287");
|
||||
addTest(root, &Test4073003, "tsformat/cdtrgtst/Test4073003");
|
||||
addTest(root, &Test4162071, "tsformat/cdtrgtst/Test4162071");
|
||||
addTest(root, &Test714, "tsformat/cdtrgtst/Test714");
|
||||
addTest(root, &Test714, "tsformat/cdtrgtst/Test714");
|
||||
addTest(root, &TestJ6072, "tsformat/cdtrgtst/TestJ6072");
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -499,6 +500,61 @@ void Test714(void)
|
|||
ctest_resetTimeZone();
|
||||
}
|
||||
|
||||
static const UDate july022008 = 1.215e+12; /* 02 July 2008 5:00 AM PDT (approx ICU 4.0 release date :-) */
|
||||
static const UChar zonePST[] = { 'P','S','T',0 };
|
||||
static const UChar dmyGGGPattern[] = { 'd','d',' ','M','M','M',' ','y','y','y','y',' ','G','G','G',0 };
|
||||
static const UChar dmyGGGGGPattern[] = { 'd','d',' ','M','M','M',' ','y','y','y','y',' ','G','G','G','G','G',0 };
|
||||
static const UChar dmyGGGText[] = { '0','2',' ','J','u','l',' ','2','0','0','8',' ','A','D',0 };
|
||||
static const UChar dmyGGGGGText[] = { '0','2',' ','J','u','l',' ','2','0','0','8',' ','A',0 };
|
||||
static const double dayMillisec = 8.64e+07;
|
||||
enum { kdmyGnTextMaxChars = 64 };
|
||||
void TestJ6072(void)
|
||||
{
|
||||
UErrorCode status = U_ZERO_ERROR;
|
||||
UDateFormat * dtfmt = udat_open(UDAT_LONG, UDAT_LONG, "en", zonePST, -1, NULL, 0, &status);
|
||||
if ( U_SUCCESS(status) ) {
|
||||
UChar dmyGnText[kdmyGnTextMaxChars];
|
||||
int32_t dmyGnTextLen;
|
||||
UDate dateResult;
|
||||
|
||||
udat_applyPattern(dtfmt, FALSE, dmyGGGPattern, -1);
|
||||
dmyGnTextLen = udat_format(dtfmt, july022008, dmyGnText, kdmyGnTextMaxChars, NULL, &status);
|
||||
if ( U_FAILURE(status) ) {
|
||||
log_err("FAIL: udat_format with GGG: %s\n", myErrorName(status) );
|
||||
status = U_ZERO_ERROR;
|
||||
} else if ( u_strcmp(dmyGnText, dmyGGGText) != 0 ) {
|
||||
log_err("FAIL: udat_format with GGG: wrong UChar[] result\n" );
|
||||
}
|
||||
dateResult = udat_parse(dtfmt, dmyGGGText, -1, NULL, &status); /* no time, dateResult != july022008 by some hours */
|
||||
if ( U_FAILURE(status) ) {
|
||||
log_err("FAIL: udat_parse with GGG: %s\n", myErrorName(status) );
|
||||
status = U_ZERO_ERROR;
|
||||
} else if ( july022008 - dateResult > dayMillisec ) {
|
||||
log_err("FAIL: udat_parse with GGG: wrong UDate result\n" );
|
||||
}
|
||||
|
||||
udat_applyPattern(dtfmt, FALSE, dmyGGGGGPattern, -1);
|
||||
dmyGnTextLen = udat_format(dtfmt, july022008, dmyGnText, kdmyGnTextMaxChars, NULL, &status);
|
||||
if ( U_FAILURE(status) ) {
|
||||
log_err("FAIL: udat_format with GGGGG: %s\n", myErrorName(status) );
|
||||
status = U_ZERO_ERROR;
|
||||
} else if ( u_strcmp(dmyGnText, dmyGGGGGText) != 0 ) {
|
||||
log_err("FAIL: udat_format with GGGGG: wrong UChar[] result\n" );
|
||||
}
|
||||
dateResult = udat_parse(dtfmt, dmyGGGGGText, -1, NULL, &status); /* no time, dateResult != july022008 by some hours */
|
||||
if ( U_FAILURE(status) ) {
|
||||
log_err("FAIL: udat_parse with GGGGG: %s\n", myErrorName(status) );
|
||||
status = U_ZERO_ERROR;
|
||||
} else if ( july022008 - dateResult > dayMillisec ) {
|
||||
log_err("FAIL: udat_parse with GGGGG: wrong UDate result\n" );
|
||||
}
|
||||
|
||||
udat_close(dtfmt);
|
||||
} else {
|
||||
log_err("FAIL: udat_open fails: %s\n", myErrorName(status));
|
||||
}
|
||||
}
|
||||
|
||||
/*INTERNAL FUNCTION USED */
|
||||
|
||||
UChar* myFormatit(UDateFormat* datdef, UDate d1)
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
/********************************************************************
|
||||
* COPYRIGHT:
|
||||
* Copyright (c) 1997-2001, International Business Machines Corporation and
|
||||
* Copyright (c) 1997-2002,2008, International Business Machines Corporation and
|
||||
* others. All Rights Reserved.
|
||||
********************************************************************/
|
||||
/********************************************************************************
|
||||
|
@ -23,7 +23,7 @@
|
|||
#include "cintltst.h"
|
||||
|
||||
/**
|
||||
* DateFormat Regresstion tests
|
||||
* DateFormat Regression tests
|
||||
**/
|
||||
|
||||
void Test4029195(void);
|
||||
|
@ -34,6 +34,7 @@
|
|||
void Test4073003(void);
|
||||
void Test4162071(void);
|
||||
void Test714(void);
|
||||
void TestJ6072(void);
|
||||
|
||||
/**
|
||||
* test subroutine
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/********************************************************************
|
||||
* Copyright (c) 1997-2007, International Business Machines
|
||||
* Copyright (c) 1997-2008, International Business Machines
|
||||
* Corporation and others. All Rights Reserved.
|
||||
********************************************************************/
|
||||
|
||||
|
@ -159,9 +159,25 @@ void IntlTestDateFormatSymbols::TestSymbols(/* char *par */)
|
|||
int32_t count = 0;
|
||||
const UnicodeString *eras = en.getEras(count);
|
||||
if(count == 0) {
|
||||
errln("ERROR: 0 english eras.. exitting..\n");
|
||||
errln("ERROR: 0 english eras.. exiting..\n");
|
||||
return;
|
||||
}
|
||||
int32_t eraNamesCount = 0;
|
||||
const UnicodeString *eraNames = en.getEraNames(eraNamesCount);
|
||||
if(eraNamesCount == 0) {
|
||||
errln("ERROR: 0 english eraNames\n");
|
||||
} else if ( eraNames[0].length() <= eras[0].length() ) {
|
||||
// At least for English we know a wide eraName should be longer than an abbrev era
|
||||
errln("ERROR: english eraNames[0] not longer than eras[0]\n");
|
||||
}
|
||||
int32_t narrowErasCount = 0;
|
||||
const UnicodeString *narrowEras = en.getNarrowEras(narrowErasCount);
|
||||
if(narrowErasCount == 0) {
|
||||
errln("ERROR: 0 english narrowEras\n");
|
||||
} else if ( narrowEras[0].length() >= eras[0].length() ) {
|
||||
// At least for English we know a narrowEra should be shorter than an abbrev era
|
||||
errln("ERROR: english narrowEras[0] not shorter than eras[0]\n");
|
||||
}
|
||||
|
||||
fr.setEras(eras, count);
|
||||
if( *en.getEras(count) != *fr.getEras(count)) {
|
||||
|
|
Loading…
Add table
Reference in a new issue