Skip to content

Commit

Permalink
ICU-22226 Fix Calendar.getFirstDayOfWeek to honor -u-fw
Browse files Browse the repository at this point in the history
  • Loading branch information
mihnita authored and FrankYFTang committed Jan 31, 2023
1 parent de0a286 commit 76df897
Show file tree
Hide file tree
Showing 5 changed files with 111 additions and 0 deletions.
23 changes: 23 additions & 0 deletions icu4c/source/i18n/calendar.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -3948,6 +3948,29 @@ Calendar::setWeekData(const Locale& desiredLocale, const char *type, UErrorCode&
} else {
status = U_INVALID_FORMAT_ERROR;
}

// Check if the locale has a "fw" u extension and we honor it if present.
// And we don't change the overal status, as the presence / lack of "fw" is not an error.
UErrorCode fwStatus = U_ZERO_ERROR;
char fwExt[ULOC_FULLNAME_CAPACITY] = "";
desiredLocale.getKeywordValue("fw", fwExt, ULOC_FULLNAME_CAPACITY, fwStatus);
if (U_SUCCESS(fwStatus)) {
if (uprv_strcmp(fwExt, "sun") == 0) {
fFirstDayOfWeek = UCAL_SUNDAY;
} else if (uprv_strcmp(fwExt, "mon") == 0) {
fFirstDayOfWeek = UCAL_MONDAY;
} else if (uprv_strcmp(fwExt, "tue") == 0) {
fFirstDayOfWeek = UCAL_TUESDAY;
} else if (uprv_strcmp(fwExt, "wed") == 0) {
fFirstDayOfWeek = UCAL_WEDNESDAY;
} else if (uprv_strcmp(fwExt, "thu") == 0) {
fFirstDayOfWeek = UCAL_THURSDAY;
} else if (uprv_strcmp(fwExt, "fri") == 0) {
fFirstDayOfWeek = UCAL_FRIDAY;
} else if (uprv_strcmp(fwExt, "sat") == 0) {
fFirstDayOfWeek = UCAL_SATURDAY;
}
}
}
ures_close(weekData);
ures_close(rb);
Expand Down
37 changes: 37 additions & 0 deletions icu4c/source/test/intltest/calregts.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -99,6 +99,7 @@ CalendarRegressionTest::runIndexedTest( int32_t index, UBool exec, const char* &
CASE(55,Test13745);
CASE(56,TestUTCWrongAMPM22023);
CASE(57,TestAsiaManilaAfterSetGregorianChange22043);
CASE(58,TestRespectUExtensionFw);
default: name = ""; break;
}
}
Expand Down Expand Up @@ -3240,4 +3241,40 @@ void CalendarRegressionTest::TestWeekOfYear13548(void) {
}
}

void CalendarRegressionTest::TestRespectUExtensionFw(void) { // ICU-22226
static const char* LOCALE_IDS[] = {
"en-US",
"en-US-u-fw-xyz",
"en-US-u-fw-sun",
"en-US-u-fw-mon",
"en-US-u-fw-thu",
"en-US-u-fw-sat"
};
static const UCalendarDaysOfWeek EXPECTED_VAL[] = {
UCAL_SUNDAY,
UCAL_SUNDAY,
UCAL_SUNDAY,
UCAL_MONDAY,
UCAL_THURSDAY,
UCAL_SATURDAY
};

int32_t EXPECTED_VAL_count = UPRV_LENGTHOF(EXPECTED_VAL);
assertEquals("The number of locales should be equal to the number of expected results.",
EXPECTED_VAL_count, UPRV_LENGTHOF(LOCALE_IDS));

for (int32_t i=0; i<EXPECTED_VAL_count; ++i) {
UErrorCode status = U_ZERO_ERROR;
const char * localeId = LOCALE_IDS[i];
UCalendarDaysOfWeek expected = EXPECTED_VAL[i];

Locale locale = Locale::forLanguageTag(localeId, status);
LocalPointer<Calendar> cal(Calendar::createInstance(locale, status));
UCalendarDaysOfWeek actual = cal->getFirstDayOfWeek(status);
failure(status, "Calendar::getFirstDayOfWeek(status)");

assertEquals((UnicodeString)"Calendar.getFirstDayOfWeek() ignores the 'fw' extension u in '"
+ localeId + "' locale", expected, actual);
}
}
#endif /* #if !UCONFIG_NO_FORMATTING */
1 change: 1 addition & 0 deletions icu4c/source/test/intltest/calregts.h
Original file line number Diff line number Diff line change
Expand Up @@ -85,6 +85,7 @@ class CalendarRegressionTest: public IntlTest {
void TestAsiaManilaAfterSetGregorianChange22043(void);

void Test13745(void);
void TestRespectUExtensionFw(void);

void printdate(GregorianCalendar *cal, const char *string);
void dowTest(UBool lenient) ;
Expand Down
19 changes: 19 additions & 0 deletions icu4j/main/classes/core/src/com/ibm/icu/util/Calendar.java
Original file line number Diff line number Diff line change
Expand Up @@ -1595,6 +1595,25 @@ protected Calendar(TimeZone zone, ULocale locale)
// week data
setWeekData(getRegionForCalendar(locale));

// Check if the locale has a "fw" u extension and we honor it if present.
String fw = locale.getKeywordValue("fw");
if (fw != null) {
int fwOverride;
switch (fw) {
case "sun": fwOverride = SUNDAY; break;
case "mon": fwOverride = MONDAY; break;
case "tue": fwOverride = TUESDAY; break;
case "wed": fwOverride = WEDNESDAY; break;
case "thu": fwOverride = THURSDAY; break;
case "fri": fwOverride = FRIDAY; break;
case "sat": fwOverride = SATURDAY; break;
default: fwOverride = -1;
}
if (fwOverride != -1) {
setFirstDayOfWeek(fwOverride);
}
}

// set valid/actual locale
setCalendarLocale(locale);

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2640,5 +2640,36 @@ public void TestAsiaManilaAfterSetGregorianChange22043() {
}
}

@Test
public void TestRespectUExtensionFw() { // ICU-22226
String[] localeIds = {
"en-US",
"en-US-u-fw-xyz",
"en-US-u-fw-sun",
"en-US-u-fw-mon",
"en-US-u-fw-thu",
"en-US-u-fw-sat"
};
int[] expectedValues = {
Calendar.SUNDAY,
Calendar.SUNDAY,
Calendar.SUNDAY,
Calendar.MONDAY,
Calendar.THURSDAY,
Calendar.SATURDAY
};

assertEquals(
"The localeIds count matches the expectedValues count",
localeIds.length,
expectedValues.length);

for (int i = 0; i < localeIds.length; i++) {
assertEquals(
"Calendar.getFirstDayOfWeek() does not seem to respect fw extension u in locale id",
expectedValues[i],
Calendar.getInstance(Locale.forLanguageTag(localeIds[i])).getFirstDayOfWeek());
}
}
}
//eof

0 comments on commit 76df897

Please sign in to comment.