From 19dc7e8efd525023755581bd7485ca44d514e9ea Mon Sep 17 00:00:00 2001 From: Meri Khamoyan Date: Fri, 22 Sep 2023 13:24:41 +0200 Subject: [PATCH 01/10] Add japanese calendar function for hybrid mode --- .../src/Interop/Interop.Calendar.iOS.cs | 10 ++ .../System/Globalization/CalendarTestBase.cs | 2 +- .../System.Private.CoreLib.Shared.projitems | 1 + .../System/Globalization/CalendarData.Icu.cs | 10 +- .../System/Globalization/JapaneseCalendar.cs | 15 +- .../Globalization/JapaneseCalendar.iOS.cs | 97 +++++++++++ .../System.Globalization.Native/entrypoints.c | 3 + .../pal_calendarData.h | 7 + .../pal_calendarData.m | 161 +++++++++++++++++- 9 files changed, 298 insertions(+), 8 deletions(-) create mode 100644 src/libraries/System.Private.CoreLib/src/System/Globalization/JapaneseCalendar.iOS.cs diff --git a/src/libraries/Common/src/Interop/Interop.Calendar.iOS.cs b/src/libraries/Common/src/Interop/Interop.Calendar.iOS.cs index 11a6246a1d700..066d673dfbaaa 100644 --- a/src/libraries/Common/src/Interop/Interop.Calendar.iOS.cs +++ b/src/libraries/Common/src/Interop/Interop.Calendar.iOS.cs @@ -9,7 +9,17 @@ internal static partial class Interop { internal static partial class Globalization { + [LibraryImport(Libraries.GlobalizationNative, EntryPoint = "GlobalizationNative_GetCalendarsNative", StringMarshalling = StringMarshalling.Utf8)] + internal static partial int GetCalendarsNative(string localeName, CalendarId[] calendars, int calendarsCapacity); + [LibraryImport(Libraries.GlobalizationNative, EntryPoint = "GlobalizationNative_GetCalendarInfoNative", StringMarshalling = StringMarshalling.Utf8)] internal static partial string GetCalendarInfoNative(string localeName, CalendarId calendarId, CalendarDataType calendarDataType); + + [LibraryImport(Libraries.GlobalizationNative, EntryPoint = "GlobalizationNative_GetLatestJapaneseEraNative")] + internal static partial int GetLatestJapaneseEraNative(); + + [LibraryImport(Libraries.GlobalizationNative, EntryPoint = "GlobalizationNative_GetJapaneseEraStartDateNative", StringMarshalling = StringMarshalling.Utf8)] + internal static partial string GetJapaneseEraStartDateNative(int era); + } } diff --git a/src/libraries/System.Globalization.Calendars/tests/System/Globalization/CalendarTestBase.cs b/src/libraries/System.Globalization.Calendars/tests/System/Globalization/CalendarTestBase.cs index 0d67b2ec9fd34..061d07108e526 100644 --- a/src/libraries/System.Globalization.Calendars/tests/System/Globalization/CalendarTestBase.cs +++ b/src/libraries/System.Globalization.Calendars/tests/System/Globalization/CalendarTestBase.cs @@ -430,7 +430,7 @@ public void GetEra_Invalid_ThrowsArgumentOutOfRangeException() Assert.All(DateTime_TestData(calendar), dt => { // JapaneseCalendar throws on ICU, but not on NLS or in HybridGlobalization on Browser - if ((calendar is JapaneseCalendar && (PlatformDetection.IsNlsGlobalization || PlatformDetection.IsHybridGlobalizationOnBrowser || PlatformDetection.IsHybridGlobalizationOnOSX)) || calendar is HebrewCalendar || calendar is TaiwanLunisolarCalendar || calendar is JapaneseLunisolarCalendar) + if ((calendar is JapaneseCalendar && (PlatformDetection.IsNlsGlobalization || PlatformDetection.IsHybridGlobalizationOnBrowser)) || calendar is HebrewCalendar || calendar is TaiwanLunisolarCalendar || calendar is JapaneseLunisolarCalendar) { calendar.GetEra(dt); } diff --git a/src/libraries/System.Private.CoreLib/src/System.Private.CoreLib.Shared.projitems b/src/libraries/System.Private.CoreLib/src/System.Private.CoreLib.Shared.projitems index 0d6ae242ae6ec..5a187c2107e24 100644 --- a/src/libraries/System.Private.CoreLib/src/System.Private.CoreLib.Shared.projitems +++ b/src/libraries/System.Private.CoreLib/src/System.Private.CoreLib.Shared.projitems @@ -368,6 +368,7 @@ + diff --git a/src/libraries/System.Private.CoreLib/src/System/Globalization/CalendarData.Icu.cs b/src/libraries/System.Private.CoreLib/src/System/Globalization/CalendarData.Icu.cs index 5bc85b88384ec..f3a71c6bc9910 100644 --- a/src/libraries/System.Private.CoreLib/src/System/Globalization/CalendarData.Icu.cs +++ b/src/libraries/System.Private.CoreLib/src/System/Globalization/CalendarData.Icu.cs @@ -89,7 +89,15 @@ internal static int IcuGetCalendars(string localeName, CalendarId[] calendars) Debug.Assert(!GlobalizationMode.UseNls); // NOTE: there are no 'user overrides' on Linux - int count = Interop.Globalization.GetCalendars(localeName, calendars, calendars.Length); + int count; +#if TARGET_MACCATALYST || TARGET_IOS || TARGET_TVOS + if (GlobalizationMode.Hybrid) + count = Interop.Globalization.GetCalendarsNative(localeName, calendars, calendars.Length); + else + count = Interop.Globalization.GetCalendars(localeName, calendars, calendars.Length); +#else + count = Interop.Globalization.GetCalendars(localeName, calendars, calendars.Length); +#endif // ensure there is at least 1 calendar returned if (count == 0 && calendars.Length > 0) diff --git a/src/libraries/System.Private.CoreLib/src/System/Globalization/JapaneseCalendar.cs b/src/libraries/System.Private.CoreLib/src/System/Globalization/JapaneseCalendar.cs index cd37d6ba65292..d377c615c9766 100644 --- a/src/libraries/System.Private.CoreLib/src/System/Globalization/JapaneseCalendar.cs +++ b/src/libraries/System.Private.CoreLib/src/System/Globalization/JapaneseCalendar.cs @@ -66,18 +66,25 @@ public partial class JapaneseCalendar : Calendar // english name, and abbreviated english names. internal static EraInfo[] GetEraInfo() { - // See if we need to build it + if (s_japaneseEraInfo == null) + { +#if TARGET_MACCATALYST || TARGET_IOS || TARGET_TVOS + s_japaneseEraInfo = GlobalizationMode.UseNls ? NlsGetJapaneseEras() : (GlobalizationMode.Hybrid ? GetJapaneseErasNative() : IcuGetJapaneseEras()); +#else + s_japaneseEraInfo = GlobalizationMode.UseNls ? NlsGetJapaneseEras() : IcuGetJapaneseEras(); +#endif + } + return s_japaneseEraInfo ?? - (s_japaneseEraInfo = GlobalizationMode.UseNls ? NlsGetJapaneseEras() : IcuGetJapaneseEras()) ?? // See if we have to use the built-in eras - (s_japaneseEraInfo = new EraInfo[] + new EraInfo[] { new EraInfo(5, 2019, 5, 1, 2018, 1, GregorianCalendar.MaxYear - 2018, "\x4ee4\x548c", "\x4ee4", "R"), new EraInfo(4, 1989, 1, 8, 1988, 1, 2019 - 1988, "\x5e73\x6210", "\x5e73", "H"), new EraInfo(3, 1926, 12, 25, 1925, 1, 1989 - 1925, "\x662d\x548c", "\x662d", "S"), new EraInfo(2, 1912, 7, 30, 1911, 1, 1926 - 1911, "\x5927\x6b63", "\x5927", "T"), new EraInfo(1, 1868, 1, 1, 1867, 1, 1912 - 1867, "\x660e\x6cbb", "\x660e", "M") - }); + }; } internal static volatile Calendar? s_defaultInstance; diff --git a/src/libraries/System.Private.CoreLib/src/System/Globalization/JapaneseCalendar.iOS.cs b/src/libraries/System.Private.CoreLib/src/System/Globalization/JapaneseCalendar.iOS.cs new file mode 100644 index 0000000000000..6fd96b487301d --- /dev/null +++ b/src/libraries/System.Private.CoreLib/src/System/Globalization/JapaneseCalendar.iOS.cs @@ -0,0 +1,97 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. + +using System.Collections.Generic; +using System.Diagnostics; + +namespace System.Globalization +{ + public partial class JapaneseCalendar : Calendar + { + private static EraInfo[]? GetJapaneseErasNative() + { + if (GlobalizationMode.Invariant) + { + return null; + } + + Debug.Assert(!GlobalizationMode.UseNls); + + string[]? eraNames; + eraNames = Interop.Globalization.GetCalendarInfoNative("ja-JP", CalendarId.JAPAN, CalendarDataType.EraNames).Split("||"); + if (eraNames.Length == 0) + { + return null; + } + + List eras = new List(); + int lastMaxYear = GregorianCalendar.MaxYear; + int latestEra = Interop.Globalization.GetLatestJapaneseEraNative(); + + for (int i = latestEra; i >= 0; i--) + { + DateTime dt; + if (!GetJapaneseEraStartDateNative(i, out dt)) + { + return null; + } + + if (dt < s_calendarMinValue) + { + // only populate the Eras that are valid JapaneseCalendar date times + break; + } + + eras.Add(new EraInfo(i, dt.Year, dt.Month, dt.Day, dt.Year - 1, 1, lastMaxYear - dt.Year + 1, eraNames![i], GetAbbreviatedEraName(eraNames, i), "")); + + lastMaxYear = dt.Year; + } + + string[] abbrevEnglishEraNames = Interop.Globalization.GetCalendarInfoNative("ja", CalendarId.JAPAN, CalendarDataType.AbbrevEraNames).Split("||"); + if (abbrevEnglishEraNames.Length == 0) + { + // Failed to get English names. fallback to hardcoded data. + abbrevEnglishEraNames = s_abbreviatedEnglishEraNames; + } + + // Check if we are getting the English Name at the end of the returned list. + // ICU usually return long list including all Era names written in Japanese characters except the recent eras which actually we support will be returned in English. + // We have the following check as older ICU versions doesn't carry the English names (e.g. ICU version 50). + if (abbrevEnglishEraNames[abbrevEnglishEraNames.Length - 1].Length == 0 || abbrevEnglishEraNames[abbrevEnglishEraNames.Length - 1][0] > '\u007F') + { + // Couldn't get English names. + abbrevEnglishEraNames = s_abbreviatedEnglishEraNames; + } + + int startIndex = abbrevEnglishEraNames == s_abbreviatedEnglishEraNames ? eras.Count - 1 : abbrevEnglishEraNames.Length - 1; + + Debug.Assert(abbrevEnglishEraNames == s_abbreviatedEnglishEraNames || eras.Count <= abbrevEnglishEraNames.Length); + + // remap the Era numbers, now that we know how many there will be + for (int i = 0; i < eras.Count; i++) + { + eras[i].era = eras.Count - i; + if (startIndex < abbrevEnglishEraNames.Length) + { + eras[i].englishEraName = abbrevEnglishEraNames[startIndex]; + } + startIndex--; + } + + return eras.ToArray(); + } + + private static bool GetJapaneseEraStartDateNative(int era, out DateTime dateTime) + { + Debug.Assert(!GlobalizationMode.Invariant); + + string eraStartDate = Interop.Globalization.GetJapaneseEraStartDateNative(era); + var values = eraStartDate.Split('-'); + int startYear = int.Parse(values[0]); + int startMonth = int.Parse(values[1]); + int startDay = int.Parse(values[2]); + dateTime = new DateTime(startYear, startMonth, startDay); + return true; + } + } +} diff --git a/src/native/libs/System.Globalization.Native/entrypoints.c b/src/native/libs/System.Globalization.Native/entrypoints.c index 799b15ed2ca76..1cae8c378b828 100644 --- a/src/native/libs/System.Globalization.Native/entrypoints.c +++ b/src/native/libs/System.Globalization.Native/entrypoints.c @@ -64,6 +64,9 @@ static const Entry s_globalizationNative[] = DllImportEntry(GlobalizationNative_CompareStringNative) DllImportEntry(GlobalizationNative_EndsWithNative) DllImportEntry(GlobalizationNative_GetCalendarInfoNative) + DllImportEntry(GlobalizationNative_GetCalendarsNative) + DllImportEntry(GlobalizationNative_GetJapaneseEraStartDateNative) + DllImportEntry(GlobalizationNative_GetLatestJapaneseEraNative) DllImportEntry(GlobalizationNative_GetLocaleInfoIntNative) DllImportEntry(GlobalizationNative_GetLocaleInfoPrimaryGroupingSizeNative) DllImportEntry(GlobalizationNative_GetLocaleInfoSecondaryGroupingSizeNative) diff --git a/src/native/libs/System.Globalization.Native/pal_calendarData.h b/src/native/libs/System.Globalization.Native/pal_calendarData.h index 50458ac471a60..9a8f97a45dcfd 100644 --- a/src/native/libs/System.Globalization.Native/pal_calendarData.h +++ b/src/native/libs/System.Globalization.Native/pal_calendarData.h @@ -96,4 +96,11 @@ PALEXPORT int32_t GlobalizationNative_GetJapaneseEraStartDate(int32_t era, PALEXPORT const char* GlobalizationNative_GetCalendarInfoNative(const char* localeName, CalendarId calendarId, CalendarDataType dataType); + +PALEXPORT int32_t GlobalizationNative_GetCalendarsNative(const char* localeName, + CalendarId* calendars, + int32_t calendarsCapacity); + +PALEXPORT int32_t GlobalizationNative_GetLatestJapaneseEraNative(void); +PALEXPORT const char* GlobalizationNative_GetJapaneseEraStartDateNative(int32_t era); #endif diff --git a/src/native/libs/System.Globalization.Native/pal_calendarData.m b/src/native/libs/System.Globalization.Native/pal_calendarData.m index c17c8f343dd22..ba7637a213543 100644 --- a/src/native/libs/System.Globalization.Native/pal_calendarData.m +++ b/src/native/libs/System.Globalization.Native/pal_calendarData.m @@ -11,7 +11,15 @@ #endif #if defined(TARGET_MACCATALYST) || defined(TARGET_IOS) || defined(TARGET_TVOS) - +#define GREGORIAN_NAME "gregorian" +#define JAPANESE_NAME "japanese" +#define BUDDHIST_NAME "buddhist" +#define HEBREW_NAME "hebrew" +#define DANGI_NAME "dangi" +#define PERSIAN_NAME "persian" +#define ISLAMIC_NAME "islamic" +#define ISLAMIC_UMALQURA_NAME "islamic-umalqura" +#define ROC_NAME "roc" /* Function: GetCalendarIdentifier @@ -50,6 +58,35 @@ return calendarIdentifier; } +/* +Function: +GetCalendarId + +Gets the associated CalendarId for the calendar name. +*/ +static CalendarId GetCalendarId(const char* calendarName) +{ + if (strcasecmp(calendarName, GREGORIAN_NAME) == 0) + return GREGORIAN; + else if (strcasecmp(calendarName, JAPANESE_NAME) == 0) + return JAPAN; + else if (strcasecmp(calendarName, BUDDHIST_NAME) == 0) + return THAI; + else if (strcasecmp(calendarName, HEBREW_NAME) == 0) + return HEBREW; + else if (strcasecmp(calendarName, DANGI_NAME) == 0) + return KOREA; + else if (strcasecmp(calendarName, PERSIAN_NAME) == 0) + return PERSIAN; + else if (strcasecmp(calendarName, ISLAMIC_NAME) == 0) + return HIJRI; + else if (strcasecmp(calendarName, ISLAMIC_UMALQURA_NAME) == 0) + return UMALQURA; + else if (strcasecmp(calendarName, ROC_NAME) == 0) + return TAIWAN; + else + return UNINITIALIZED_VALUE; +} /* Function: GlobalizationNative_GetCalendarInfoNative @@ -79,7 +116,7 @@ NSCalendar *calendar = [[NSCalendar alloc] initWithCalendarIdentifier:calendarIdentifier]; if (dataType == CalendarData_NativeName) - return calendar ? strdup([[calendar calendarIdentifier] UTF8String]) : NULL; + return strdup([[currentLocale localizedStringForCalendarIdentifier:calendarIdentifier] UTF8String]);//calendar ? strdup([[calendar calendarIdentifier] UTF8String]) : NULL; NSDateFormatter *dateFormat = [[NSDateFormatter alloc] init]; dateFormat.locale = currentLocale; @@ -141,4 +178,124 @@ return arrayToString ? strdup([arrayToString UTF8String]) : NULL; } } + +/* +Function: +GetLatestJapaneseEra + +Gets the latest era in the Japanese calendar. +*/ +int32_t GlobalizationNative_GetLatestJapaneseEraNative() +{ + // Create an NSCalendar with the Japanese calendar identifier + NSCalendar *japaneseCalendar = [[NSCalendar alloc] initWithCalendarIdentifier:NSCalendarIdentifierJapanese]; + // Get the latest era + NSDateComponents *latestEraComponents = [japaneseCalendar components:NSCalendarUnitEra fromDate:[NSDate date]]; + // Extract the era component + NSInteger latestEra = [latestEraComponents era]; + return (int32_t)latestEra; +} + +/* +Function: +GetJapaneseEraInfo + +Gets the starting Gregorian date of the specified Japanese Era. +*/ +const char* GlobalizationNative_GetJapaneseEraStartDateNative(int32_t era) +{ + NSCalendar *japaneseCalendar = [[NSCalendar alloc] initWithCalendarIdentifier:NSCalendarIdentifierJapanese]; + NSDateComponents *startDateComponents = [[NSDateComponents alloc] init]; + startDateComponents.era = era; + startDateComponents.month = 1; + startDateComponents.day = 1; + startDateComponents.year = 1; + NSDate *date = [japaneseCalendar dateFromComponents:startDateComponents]; + NSDate *startDay = date; + int32_t currentEra; + + for (int month = 0; month <= 12; month++) + { + NSDateComponents *eraComponents = [japaneseCalendar components:NSCalendarUnitEra fromDate:date]; + // Extract the era component + currentEra = [eraComponents era]; + if (currentEra == era) + { + for (int day = 0; day < 31; day++) + { + // subtract 1 day at a time until we get out of the specified Era + startDateComponents.day = startDateComponents.day - 1; + date = [japaneseCalendar dateFromComponents:startDateComponents]; + eraComponents = [japaneseCalendar components:NSCalendarUnitEra fromDate:date]; + currentEra = [eraComponents era]; + if (currentEra != era) + { + // add back 1 day to get back into the specified Era + startDateComponents.day = startDateComponents.day + 1; + + startDay = [japaneseCalendar dateFromComponents:startDateComponents]; + //eraComponents = [japaneseCalendar components:NSCalendarUnitEra fromDate:date]; + + break; + } + } + } + // add 1 month at a time until we get into the specified Era + startDateComponents.month = startDateComponents.month + 1; + date = [japaneseCalendar dateFromComponents:startDateComponents]; + eraComponents = [japaneseCalendar components:NSCalendarUnitEra fromDate:date]; + currentEra = [eraComponents era]; + } + + // Create an NSDateFormatter to format the Gregorian date + NSDateFormatter *dateFormatter = [[NSDateFormatter alloc] init]; + dateFormatter.dateFormat = @"yyyy-MM-dd"; + + // Format and print the Gregorian start date + NSString *formattedStartDate = [dateFormatter stringFromDate:startDay]; + return formattedStartDate ? strdup([formattedStartDate UTF8String]) : NULL; +} + +/* +Function: +GetCalendars + +Returns the list of CalendarIds that are available for the specified locale. +*/ +int32_t GlobalizationNative_GetCalendarsNative( + const char* localeName, CalendarId* calendars, int32_t calendarsCapacity) +{ + + @autoreleasepool + { + NSString *locName = [NSString stringWithFormat:@"%s", localeName]; + NSLocale *currentLocale = [[NSLocale alloc] initWithLocaleIdentifier:locName]; + NSArray *calendarIdentifiers = @[ + NSCalendarIdentifierGregorian, + NSCalendarIdentifierBuddhist, + NSCalendarIdentifierChinese, + NSCalendarIdentifierCoptic, + NSCalendarIdentifierEthiopicAmeteMihret, + NSCalendarIdentifierEthiopicAmeteAlem, + NSCalendarIdentifierHebrew, + NSCalendarIdentifierISO8601, + NSCalendarIdentifierIndian, + NSCalendarIdentifierIslamicCivil, + NSCalendarIdentifierIslamicTabular, + NSCalendarIdentifierIslamicUmmAlQura, + NSCalendarIdentifierIslamic, + NSCalendarIdentifierJapanese, + NSCalendarIdentifierPersian, + NSCalendarIdentifierRepublicOfChina, + ]; + int32_t calendarsReturned = 0; + for (int i = 0; i < calendarIdentifiers.count && calendarsReturned < calendarsCapacity; i++) + { + NSString *calendarIdentifier = calendarIdentifiers[i]; + calendars[calendarsReturned] = GetCalendarId([calendarIdentifier UTF8String]); + calendarsReturned++; + } + return calendarsReturned; + } +} #endif From f9322473aafa7d06fd715fcf9a43189cb505ab35 Mon Sep 17 00:00:00 2001 From: Meri Khamoyan Date: Fri, 22 Sep 2023 15:19:42 +0200 Subject: [PATCH 02/10] Minor refactoring --- .../Globalization/JapaneseCalendar.iOS.cs | 2 - .../pal_calendarData.h | 4 +- .../pal_calendarData.m | 155 +++++++++--------- 3 files changed, 82 insertions(+), 79 deletions(-) diff --git a/src/libraries/System.Private.CoreLib/src/System/Globalization/JapaneseCalendar.iOS.cs b/src/libraries/System.Private.CoreLib/src/System/Globalization/JapaneseCalendar.iOS.cs index 6fd96b487301d..e22eae43f210f 100644 --- a/src/libraries/System.Private.CoreLib/src/System/Globalization/JapaneseCalendar.iOS.cs +++ b/src/libraries/System.Private.CoreLib/src/System/Globalization/JapaneseCalendar.iOS.cs @@ -55,8 +55,6 @@ public partial class JapaneseCalendar : Calendar } // Check if we are getting the English Name at the end of the returned list. - // ICU usually return long list including all Era names written in Japanese characters except the recent eras which actually we support will be returned in English. - // We have the following check as older ICU versions doesn't carry the English names (e.g. ICU version 50). if (abbrevEnglishEraNames[abbrevEnglishEraNames.Length - 1].Length == 0 || abbrevEnglishEraNames[abbrevEnglishEraNames.Length - 1][0] > '\u007F') { // Couldn't get English names. diff --git a/src/native/libs/System.Globalization.Native/pal_calendarData.h b/src/native/libs/System.Globalization.Native/pal_calendarData.h index 9a8f97a45dcfd..4b254b45bd4a7 100644 --- a/src/native/libs/System.Globalization.Native/pal_calendarData.h +++ b/src/native/libs/System.Globalization.Native/pal_calendarData.h @@ -98,8 +98,8 @@ PALEXPORT const char* GlobalizationNative_GetCalendarInfoNative(const char* loca CalendarDataType dataType); PALEXPORT int32_t GlobalizationNative_GetCalendarsNative(const char* localeName, - CalendarId* calendars, - int32_t calendarsCapacity); + CalendarId* calendars, + int32_t calendarsCapacity); PALEXPORT int32_t GlobalizationNative_GetLatestJapaneseEraNative(void); PALEXPORT const char* GlobalizationNative_GetJapaneseEraStartDateNative(int32_t era); diff --git a/src/native/libs/System.Globalization.Native/pal_calendarData.m b/src/native/libs/System.Globalization.Native/pal_calendarData.m index ba7637a213543..40a5f3b1fdbef 100644 --- a/src/native/libs/System.Globalization.Native/pal_calendarData.m +++ b/src/native/libs/System.Globalization.Native/pal_calendarData.m @@ -20,6 +20,7 @@ #define ISLAMIC_NAME "islamic" #define ISLAMIC_UMALQURA_NAME "islamic-umalqura" #define ROC_NAME "roc" + /* Function: GetCalendarIdentifier @@ -116,7 +117,7 @@ static CalendarId GetCalendarId(const char* calendarName) NSCalendar *calendar = [[NSCalendar alloc] initWithCalendarIdentifier:calendarIdentifier]; if (dataType == CalendarData_NativeName) - return strdup([[currentLocale localizedStringForCalendarIdentifier:calendarIdentifier] UTF8String]);//calendar ? strdup([[calendar calendarIdentifier] UTF8String]) : NULL; + return strdup([[currentLocale localizedStringForCalendarIdentifier:calendarIdentifier] UTF8String]); NSDateFormatter *dateFormat = [[NSDateFormatter alloc] init]; dateFormat.locale = currentLocale; @@ -187,13 +188,16 @@ static CalendarId GetCalendarId(const char* calendarName) */ int32_t GlobalizationNative_GetLatestJapaneseEraNative() { - // Create an NSCalendar with the Japanese calendar identifier - NSCalendar *japaneseCalendar = [[NSCalendar alloc] initWithCalendarIdentifier:NSCalendarIdentifierJapanese]; - // Get the latest era - NSDateComponents *latestEraComponents = [japaneseCalendar components:NSCalendarUnitEra fromDate:[NSDate date]]; - // Extract the era component - NSInteger latestEra = [latestEraComponents era]; - return (int32_t)latestEra; + @autoreleasepool + { + // Create an NSCalendar with the Japanese calendar identifier + NSCalendar *japaneseCalendar = [[NSCalendar alloc] initWithCalendarIdentifier:NSCalendarIdentifierJapanese]; + // Get the latest era + NSDateComponents *latestEraComponents = [japaneseCalendar components:NSCalendarUnitEra fromDate:[NSDate date]]; + // Extract the era component + NSInteger latestEra = [latestEraComponents era]; + return (int32_t)latestEra; + } } /* @@ -204,98 +208,99 @@ int32_t GlobalizationNative_GetLatestJapaneseEraNative() */ const char* GlobalizationNative_GetJapaneseEraStartDateNative(int32_t era) { - NSCalendar *japaneseCalendar = [[NSCalendar alloc] initWithCalendarIdentifier:NSCalendarIdentifierJapanese]; - NSDateComponents *startDateComponents = [[NSDateComponents alloc] init]; - startDateComponents.era = era; - startDateComponents.month = 1; - startDateComponents.day = 1; - startDateComponents.year = 1; - NSDate *date = [japaneseCalendar dateFromComponents:startDateComponents]; - NSDate *startDay = date; - int32_t currentEra; - - for (int month = 0; month <= 12; month++) + @autoreleasepool { - NSDateComponents *eraComponents = [japaneseCalendar components:NSCalendarUnitEra fromDate:date]; - // Extract the era component - currentEra = [eraComponents era]; - if (currentEra == era) + NSCalendar *japaneseCalendar = [[NSCalendar alloc] initWithCalendarIdentifier:NSCalendarIdentifierJapanese]; + NSDateComponents *startDateComponents = [[NSDateComponents alloc] init]; + startDateComponents.era = era; + // set the date to Jan 1, 1 + startDateComponents.month = 1; + startDateComponents.day = 1; + startDateComponents.year = 1; + NSDate *date = [japaneseCalendar dateFromComponents:startDateComponents]; + NSDate *startDay = date; + int32_t currentEra; + bool foundStartDate = false; + + for (int month = 0; month <= 12; month++) { - for (int day = 0; day < 31; day++) + NSDateComponents *eraComponents = [japaneseCalendar components:NSCalendarUnitEra fromDate:date]; + currentEra = [eraComponents era]; + if (currentEra == era) { - // subtract 1 day at a time until we get out of the specified Era - startDateComponents.day = startDateComponents.day - 1; - date = [japaneseCalendar dateFromComponents:startDateComponents]; - eraComponents = [japaneseCalendar components:NSCalendarUnitEra fromDate:date]; - currentEra = [eraComponents era]; - if (currentEra != era) + for (int day = 0; day < 31; day++) { - // add back 1 day to get back into the specified Era - startDateComponents.day = startDateComponents.day + 1; - - startDay = [japaneseCalendar dateFromComponents:startDateComponents]; - //eraComponents = [japaneseCalendar components:NSCalendarUnitEra fromDate:date]; - - break; + // subtract 1 day at a time until we get out of the specified Era + startDateComponents.day = startDateComponents.day - 1; + date = [japaneseCalendar dateFromComponents:startDateComponents]; + eraComponents = [japaneseCalendar components:NSCalendarUnitEra fromDate:date]; + currentEra = [eraComponents era]; + if (currentEra != era) + { + // add back 1 day to get back into the specified Era + startDateComponents.day = startDateComponents.day + 1; + startDay = [japaneseCalendar dateFromComponents:startDateComponents]; + foundStartDate = true; + break; + } } } + if (foundStartDate) + break; + // add 1 month at a time until we get into the specified Era + startDateComponents.month = startDateComponents.month + 1; + date = [japaneseCalendar dateFromComponents:startDateComponents]; + eraComponents = [japaneseCalendar components:NSCalendarUnitEra fromDate:date]; + currentEra = [eraComponents era]; } - // add 1 month at a time until we get into the specified Era - startDateComponents.month = startDateComponents.month + 1; - date = [japaneseCalendar dateFromComponents:startDateComponents]; - eraComponents = [japaneseCalendar components:NSCalendarUnitEra fromDate:date]; - currentEra = [eraComponents era]; - } - // Create an NSDateFormatter to format the Gregorian date - NSDateFormatter *dateFormatter = [[NSDateFormatter alloc] init]; - dateFormatter.dateFormat = @"yyyy-MM-dd"; + // Create an NSDateFormatter to format the Gregorian date + NSDateFormatter *dateFormatter = [[NSDateFormatter alloc] init]; + dateFormatter.dateFormat = @"yyyy-MM-dd"; - // Format and print the Gregorian start date - NSString *formattedStartDate = [dateFormatter stringFromDate:startDay]; - return formattedStartDate ? strdup([formattedStartDate UTF8String]) : NULL; + // Format and print the Gregorian start date + NSString *formattedStartDate = [dateFormatter stringFromDate:startDay]; + return formattedStartDate ? strdup([formattedStartDate UTF8String]) : NULL; + } } /* Function: -GetCalendars +GetCalendarsNative Returns the list of CalendarIds that are available for the specified locale. */ -int32_t GlobalizationNative_GetCalendarsNative( - const char* localeName, CalendarId* calendars, int32_t calendarsCapacity) +int32_t GlobalizationNative_GetCalendarsNative(const char* localeName, CalendarId* calendars, int32_t calendarsCapacity) { - @autoreleasepool { NSString *locName = [NSString stringWithFormat:@"%s", localeName]; NSLocale *currentLocale = [[NSLocale alloc] initWithLocaleIdentifier:locName]; NSArray *calendarIdentifiers = @[ - NSCalendarIdentifierGregorian, - NSCalendarIdentifierBuddhist, - NSCalendarIdentifierChinese, - NSCalendarIdentifierCoptic, - NSCalendarIdentifierEthiopicAmeteMihret, - NSCalendarIdentifierEthiopicAmeteAlem, - NSCalendarIdentifierHebrew, - NSCalendarIdentifierISO8601, - NSCalendarIdentifierIndian, - NSCalendarIdentifierIslamicCivil, - NSCalendarIdentifierIslamicTabular, - NSCalendarIdentifierIslamicUmmAlQura, - NSCalendarIdentifierIslamic, - NSCalendarIdentifierJapanese, - NSCalendarIdentifierPersian, - NSCalendarIdentifierRepublicOfChina, - ]; - int32_t calendarsReturned = 0; - for (int i = 0; i < calendarIdentifiers.count && calendarsReturned < calendarsCapacity; i++) + NSCalendarIdentifierGregorian, + NSCalendarIdentifierBuddhist, + NSCalendarIdentifierChinese, + NSCalendarIdentifierCoptic, + NSCalendarIdentifierEthiopicAmeteMihret, + NSCalendarIdentifierEthiopicAmeteAlem, + NSCalendarIdentifierHebrew, + NSCalendarIdentifierISO8601, + NSCalendarIdentifierIndian, + NSCalendarIdentifierIslamicCivil, + NSCalendarIdentifierIslamicTabular, + NSCalendarIdentifierIslamicUmmAlQura, + NSCalendarIdentifierIslamic, + NSCalendarIdentifierJapanese, + NSCalendarIdentifierPersian, + NSCalendarIdentifierRepublicOfChina, + ]; + int32_t calendarCount = MIN(calendarIdentifiers.count, calendarsCapacity); + for (int i = 0; i < calendarCount; i++) { NSString *calendarIdentifier = calendarIdentifiers[i]; - calendars[calendarsReturned] = GetCalendarId([calendarIdentifier UTF8String]); - calendarsReturned++; + calendars[i] = GetCalendarId([calendarIdentifier UTF8String]); } - return calendarsReturned; + return calendarCount; } } #endif From 7011aa97b3b762fbca2bdd5da93efafa16cb460e Mon Sep 17 00:00:00 2001 From: Meri Khamoyan Date: Fri, 22 Sep 2023 17:52:40 +0200 Subject: [PATCH 03/10] Refactor GetJapaneseEraStartDateNative --- .../src/Interop/Interop.Calendar.iOS.cs | 3 +- .../Globalization/JapaneseCalendar.iOS.cs | 21 +++++++------ .../pal_calendarData.h | 5 ++- .../pal_calendarData.m | 31 ++++++++----------- 4 files changed, 31 insertions(+), 29 deletions(-) diff --git a/src/libraries/Common/src/Interop/Interop.Calendar.iOS.cs b/src/libraries/Common/src/Interop/Interop.Calendar.iOS.cs index 066d673dfbaaa..985e55b604e4f 100644 --- a/src/libraries/Common/src/Interop/Interop.Calendar.iOS.cs +++ b/src/libraries/Common/src/Interop/Interop.Calendar.iOS.cs @@ -19,7 +19,8 @@ internal static partial class Globalization internal static partial int GetLatestJapaneseEraNative(); [LibraryImport(Libraries.GlobalizationNative, EntryPoint = "GlobalizationNative_GetJapaneseEraStartDateNative", StringMarshalling = StringMarshalling.Utf8)] - internal static partial string GetJapaneseEraStartDateNative(int era); + [return: MarshalAs(UnmanagedType.Bool)] + internal static partial bool GetJapaneseEraStartDateNative(int era, out int startYear, out int startMonth, out int startDay); } } diff --git a/src/libraries/System.Private.CoreLib/src/System/Globalization/JapaneseCalendar.iOS.cs b/src/libraries/System.Private.CoreLib/src/System/Globalization/JapaneseCalendar.iOS.cs index e22eae43f210f..7b1da8dc7ab4b 100644 --- a/src/libraries/System.Private.CoreLib/src/System/Globalization/JapaneseCalendar.iOS.cs +++ b/src/libraries/System.Private.CoreLib/src/System/Globalization/JapaneseCalendar.iOS.cs @@ -81,15 +81,18 @@ public partial class JapaneseCalendar : Calendar private static bool GetJapaneseEraStartDateNative(int era, out DateTime dateTime) { - Debug.Assert(!GlobalizationMode.Invariant); - - string eraStartDate = Interop.Globalization.GetJapaneseEraStartDateNative(era); - var values = eraStartDate.Split('-'); - int startYear = int.Parse(values[0]); - int startMonth = int.Parse(values[1]); - int startDay = int.Parse(values[2]); - dateTime = new DateTime(startYear, startMonth, startDay); - return true; + dateTime = default; + + int startYear; + int startMonth; + int startDay; + bool result = Interop.Globalization.GetJapaneseEraStartDateNative(era, out startYear, out startMonth, out startDay); + if (result) + { + dateTime = new DateTime(startYear, startMonth, startDay); + } + + return result; } } } diff --git a/src/native/libs/System.Globalization.Native/pal_calendarData.h b/src/native/libs/System.Globalization.Native/pal_calendarData.h index 4b254b45bd4a7..824cf856bef06 100644 --- a/src/native/libs/System.Globalization.Native/pal_calendarData.h +++ b/src/native/libs/System.Globalization.Native/pal_calendarData.h @@ -102,5 +102,8 @@ PALEXPORT int32_t GlobalizationNative_GetCalendarsNative(const char* localeName, int32_t calendarsCapacity); PALEXPORT int32_t GlobalizationNative_GetLatestJapaneseEraNative(void); -PALEXPORT const char* GlobalizationNative_GetJapaneseEraStartDateNative(int32_t era); +PALEXPORT int32_t GlobalizationNative_GetJapaneseEraStartDateNative(int32_t era, + int32_t* startYear, + int32_t* startMonth, + int32_t* startDay); #endif diff --git a/src/native/libs/System.Globalization.Native/pal_calendarData.m b/src/native/libs/System.Globalization.Native/pal_calendarData.m index 40a5f3b1fdbef..63fea4ed6970b 100644 --- a/src/native/libs/System.Globalization.Native/pal_calendarData.m +++ b/src/native/libs/System.Globalization.Native/pal_calendarData.m @@ -182,11 +182,11 @@ static CalendarId GetCalendarId(const char* calendarName) /* Function: -GetLatestJapaneseEra +GetLatestJapaneseEraNative Gets the latest era in the Japanese calendar. */ -int32_t GlobalizationNative_GetLatestJapaneseEraNative() +int32_t GlobalizationNative_GetLatestJapaneseEraNative(void) { @autoreleasepool { @@ -202,11 +202,11 @@ int32_t GlobalizationNative_GetLatestJapaneseEraNative() /* Function: -GetJapaneseEraInfo +GetJapaneseEraStartDateNative Gets the starting Gregorian date of the specified Japanese Era. */ -const char* GlobalizationNative_GetJapaneseEraStartDateNative(int32_t era) +int32_t GlobalizationNative_GetJapaneseEraStartDateNative(int32_t era, int32_t* startYear, int32_t* startMonth, int32_t* startDay) { @autoreleasepool { @@ -218,9 +218,8 @@ int32_t GlobalizationNative_GetLatestJapaneseEraNative() startDateComponents.day = 1; startDateComponents.year = 1; NSDate *date = [japaneseCalendar dateFromComponents:startDateComponents]; - NSDate *startDay = date; + NSDate *startDate = date; int32_t currentEra; - bool foundStartDate = false; for (int month = 0; month <= 12; month++) { @@ -239,14 +238,16 @@ int32_t GlobalizationNative_GetLatestJapaneseEraNative() { // add back 1 day to get back into the specified Era startDateComponents.day = startDateComponents.day + 1; - startDay = [japaneseCalendar dateFromComponents:startDateComponents]; - foundStartDate = true; - break; + startDate = [japaneseCalendar dateFromComponents:startDateComponents]; + NSCalendar *gregorianCalendar = [[NSCalendar alloc] initWithCalendarIdentifier:NSCalendarIdentifierGregorian]; + NSDateComponents *components = [gregorianCalendar components:NSCalendarUnitDay | NSCalendarUnitMonth | NSCalendarUnitYear fromDate:startDate]; + *startYear = [components year]; + *startMonth = [components month]; + *startDay = [components day]; + return 1; } } } - if (foundStartDate) - break; // add 1 month at a time until we get into the specified Era startDateComponents.month = startDateComponents.month + 1; date = [japaneseCalendar dateFromComponents:startDateComponents]; @@ -254,13 +255,7 @@ int32_t GlobalizationNative_GetLatestJapaneseEraNative() currentEra = [eraComponents era]; } - // Create an NSDateFormatter to format the Gregorian date - NSDateFormatter *dateFormatter = [[NSDateFormatter alloc] init]; - dateFormatter.dateFormat = @"yyyy-MM-dd"; - - // Format and print the Gregorian start date - NSString *formattedStartDate = [dateFormatter stringFromDate:startDay]; - return formattedStartDate ? strdup([formattedStartDate UTF8String]) : NULL; + return 0; } } From 4e3a1d96a813bb0524841b5a2052435deaaa5114 Mon Sep 17 00:00:00 2001 From: Meri Khamoyan Date: Mon, 25 Sep 2023 16:13:03 +0200 Subject: [PATCH 04/10] Refactored as requested by review --- .../src/Interop/Interop.Calendar.iOS.cs | 2 +- .../System.Private.CoreLib.Shared.projitems | 1 - .../System/Globalization/CalendarData.Icu.cs | 2 +- .../Globalization/JapaneseCalendar.Icu.cs | 68 +++++++++++-- .../System/Globalization/JapaneseCalendar.cs | 15 +-- .../Globalization/JapaneseCalendar.iOS.cs | 98 ------------------- .../pal_calendarData.c | 10 -- .../pal_calendarData.h | 14 ++- .../pal_calendarData.m | 19 +--- 9 files changed, 82 insertions(+), 147 deletions(-) delete mode 100644 src/libraries/System.Private.CoreLib/src/System/Globalization/JapaneseCalendar.iOS.cs diff --git a/src/libraries/Common/src/Interop/Interop.Calendar.iOS.cs b/src/libraries/Common/src/Interop/Interop.Calendar.iOS.cs index 985e55b604e4f..8c567076fda12 100644 --- a/src/libraries/Common/src/Interop/Interop.Calendar.iOS.cs +++ b/src/libraries/Common/src/Interop/Interop.Calendar.iOS.cs @@ -10,7 +10,7 @@ internal static partial class Interop internal static partial class Globalization { [LibraryImport(Libraries.GlobalizationNative, EntryPoint = "GlobalizationNative_GetCalendarsNative", StringMarshalling = StringMarshalling.Utf8)] - internal static partial int GetCalendarsNative(string localeName, CalendarId[] calendars, int calendarsCapacity); + internal static partial int GetCalendarsNative(CalendarId[] calendars, int calendarsCapacity); [LibraryImport(Libraries.GlobalizationNative, EntryPoint = "GlobalizationNative_GetCalendarInfoNative", StringMarshalling = StringMarshalling.Utf8)] internal static partial string GetCalendarInfoNative(string localeName, CalendarId calendarId, CalendarDataType calendarDataType); diff --git a/src/libraries/System.Private.CoreLib/src/System.Private.CoreLib.Shared.projitems b/src/libraries/System.Private.CoreLib/src/System.Private.CoreLib.Shared.projitems index 5a187c2107e24..0d6ae242ae6ec 100644 --- a/src/libraries/System.Private.CoreLib/src/System.Private.CoreLib.Shared.projitems +++ b/src/libraries/System.Private.CoreLib/src/System.Private.CoreLib.Shared.projitems @@ -368,7 +368,6 @@ - diff --git a/src/libraries/System.Private.CoreLib/src/System/Globalization/CalendarData.Icu.cs b/src/libraries/System.Private.CoreLib/src/System/Globalization/CalendarData.Icu.cs index f3a71c6bc9910..f3d05eeb49357 100644 --- a/src/libraries/System.Private.CoreLib/src/System/Globalization/CalendarData.Icu.cs +++ b/src/libraries/System.Private.CoreLib/src/System/Globalization/CalendarData.Icu.cs @@ -92,7 +92,7 @@ internal static int IcuGetCalendars(string localeName, CalendarId[] calendars) int count; #if TARGET_MACCATALYST || TARGET_IOS || TARGET_TVOS if (GlobalizationMode.Hybrid) - count = Interop.Globalization.GetCalendarsNative(localeName, calendars, calendars.Length); + count = Interop.Globalization.GetCalendarsNative(calendars, calendars.Length); else count = Interop.Globalization.GetCalendars(localeName, calendars, calendars.Length); #else diff --git a/src/libraries/System.Private.CoreLib/src/System/Globalization/JapaneseCalendar.Icu.cs b/src/libraries/System.Private.CoreLib/src/System/Globalization/JapaneseCalendar.Icu.cs index 5ac43a99e56c0..09d347c728470 100644 --- a/src/libraries/System.Private.CoreLib/src/System/Globalization/JapaneseCalendar.Icu.cs +++ b/src/libraries/System.Private.CoreLib/src/System/Globalization/JapaneseCalendar.Icu.cs @@ -20,16 +20,36 @@ public partial class JapaneseCalendar : Calendar Debug.Assert(!GlobalizationMode.UseNls); string[]? eraNames; + int latestEra; +#if TARGET_MACCATALYST || TARGET_IOS || TARGET_TVOS + if (GlobalizationMode.Hybrid) + { + eraNames = Interop.Globalization.GetCalendarInfoNative("ja-JP", CalendarId.JAPAN, CalendarDataType.EraNames).Split("||"); + if (eraNames.Length == 0) + { + return null; + } + latestEra = Interop.Globalization.GetLatestJapaneseEraNative(); + } + else + { + if (!CalendarData.EnumCalendarInfo("ja-JP", CalendarId.JAPAN, CalendarDataType.EraNames, out eraNames)) + { + return null; + } + latestEra = Interop.Globalization.GetLatestJapaneseEra(); + } +#else if (!CalendarData.EnumCalendarInfo("ja-JP", CalendarId.JAPAN, CalendarDataType.EraNames, out eraNames)) { return null; } + latestEra = Interop.Globalization.GetLatestJapaneseEra(); +#endif List eras = new List(); int lastMaxYear = GregorianCalendar.MaxYear; - int latestEra = Interop.Globalization.GetLatestJapaneseEra(); - for (int i = latestEra; i >= 0; i--) { DateTime dt; @@ -50,11 +70,40 @@ public partial class JapaneseCalendar : Calendar } string[] abbrevEnglishEraNames; +#if TARGET_MACCATALYST || TARGET_IOS || TARGET_TVOS + if (GlobalizationMode.Hybrid) + { + var abbrevEraNames = Interop.Globalization.GetCalendarInfoNative("ja", CalendarId.JAPAN, CalendarDataType.AbbrevEraNames); + if (abbrevEraNames == null) + { + // Failed to get English names. fallback to hardcoded data. + abbrevEnglishEraNames = s_abbreviatedEnglishEraNames; + } + else + { + abbrevEnglishEraNames = abbrevEraNames.Split("||"); + } + } + else + { + string[]? abbrevEraNames; + if (!CalendarData.EnumCalendarInfo("ja", CalendarId.JAPAN, CalendarDataType.AbbrevEraNames, out abbrevEraNames)) + { + // Failed to get English names. fallback to hardcoded data. + abbrevEnglishEraNames = s_abbreviatedEnglishEraNames; + } + else + { + abbrevEnglishEraNames = abbrevEraNames ?? s_abbreviatedEnglishEraNames; + } + } +#else if (!CalendarData.EnumCalendarInfo("ja", CalendarId.JAPAN, CalendarDataType.AbbrevEraNames, out abbrevEnglishEraNames!)) { // Failed to get English names. fallback to hardcoded data. abbrevEnglishEraNames = s_abbreviatedEnglishEraNames; } +#endif // Check if we are getting the English Name at the end of the returned list. // ICU usually return long list including all Era names written in Japanese characters except the recent eras which actually we support will be returned in English. @@ -101,12 +150,15 @@ private static bool GetJapaneseEraStartDate(int era, out DateTime dateTime) int startYear; int startMonth; int startDay; - bool result = Interop.Globalization.GetJapaneseEraStartDate( - era, - out startYear, - out startMonth, - out startDay); - + bool result; +#if TARGET_MACCATALYST || TARGET_IOS || TARGET_TVOS + if (GlobalizationMode.Hybrid) + result = Interop.Globalization.GetJapaneseEraStartDateNative(era, out startYear, out startMonth, out startDay); + else + result = Interop.Globalization.GetJapaneseEraStartDate(era, out startYear, out startMonth, out startDay); +#else + result = Interop.Globalization.GetJapaneseEraStartDate(era, out startYear, out startMonth, out startDay); +#endif if (result) { dateTime = new DateTime(startYear, startMonth, startDay); diff --git a/src/libraries/System.Private.CoreLib/src/System/Globalization/JapaneseCalendar.cs b/src/libraries/System.Private.CoreLib/src/System/Globalization/JapaneseCalendar.cs index d377c615c9766..cd37d6ba65292 100644 --- a/src/libraries/System.Private.CoreLib/src/System/Globalization/JapaneseCalendar.cs +++ b/src/libraries/System.Private.CoreLib/src/System/Globalization/JapaneseCalendar.cs @@ -66,25 +66,18 @@ public partial class JapaneseCalendar : Calendar // english name, and abbreviated english names. internal static EraInfo[] GetEraInfo() { - if (s_japaneseEraInfo == null) - { -#if TARGET_MACCATALYST || TARGET_IOS || TARGET_TVOS - s_japaneseEraInfo = GlobalizationMode.UseNls ? NlsGetJapaneseEras() : (GlobalizationMode.Hybrid ? GetJapaneseErasNative() : IcuGetJapaneseEras()); -#else - s_japaneseEraInfo = GlobalizationMode.UseNls ? NlsGetJapaneseEras() : IcuGetJapaneseEras(); -#endif - } - + // See if we need to build it return s_japaneseEraInfo ?? + (s_japaneseEraInfo = GlobalizationMode.UseNls ? NlsGetJapaneseEras() : IcuGetJapaneseEras()) ?? // See if we have to use the built-in eras - new EraInfo[] + (s_japaneseEraInfo = new EraInfo[] { new EraInfo(5, 2019, 5, 1, 2018, 1, GregorianCalendar.MaxYear - 2018, "\x4ee4\x548c", "\x4ee4", "R"), new EraInfo(4, 1989, 1, 8, 1988, 1, 2019 - 1988, "\x5e73\x6210", "\x5e73", "H"), new EraInfo(3, 1926, 12, 25, 1925, 1, 1989 - 1925, "\x662d\x548c", "\x662d", "S"), new EraInfo(2, 1912, 7, 30, 1911, 1, 1926 - 1911, "\x5927\x6b63", "\x5927", "T"), new EraInfo(1, 1868, 1, 1, 1867, 1, 1912 - 1867, "\x660e\x6cbb", "\x660e", "M") - }; + }); } internal static volatile Calendar? s_defaultInstance; diff --git a/src/libraries/System.Private.CoreLib/src/System/Globalization/JapaneseCalendar.iOS.cs b/src/libraries/System.Private.CoreLib/src/System/Globalization/JapaneseCalendar.iOS.cs deleted file mode 100644 index 7b1da8dc7ab4b..0000000000000 --- a/src/libraries/System.Private.CoreLib/src/System/Globalization/JapaneseCalendar.iOS.cs +++ /dev/null @@ -1,98 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. - -using System.Collections.Generic; -using System.Diagnostics; - -namespace System.Globalization -{ - public partial class JapaneseCalendar : Calendar - { - private static EraInfo[]? GetJapaneseErasNative() - { - if (GlobalizationMode.Invariant) - { - return null; - } - - Debug.Assert(!GlobalizationMode.UseNls); - - string[]? eraNames; - eraNames = Interop.Globalization.GetCalendarInfoNative("ja-JP", CalendarId.JAPAN, CalendarDataType.EraNames).Split("||"); - if (eraNames.Length == 0) - { - return null; - } - - List eras = new List(); - int lastMaxYear = GregorianCalendar.MaxYear; - int latestEra = Interop.Globalization.GetLatestJapaneseEraNative(); - - for (int i = latestEra; i >= 0; i--) - { - DateTime dt; - if (!GetJapaneseEraStartDateNative(i, out dt)) - { - return null; - } - - if (dt < s_calendarMinValue) - { - // only populate the Eras that are valid JapaneseCalendar date times - break; - } - - eras.Add(new EraInfo(i, dt.Year, dt.Month, dt.Day, dt.Year - 1, 1, lastMaxYear - dt.Year + 1, eraNames![i], GetAbbreviatedEraName(eraNames, i), "")); - - lastMaxYear = dt.Year; - } - - string[] abbrevEnglishEraNames = Interop.Globalization.GetCalendarInfoNative("ja", CalendarId.JAPAN, CalendarDataType.AbbrevEraNames).Split("||"); - if (abbrevEnglishEraNames.Length == 0) - { - // Failed to get English names. fallback to hardcoded data. - abbrevEnglishEraNames = s_abbreviatedEnglishEraNames; - } - - // Check if we are getting the English Name at the end of the returned list. - if (abbrevEnglishEraNames[abbrevEnglishEraNames.Length - 1].Length == 0 || abbrevEnglishEraNames[abbrevEnglishEraNames.Length - 1][0] > '\u007F') - { - // Couldn't get English names. - abbrevEnglishEraNames = s_abbreviatedEnglishEraNames; - } - - int startIndex = abbrevEnglishEraNames == s_abbreviatedEnglishEraNames ? eras.Count - 1 : abbrevEnglishEraNames.Length - 1; - - Debug.Assert(abbrevEnglishEraNames == s_abbreviatedEnglishEraNames || eras.Count <= abbrevEnglishEraNames.Length); - - // remap the Era numbers, now that we know how many there will be - for (int i = 0; i < eras.Count; i++) - { - eras[i].era = eras.Count - i; - if (startIndex < abbrevEnglishEraNames.Length) - { - eras[i].englishEraName = abbrevEnglishEraNames[startIndex]; - } - startIndex--; - } - - return eras.ToArray(); - } - - private static bool GetJapaneseEraStartDateNative(int era, out DateTime dateTime) - { - dateTime = default; - - int startYear; - int startMonth; - int startDay; - bool result = Interop.Globalization.GetJapaneseEraStartDateNative(era, out startYear, out startMonth, out startDay); - if (result) - { - dateTime = new DateTime(startYear, startMonth, startDay); - } - - return result; - } - } -} diff --git a/src/native/libs/System.Globalization.Native/pal_calendarData.c b/src/native/libs/System.Globalization.Native/pal_calendarData.c index ba4070252bdcd..e4d01d9426dfd 100644 --- a/src/native/libs/System.Globalization.Native/pal_calendarData.c +++ b/src/native/libs/System.Globalization.Native/pal_calendarData.c @@ -21,16 +21,6 @@ #define STRING_COPY(destination, numberOfElements, source) strncpy_s(destination, numberOfElements, source, _TRUNCATE); #endif -#define GREGORIAN_NAME "gregorian" -#define JAPANESE_NAME "japanese" -#define BUDDHIST_NAME "buddhist" -#define HEBREW_NAME "hebrew" -#define DANGI_NAME "dangi" -#define PERSIAN_NAME "persian" -#define ISLAMIC_NAME "islamic" -#define ISLAMIC_UMALQURA_NAME "islamic-umalqura" -#define ROC_NAME "roc" - #define JAPANESE_LOCALE_AND_CALENDAR "ja_JP@calendar=japanese" static const UChar UDAT_MONTH_DAY_UCHAR[] = {'M', 'M', 'M', 'M', 'd', '\0'}; diff --git a/src/native/libs/System.Globalization.Native/pal_calendarData.h b/src/native/libs/System.Globalization.Native/pal_calendarData.h index 824cf856bef06..9fe5f3c5d2335 100644 --- a/src/native/libs/System.Globalization.Native/pal_calendarData.h +++ b/src/native/libs/System.Globalization.Native/pal_calendarData.h @@ -66,6 +66,16 @@ typedef enum CalendarData_AbbrevEraNames = 14, } CalendarDataType; +#define GREGORIAN_NAME "gregorian" +#define JAPANESE_NAME "japanese" +#define BUDDHIST_NAME "buddhist" +#define HEBREW_NAME "hebrew" +#define DANGI_NAME "dangi" +#define PERSIAN_NAME "persian" +#define ISLAMIC_NAME "islamic" +#define ISLAMIC_UMALQURA_NAME "islamic-umalqura" +#define ROC_NAME "roc" + // the function pointer definition for the callback used in EnumCalendarInfo typedef void (PAL_CALLBACK_CALLTYPE *EnumCalendarInfoCallback)(const UChar*, const void*); @@ -97,11 +107,11 @@ PALEXPORT const char* GlobalizationNative_GetCalendarInfoNative(const char* loca CalendarId calendarId, CalendarDataType dataType); -PALEXPORT int32_t GlobalizationNative_GetCalendarsNative(const char* localeName, - CalendarId* calendars, +PALEXPORT int32_t GlobalizationNative_GetCalendarsNative(CalendarId* calendars, int32_t calendarsCapacity); PALEXPORT int32_t GlobalizationNative_GetLatestJapaneseEraNative(void); + PALEXPORT int32_t GlobalizationNative_GetJapaneseEraStartDateNative(int32_t era, int32_t* startYear, int32_t* startMonth, diff --git a/src/native/libs/System.Globalization.Native/pal_calendarData.m b/src/native/libs/System.Globalization.Native/pal_calendarData.m index 63fea4ed6970b..3b07a0bc13faa 100644 --- a/src/native/libs/System.Globalization.Native/pal_calendarData.m +++ b/src/native/libs/System.Globalization.Native/pal_calendarData.m @@ -11,15 +11,6 @@ #endif #if defined(TARGET_MACCATALYST) || defined(TARGET_IOS) || defined(TARGET_TVOS) -#define GREGORIAN_NAME "gregorian" -#define JAPANESE_NAME "japanese" -#define BUDDHIST_NAME "buddhist" -#define HEBREW_NAME "hebrew" -#define DANGI_NAME "dangi" -#define PERSIAN_NAME "persian" -#define ISLAMIC_NAME "islamic" -#define ISLAMIC_UMALQURA_NAME "islamic-umalqura" -#define ROC_NAME "roc" /* Function: @@ -218,7 +209,7 @@ int32_t GlobalizationNative_GetJapaneseEraStartDateNative(int32_t era, int32_t* startDateComponents.day = 1; startDateComponents.year = 1; NSDate *date = [japaneseCalendar dateFromComponents:startDateComponents]; - NSDate *startDate = date; + // NSDate *startDate = date; int32_t currentEra; for (int month = 0; month <= 12; month++) @@ -238,9 +229,9 @@ int32_t GlobalizationNative_GetJapaneseEraStartDateNative(int32_t era, int32_t* { // add back 1 day to get back into the specified Era startDateComponents.day = startDateComponents.day + 1; - startDate = [japaneseCalendar dateFromComponents:startDateComponents]; + date = [japaneseCalendar dateFromComponents:startDateComponents]; NSCalendar *gregorianCalendar = [[NSCalendar alloc] initWithCalendarIdentifier:NSCalendarIdentifierGregorian]; - NSDateComponents *components = [gregorianCalendar components:NSCalendarUnitDay | NSCalendarUnitMonth | NSCalendarUnitYear fromDate:startDate]; + NSDateComponents *components = [gregorianCalendar components:NSCalendarUnitDay | NSCalendarUnitMonth | NSCalendarUnitYear fromDate:date]; *startYear = [components year]; *startMonth = [components month]; *startDay = [components day]; @@ -265,12 +256,10 @@ int32_t GlobalizationNative_GetJapaneseEraStartDateNative(int32_t era, int32_t* Returns the list of CalendarIds that are available for the specified locale. */ -int32_t GlobalizationNative_GetCalendarsNative(const char* localeName, CalendarId* calendars, int32_t calendarsCapacity) +int32_t GlobalizationNative_GetCalendarsNative(CalendarId* calendars, int32_t calendarsCapacity) { @autoreleasepool { - NSString *locName = [NSString stringWithFormat:@"%s", localeName]; - NSLocale *currentLocale = [[NSLocale alloc] initWithLocaleIdentifier:locName]; NSArray *calendarIdentifiers = @[ NSCalendarIdentifierGregorian, NSCalendarIdentifierBuddhist, From 8ba1be56399d041b0cb18f3e71e9526920d3b1ab Mon Sep 17 00:00:00 2001 From: Meri Khamoyan Date: Mon, 25 Sep 2023 18:10:22 +0200 Subject: [PATCH 05/10] Remove commented code --- src/native/libs/System.Globalization.Native/pal_calendarData.m | 1 - 1 file changed, 1 deletion(-) diff --git a/src/native/libs/System.Globalization.Native/pal_calendarData.m b/src/native/libs/System.Globalization.Native/pal_calendarData.m index 3b07a0bc13faa..59f25a4f01fe0 100644 --- a/src/native/libs/System.Globalization.Native/pal_calendarData.m +++ b/src/native/libs/System.Globalization.Native/pal_calendarData.m @@ -209,7 +209,6 @@ int32_t GlobalizationNative_GetJapaneseEraStartDateNative(int32_t era, int32_t* startDateComponents.day = 1; startDateComponents.year = 1; NSDate *date = [japaneseCalendar dateFromComponents:startDateComponents]; - // NSDate *startDate = date; int32_t currentEra; for (int month = 0; month <= 12; month++) From d5d95b8eedd82531c5f783e760b5477451280430 Mon Sep 17 00:00:00 2001 From: Meri Khamoyan Date: Wed, 4 Oct 2023 17:49:21 +0200 Subject: [PATCH 06/10] Fix default calendar for locales --- src/libraries/Common/src/Interop/Interop.Calendar.iOS.cs | 2 +- .../tests/DateTimeFormatInfo/DateTimeFormatInfoTests.cs | 4 ++-- .../src/System/Globalization/CalendarData.Icu.cs | 2 +- .../libs/System.Globalization.Native/pal_calendarData.h | 3 ++- .../libs/System.Globalization.Native/pal_calendarData.m | 9 ++++++++- 5 files changed, 14 insertions(+), 6 deletions(-) diff --git a/src/libraries/Common/src/Interop/Interop.Calendar.iOS.cs b/src/libraries/Common/src/Interop/Interop.Calendar.iOS.cs index 8c567076fda12..985e55b604e4f 100644 --- a/src/libraries/Common/src/Interop/Interop.Calendar.iOS.cs +++ b/src/libraries/Common/src/Interop/Interop.Calendar.iOS.cs @@ -10,7 +10,7 @@ internal static partial class Interop internal static partial class Globalization { [LibraryImport(Libraries.GlobalizationNative, EntryPoint = "GlobalizationNative_GetCalendarsNative", StringMarshalling = StringMarshalling.Utf8)] - internal static partial int GetCalendarsNative(CalendarId[] calendars, int calendarsCapacity); + internal static partial int GetCalendarsNative(string localeName, CalendarId[] calendars, int calendarsCapacity); [LibraryImport(Libraries.GlobalizationNative, EntryPoint = "GlobalizationNative_GetCalendarInfoNative", StringMarshalling = StringMarshalling.Utf8)] internal static partial string GetCalendarInfoNative(string localeName, CalendarId calendarId, CalendarDataType calendarDataType); diff --git a/src/libraries/System.Globalization/tests/DateTimeFormatInfo/DateTimeFormatInfoTests.cs b/src/libraries/System.Globalization/tests/DateTimeFormatInfo/DateTimeFormatInfoTests.cs index eacdfb0455a67..af6aef3802d2b 100644 --- a/src/libraries/System.Globalization/tests/DateTimeFormatInfo/DateTimeFormatInfoTests.cs +++ b/src/libraries/System.Globalization/tests/DateTimeFormatInfo/DateTimeFormatInfoTests.cs @@ -67,7 +67,7 @@ public void NativeCalendarName_Get_ReturnsExpected(DateTimeFormatInfo dtfi, Cale { dtfi.Calendar = calendar; - if (PlatformDetection.IsNotUsingLimitedCultures) + if (PlatformDetection.IsNotUsingLimitedCultures && !PlatformDetection.IsHybridGlobalizationOnOSX) { // Mobile / Browser ICU doesn't contain NativeCalendarName, Assert.Equal(nativeCalendarName, dtfi.NativeCalendarName); @@ -75,7 +75,7 @@ public void NativeCalendarName_Get_ReturnsExpected(DateTimeFormatInfo dtfi, Cale } catch { - if (PlatformDetection.IsNlsGlobalization) + if (PlatformDetection.IsNlsGlobalization || PlatformDetection.IsHybridGlobalizationOnOSX) { // Persian calendar is recently supported as one of the optional calendars for fa-IR Assert.True(calendar is PersianCalendar, "Exception can occur only with PersianCalendar"); diff --git a/src/libraries/System.Private.CoreLib/src/System/Globalization/CalendarData.Icu.cs b/src/libraries/System.Private.CoreLib/src/System/Globalization/CalendarData.Icu.cs index f3d05eeb49357..f3a71c6bc9910 100644 --- a/src/libraries/System.Private.CoreLib/src/System/Globalization/CalendarData.Icu.cs +++ b/src/libraries/System.Private.CoreLib/src/System/Globalization/CalendarData.Icu.cs @@ -92,7 +92,7 @@ internal static int IcuGetCalendars(string localeName, CalendarId[] calendars) int count; #if TARGET_MACCATALYST || TARGET_IOS || TARGET_TVOS if (GlobalizationMode.Hybrid) - count = Interop.Globalization.GetCalendarsNative(calendars, calendars.Length); + count = Interop.Globalization.GetCalendarsNative(localeName, calendars, calendars.Length); else count = Interop.Globalization.GetCalendars(localeName, calendars, calendars.Length); #else diff --git a/src/native/libs/System.Globalization.Native/pal_calendarData.h b/src/native/libs/System.Globalization.Native/pal_calendarData.h index 9fe5f3c5d2335..ab725f7f65df1 100644 --- a/src/native/libs/System.Globalization.Native/pal_calendarData.h +++ b/src/native/libs/System.Globalization.Native/pal_calendarData.h @@ -107,7 +107,8 @@ PALEXPORT const char* GlobalizationNative_GetCalendarInfoNative(const char* loca CalendarId calendarId, CalendarDataType dataType); -PALEXPORT int32_t GlobalizationNative_GetCalendarsNative(CalendarId* calendars, +PALEXPORT int32_t GlobalizationNative_GetCalendarsNative(const char* localeName, + CalendarId* calendars, int32_t calendarsCapacity); PALEXPORT int32_t GlobalizationNative_GetLatestJapaneseEraNative(void); diff --git a/src/native/libs/System.Globalization.Native/pal_calendarData.m b/src/native/libs/System.Globalization.Native/pal_calendarData.m index 59f25a4f01fe0..eb2057dd8260c 100644 --- a/src/native/libs/System.Globalization.Native/pal_calendarData.m +++ b/src/native/libs/System.Globalization.Native/pal_calendarData.m @@ -255,7 +255,7 @@ int32_t GlobalizationNative_GetJapaneseEraStartDateNative(int32_t era, int32_t* Returns the list of CalendarIds that are available for the specified locale. */ -int32_t GlobalizationNative_GetCalendarsNative(CalendarId* calendars, int32_t calendarsCapacity) +int32_t GlobalizationNative_GetCalendarsNative(const char* localeName, CalendarId* calendars, int32_t calendarsCapacity) { @autoreleasepool { @@ -277,10 +277,17 @@ int32_t GlobalizationNative_GetCalendarsNative(CalendarId* calendars, int32_t ca NSCalendarIdentifierPersian, NSCalendarIdentifierRepublicOfChina, ]; + + NSString *locName = [NSString stringWithFormat:@"%s", localeName]; + NSLocale *currentLocale = [[NSLocale alloc] initWithLocaleIdentifier:locName]; + NSString *defaultCalendarIdentifier = [currentLocale calendarIdentifier]; int32_t calendarCount = MIN(calendarIdentifiers.count, calendarsCapacity); + calendars[0] = GetCalendarId([defaultCalendarIdentifier UTF8String]); for (int i = 0; i < calendarCount; i++) { NSString *calendarIdentifier = calendarIdentifiers[i]; + if (calendarIdentifier == defaultCalendarIdentifier) + continue; calendars[i] = GetCalendarId([calendarIdentifier UTF8String]); } return calendarCount; From 5a7675d257e8063578c950aba7318deb59a48386 Mon Sep 17 00:00:00 2001 From: Meri Khamoyan Date: Wed, 4 Oct 2023 18:44:55 +0200 Subject: [PATCH 07/10] Fix DateTimeFormatInfo test --- .../tests/DateTimeFormatInfo/DateTimeFormatInfoTests.cs | 4 ++-- .../libs/System.Globalization.Native/pal_calendarData.m | 5 +++-- 2 files changed, 5 insertions(+), 4 deletions(-) diff --git a/src/libraries/System.Globalization/tests/DateTimeFormatInfo/DateTimeFormatInfoTests.cs b/src/libraries/System.Globalization/tests/DateTimeFormatInfo/DateTimeFormatInfoTests.cs index af6aef3802d2b..eacdfb0455a67 100644 --- a/src/libraries/System.Globalization/tests/DateTimeFormatInfo/DateTimeFormatInfoTests.cs +++ b/src/libraries/System.Globalization/tests/DateTimeFormatInfo/DateTimeFormatInfoTests.cs @@ -67,7 +67,7 @@ public void NativeCalendarName_Get_ReturnsExpected(DateTimeFormatInfo dtfi, Cale { dtfi.Calendar = calendar; - if (PlatformDetection.IsNotUsingLimitedCultures && !PlatformDetection.IsHybridGlobalizationOnOSX) + if (PlatformDetection.IsNotUsingLimitedCultures) { // Mobile / Browser ICU doesn't contain NativeCalendarName, Assert.Equal(nativeCalendarName, dtfi.NativeCalendarName); @@ -75,7 +75,7 @@ public void NativeCalendarName_Get_ReturnsExpected(DateTimeFormatInfo dtfi, Cale } catch { - if (PlatformDetection.IsNlsGlobalization || PlatformDetection.IsHybridGlobalizationOnOSX) + if (PlatformDetection.IsNlsGlobalization) { // Persian calendar is recently supported as one of the optional calendars for fa-IR Assert.True(calendar is PersianCalendar, "Exception can occur only with PersianCalendar"); diff --git a/src/native/libs/System.Globalization.Native/pal_calendarData.m b/src/native/libs/System.Globalization.Native/pal_calendarData.m index eb2057dd8260c..08f5865900b85 100644 --- a/src/native/libs/System.Globalization.Native/pal_calendarData.m +++ b/src/native/libs/System.Globalization.Native/pal_calendarData.m @@ -282,13 +282,14 @@ int32_t GlobalizationNative_GetCalendarsNative(const char* localeName, CalendarI NSLocale *currentLocale = [[NSLocale alloc] initWithLocaleIdentifier:locName]; NSString *defaultCalendarIdentifier = [currentLocale calendarIdentifier]; int32_t calendarCount = MIN(calendarIdentifiers.count, calendarsCapacity); - calendars[0] = GetCalendarId([defaultCalendarIdentifier UTF8String]); + int32_t calendarIndex = 0; + calendars[calendarIndex++] = GetCalendarId([defaultCalendarIdentifier UTF8String]); for (int i = 0; i < calendarCount; i++) { NSString *calendarIdentifier = calendarIdentifiers[i]; if (calendarIdentifier == defaultCalendarIdentifier) continue; - calendars[i] = GetCalendarId([calendarIdentifier UTF8String]); + calendars[calendarIndex++] = GetCalendarId([calendarIdentifier UTF8String]); } return calendarCount; } From b04b27e45a291664128a66b505a338a3a7bed6fe Mon Sep 17 00:00:00 2001 From: Meri Khamoyan Date: Thu, 5 Oct 2023 17:50:27 +0200 Subject: [PATCH 08/10] refactor as requested by review --- .../src/System/Globalization/JapaneseCalendar.Icu.cs | 7 +------ 1 file changed, 1 insertion(+), 6 deletions(-) diff --git a/src/libraries/System.Private.CoreLib/src/System/Globalization/JapaneseCalendar.Icu.cs b/src/libraries/System.Private.CoreLib/src/System/Globalization/JapaneseCalendar.Icu.cs index 09d347c728470..dc9204fa99c8c 100644 --- a/src/libraries/System.Private.CoreLib/src/System/Globalization/JapaneseCalendar.Icu.cs +++ b/src/libraries/System.Private.CoreLib/src/System/Globalization/JapaneseCalendar.Icu.cs @@ -86,16 +86,11 @@ public partial class JapaneseCalendar : Calendar } else { - string[]? abbrevEraNames; - if (!CalendarData.EnumCalendarInfo("ja", CalendarId.JAPAN, CalendarDataType.AbbrevEraNames, out abbrevEraNames)) + if (!CalendarData.EnumCalendarInfo("ja", CalendarId.JAPAN, CalendarDataType.AbbrevEraNames, out abbrevEnglishEraNames!)) { // Failed to get English names. fallback to hardcoded data. abbrevEnglishEraNames = s_abbreviatedEnglishEraNames; } - else - { - abbrevEnglishEraNames = abbrevEraNames ?? s_abbreviatedEnglishEraNames; - } } #else if (!CalendarData.EnumCalendarInfo("ja", CalendarId.JAPAN, CalendarDataType.AbbrevEraNames, out abbrevEnglishEraNames!)) From 33f6a7ec45a957734c20ed2d95503e732ed51c36 Mon Sep 17 00:00:00 2001 From: Meri Khamoyan Date: Fri, 6 Oct 2023 10:49:24 +0200 Subject: [PATCH 09/10] Refactor GlobalizationNative_GetCalendarsNative --- .../System.Globalization.Native/pal_calendarData.m | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/src/native/libs/System.Globalization.Native/pal_calendarData.m b/src/native/libs/System.Globalization.Native/pal_calendarData.m index 08f5865900b85..e02f9ebc945e1 100644 --- a/src/native/libs/System.Globalization.Native/pal_calendarData.m +++ b/src/native/libs/System.Globalization.Native/pal_calendarData.m @@ -283,13 +283,15 @@ int32_t GlobalizationNative_GetCalendarsNative(const char* localeName, CalendarI NSString *defaultCalendarIdentifier = [currentLocale calendarIdentifier]; int32_t calendarCount = MIN(calendarIdentifiers.count, calendarsCapacity); int32_t calendarIndex = 0; - calendars[calendarIndex++] = GetCalendarId([defaultCalendarIdentifier UTF8String]); + CalendarId defaultCalendarId = GetCalendarId([defaultCalendarIdentifier UTF8String]); + // If the default calendar is not supported, return the Gregorian calendar as the default. + calendars[calendarIndex++] = defaultCalendarId == UNINITIALIZED_VALUE ? GREGORIAN : defaultCalendarId; for (int i = 0; i < calendarCount; i++) { - NSString *calendarIdentifier = calendarIdentifiers[i]; - if (calendarIdentifier == defaultCalendarIdentifier) + CalendarId calendarId = GetCalendarId([calendarIdentifiers[i] UTF8String]); + if (calendarId == UNINITIALIZED_VALUE || calendarId == defaultCalendarId) continue; - calendars[calendarIndex++] = GetCalendarId([calendarIdentifier UTF8String]); + calendars[calendarIndex++] = calendarId; } return calendarCount; } From b17c33a333bc8d416491f7bedc5f0c13bb1f74f5 Mon Sep 17 00:00:00 2001 From: Meri Khamoyan Date: Mon, 9 Oct 2023 10:05:33 +0200 Subject: [PATCH 10/10] Remove not used calendar types --- .../System.Globalization.Native/pal_calendarData.m | 10 ---------- 1 file changed, 10 deletions(-) diff --git a/src/native/libs/System.Globalization.Native/pal_calendarData.m b/src/native/libs/System.Globalization.Native/pal_calendarData.m index e02f9ebc945e1..f401a03e4afc0 100644 --- a/src/native/libs/System.Globalization.Native/pal_calendarData.m +++ b/src/native/libs/System.Globalization.Native/pal_calendarData.m @@ -66,8 +66,6 @@ static CalendarId GetCalendarId(const char* calendarName) return THAI; else if (strcasecmp(calendarName, HEBREW_NAME) == 0) return HEBREW; - else if (strcasecmp(calendarName, DANGI_NAME) == 0) - return KOREA; else if (strcasecmp(calendarName, PERSIAN_NAME) == 0) return PERSIAN; else if (strcasecmp(calendarName, ISLAMIC_NAME) == 0) @@ -262,15 +260,7 @@ int32_t GlobalizationNative_GetCalendarsNative(const char* localeName, CalendarI NSArray *calendarIdentifiers = @[ NSCalendarIdentifierGregorian, NSCalendarIdentifierBuddhist, - NSCalendarIdentifierChinese, - NSCalendarIdentifierCoptic, - NSCalendarIdentifierEthiopicAmeteMihret, - NSCalendarIdentifierEthiopicAmeteAlem, NSCalendarIdentifierHebrew, - NSCalendarIdentifierISO8601, - NSCalendarIdentifierIndian, - NSCalendarIdentifierIslamicCivil, - NSCalendarIdentifierIslamicTabular, NSCalendarIdentifierIslamicUmmAlQura, NSCalendarIdentifierIslamic, NSCalendarIdentifierJapanese,