未验证 提交 c83324d3 编写于 作者: M Meri Khamoyan 提交者: GitHub

[iOS][non-icu] HybridGlobalization implement calendar data (#90004)

Implement calendar info for hybrid mode on iOS
上级 973626d3
......@@ -478,3 +478,34 @@ Below function are used from apple native functions:
- [uppercaseStringWithLocale](https://developer.apple.com/documentation/foundation/nsstring/1413316-uppercasestringwithlocale?language=objc)
- [lowercaseStringWithLocale](https://developer.apple.com/documentation/foundation/nsstring/1417298-lowercasestringwithlocale?language=objc)
## Calandars
Affected public APIs:
- DateTimeFormatInfo.AbbreviatedDayNames
- DateTimeFormatInfo.GetAbbreviatedDayName()
- DateTimeFormatInfo.AbbreviatedMonthGenitiveNames
- DateTimeFormatInfo.AbbreviatedMonthNames
- DateTimeFormatInfo.GetAbbreviatedMonthName()
- DateTimeFormatInfo.AMDesignator
- DateTimeFormatInfo.CalendarWeekRule
- DateTimeFormatInfo.DayNames
- DateTimeFormatInfo.GetDayName()
- DateTimeFormatInfo.GetEraName()
- DateTimeFormatInfo.FirstDayOfWeek
- DateTimeFormatInfo.FullDateTimePattern
- DateTimeFormatInfo.LongDatePattern
- DateTimeFormatInfo.LongTimePattern
- DateTimeFormatInfo.MonthDayPattern
- DateTimeFormatInfo.MonthGenitiveNames
- DateTimeFormatInfo.MonthNames
- DateTimeFormatInfo.GetMonthName()
- DateTimeFormatInfo.NativeCalendarName
- DateTimeFormatInfo.PMDesignator
- DateTimeFormatInfo.ShortDatePattern
- DateTimeFormatInfo.ShortestDayNames
- DateTimeFormatInfo.GetShortestDayName()
- DateTimeFormatInfo.ShortTimePattern
- DateTimeFormatInfo.YearMonthPattern
Apple Native API does not have an equivalent for abbreviated era name and will return empty string
- DateTimeFormatInfo.GetAbbreviatedEraName()
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.
using System;
using System.Globalization;
using System.Runtime.InteropServices;
internal static partial class Interop
{
internal static partial class Globalization
{
[LibraryImport(Libraries.GlobalizationNative, EntryPoint = "GlobalizationNative_GetCalendarInfoNative", StringMarshalling = StringMarshalling.Utf8)]
internal static partial string GetCalendarInfoNative(string localeName, CalendarId calendarId, CalendarDataType calendarDataType);
}
}
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFrameworks>$(NetCoreAppCurrent)-ios;$(NetCoreAppCurrent)-tvos;$(NetCoreAppCurrent)-maccatalyst</TargetFrameworks>
<TestRuntime>true</TestRuntime>
<HybridGlobalization>true</HybridGlobalization>
</PropertyGroup>
<ItemGroup>
<Compile Include="..\System\Globalization\CalendarTestBase.cs" />
<Compile Include="..\System\Globalization\ChineseLunisolarCalendarTests.cs" />
<Compile Include="..\System\Globalization\EastAsianLunisolarCalendarTestBase.cs" />
<Compile Include="..\System\Globalization\GregorianCalendarTests.cs" />
<Compile Include="..\System\Globalization\HebrewCalendarTests.cs" />
<Compile Include="..\System\Globalization\HijriCalendarTests.cs" />
<Compile Include="..\System\Globalization\JapaneseCalendarTests.cs" />
<Compile Include="..\System\Globalization\JapaneseLunisolarCalendarTests.cs" />
<Compile Include="..\System\Globalization\JulianCalendarTests.cs" />
<Compile Include="..\System\Globalization\KoreanCalendarTests.cs" />
<Compile Include="..\System\Globalization\KoreanLunisolarCalendarTests.cs" />
<Compile Include="..\System\Globalization\PersianCalendarTests.cs" />
<Compile Include="..\System\Globalization\TaiwanCalendarTests.cs" />
<Compile Include="..\System\Globalization\TaiwanLunisolarCalendarTests.cs" />
<Compile Include="..\System\Globalization\ThaiBuddhistCalendarTests.cs" />
<Compile Include="..\System\Globalization\UmAlQuraCalendarTests.cs" />
<Compile Include="..\GregorianCalendar\GregorianCalendarAddMonths.cs" />
<Compile Include="..\GregorianCalendar\GregorianCalendarAddYears.cs" />
<Compile Include="..\GregorianCalendar\GregorianCalendarGetDayOfMonth.cs" />
<Compile Include="..\GregorianCalendar\GregorianCalendarGetDayOfWeek.cs" />
<Compile Include="..\GregorianCalendar\GregorianCalendarGetDayOfYear.cs" />
<Compile Include="..\GregorianCalendar\GregorianCalendarGetDaysInMonth.cs" />
<Compile Include="..\GregorianCalendar\GregorianCalendarGetDaysInYear.cs" />
<Compile Include="..\GregorianCalendar\GregorianCalendarGetEra.cs" />
<Compile Include="..\GregorianCalendar\GregorianCalendarGetMonth.cs" />
<Compile Include="..\GregorianCalendar\GregorianCalendarGetLeapMonth.cs" />
<Compile Include="..\GregorianCalendar\GregorianCalendarGetMonthsInYear.cs" />
<Compile Include="..\GregorianCalendar\GregorianCalendarGetWeekOfYear.cs" />
<Compile Include="..\GregorianCalendar\GregorianCalendarGetYear.cs" />
<Compile Include="..\GregorianCalendar\GregorianCalendarIsLeapDay.cs" />
<Compile Include="..\GregorianCalendar\GregorianCalendarIsLeapMonth.cs" />
<Compile Include="..\GregorianCalendar\GregorianCalendarIsLeapYear.cs" />
<Compile Include="..\GregorianCalendar\GregorianCalendarTests.Utilities.cs" />
<Compile Include="..\GregorianCalendar\GregorianCalendarToDateTime.cs" />
<Compile Include="..\GregorianCalendar\GregorianCalendarToFourDigitYear.cs" />
<Compile Include="..\GregorianCalendar\GregorianCalendarTwoDigitYearMax.cs" />
<Compile Include="..\ISOWeek\ISOWeekTests.cs" />
<Compile Include="..\JapaneseCalendar\JapaneseCalendarAddMonths.cs" />
<Compile Include="..\JapaneseCalendar\JapaneseCalendarToFourDigitYear.cs" />
<Compile Include="..\JapaneseCalendar\JapaneseCalendarTwoDigitYearMax.cs" />
<Compile Include="..\KoreanCalendar\KoreanCalendarToDateTime.cs" />
<Compile Include="..\KoreanCalendar\KoreanCalendarAddMonths.cs" />
<Compile Include="..\KoreanCalendar\KoreanCalendarAddYears.cs" />
<Compile Include="..\KoreanCalendar\KoreanCalendarGetDayOfMonth.cs" />
<Compile Include="..\KoreanCalendar\KoreanCalendarGetDayOfWeek.cs" />
<Compile Include="..\KoreanCalendar\KoreanCalendarGetDayOfYear.cs" />
<Compile Include="..\KoreanCalendar\KoreanCalendarGetDaysInMonth.cs" />
<Compile Include="..\KoreanCalendar\KoreanCalendarGetDaysInYear.cs" />
<Compile Include="..\KoreanCalendar\KoreanCalendarGetEra.cs" />
<Compile Include="..\KoreanCalendar\KoreanCalendarGetMonth.cs" />
<Compile Include="..\KoreanCalendar\KoreanCalendarGetMonthsInYear.cs" />
<Compile Include="..\KoreanCalendar\KoreanCalendarGetWeekOfYear.cs" />
<Compile Include="..\KoreanCalendar\KoreanCalendarGetYear.cs" />
<Compile Include="..\KoreanCalendar\KoreanCalendarIsLeapDay.cs" />
<Compile Include="..\KoreanCalendar\KoreanCalendarIsLeapMonth.cs" />
<Compile Include="..\KoreanCalendar\KoreanCalendarIsLeapYear.cs" />
<Compile Include="..\KoreanCalendar\KoreanCalendarToFourDigitYear.cs" />
<Compile Include="..\KoreanCalendar\KoreanCalendarTwoDigitYearMax.cs" />
<Compile Include="..\Misc\MiscCalendars.cs" />
<Compile Include="..\Misc\Calendars.cs" />
<Compile Include="..\TaiwanCalendar\TaiwanCalendarUtilities.cs" />
<Compile Include="..\TaiwanCalendar\TaiwanCalendarAddMonths.cs" />
<Compile Include="..\TaiwanCalendar\TaiwanCalendarAddYears.cs" />
<Compile Include="..\TaiwanCalendar\TaiwanCalendarDaysAndMonths.cs" />
<Compile Include="..\TaiwanCalendar\TaiwanCalendarGetDayOfMonth.cs" />
<Compile Include="..\TaiwanCalendar\TaiwanCalendarGetDayOfWeek.cs" />
<Compile Include="..\TaiwanCalendar\TaiwanCalendarGetDayOfYear.cs" />
<Compile Include="..\TaiwanCalendar\TaiwanCalendarGetDaysInMonth.cs" />
<Compile Include="..\TaiwanCalendar\TaiwanCalendarGetDaysInYear.cs" />
<Compile Include="..\TaiwanCalendar\TaiwanCalendarGetEra.cs" />
<Compile Include="..\TaiwanCalendar\TaiwanCalendarGetMonth.cs" />
<Compile Include="..\TaiwanCalendar\TaiwanCalendarGetMonthsInYear.cs" />
<Compile Include="..\TaiwanCalendar\TaiwanCalendarGetWeekOfYear.cs" />
<Compile Include="..\TaiwanCalendar\TaiwanCalendarGetYear.cs" />
<Compile Include="..\TaiwanCalendar\TaiwanCalendarIsLeapDay.cs" />
<Compile Include="..\TaiwanCalendar\TaiwanCalendarIsLeapMonth.cs" />
<Compile Include="..\TaiwanCalendar\TaiWanCalendarIsLeapYear.cs" />
<Compile Include="..\TaiwanCalendar\TaiwanCalendarToDateTime.cs" />
<Compile Include="..\TaiwanCalendar\TaiwanCalendarToFourDigitYear.cs" />
<Compile Include="..\TaiwanCalendar\TaiwanCalendarTwoDigitYearMax.cs" />
<Compile Include="..\ThaiBuddhistCalendar\ThaiBuddhistCalendarAddMonths.cs" />
<Compile Include="..\ThaiBuddhistCalendar\ThaiBuddhistCalendarAddYears.cs" />
<Compile Include="..\ThaiBuddhistCalendar\ThaiBuddhistCalendarGetDayOfMonth.cs" />
<Compile Include="..\ThaiBuddhistCalendar\ThaiBuddhistCalendarGetDayOfWeek.cs" />
<Compile Include="..\ThaiBuddhistCalendar\ThaiBuddhistCalendarGetDayOfYear.cs" />
<Compile Include="..\ThaiBuddhistCalendar\ThaiBuddhistCalendarGetDaysInMonth.cs" />
<Compile Include="..\ThaiBuddhistCalendar\ThaiBuddhistCalendarGetDaysInYear.cs" />
<Compile Include="..\ThaiBuddhistCalendar\ThaiBuddhistCalendarGetEra.cs" />
<Compile Include="..\ThaiBuddhistCalendar\ThaiBuddhistCalendarGetMonth.cs" />
<Compile Include="..\ThaiBuddhistCalendar\ThaiBuddhistCalendarGetMonthsInYear.cs" />
<Compile Include="..\ThaiBuddhistCalendar\ThaiBuddhistCalendarGetWeekOfYear.cs" />
<Compile Include="..\ThaiBuddhistCalendar\ThaiBuddhistCalendarGetYear.cs" />
<Compile Include="..\ThaiBuddhistCalendar\ThaiBuddhistCalendarIsLeapDay.cs" />
<Compile Include="..\ThaiBuddhistCalendar\ThaiBuddhistCalendarIsLeapMonth.cs" />
<Compile Include="..\ThaiBuddhistCalendar\ThaiBuddhistCalendarIsLeapYear.cs" />
<Compile Include="..\ThaiBuddhistCalendar\ThaiBuddhistCalendarToDateTime.cs" />
<Compile Include="..\ThaiBuddhistCalendar\ThaiBuddhistCalendarToFourDigitYear.cs" />
<Compile Include="..\ThaiBuddhistCalendar\ThaiBuddhistCalendarTwoDigitYearMax.cs" />
<Compile Include="$(CommonTestPath)System\RandomDataGenerator.cs" />
</ItemGroup>
</Project>
\ No newline at end of file
......@@ -430,7 +430,7 @@ public void GetEra_Invalid_ThrowsArgumentOutOfRangeException()
Assert.All(DateTime_TestData(calendar), dt =>
{
// JapaneseCalendar throws on ICU, but not on NLS
if ((calendar is JapaneseCalendar && PlatformDetection.IsNlsGlobalization) ||
if ((calendar is JapaneseCalendar && (PlatformDetection.IsNlsGlobalization || PlatformDetection.IsHybridGlobalizationOnOSX)) ||
calendar is HebrewCalendar ||
calendar is TaiwanLunisolarCalendar ||
calendar is JapaneseLunisolarCalendar)
......
......@@ -18,9 +18,39 @@
<Compile Include="..\CompareInfo\CompareInfoTests.IsPrefix.cs" />
<Compile Include="..\CompareInfo\CompareInfoTests.IsSuffix.cs" />
<Compile Include="..\CompareInfo\CompareInfoTests.LastIndexOf.cs" />
<Compile Include="..\DateTimeFormatInfo\DateTimeFormatInfoAbbreviatedDayNames.cs" />
<Compile Include="..\DateTimeFormatInfo\DateTimeFormatInfoAbbreviatedMonthGenitiveNames.cs" />
<Compile Include="..\DateTimeFormatInfo\DateTimeFormatInfoAbbreviatedMonthNames.cs" />
<Compile Include="..\DateTimeFormatInfo\DateTimeFormatInfoAMDesignator.cs" />
<Compile Include="..\DateTimeFormatInfo\DateTimeFormatInfoCalendar.cs" />
<Compile Include="..\DateTimeFormatInfo\DateTimeFormatInfoCalendarWeekRule.cs" />
<Compile Include="..\DateTimeFormatInfo\DateTimeFormatInfoClone.cs" />
<Compile Include="..\DateTimeFormatInfo\DateTimeFormatInfoData.cs" />
<Compile Include="..\DateTimeFormatInfo\DateTimeFormatInfoDayNames.cs" />
<Compile Include="..\DateTimeFormatInfo\DateTimeFormatInfoFirstDayOfWeek.cs" />
<Compile Include="..\DateTimeFormatInfo\DateTimeFormatInfoFullDateTimePattern.cs" />
<Compile Include="..\DateTimeFormatInfo\DateTimeFormatInfoGetAbbreviatedDayName.cs" />
<Compile Include="..\DateTimeFormatInfo\DateTimeFormatInfoGetAbbreviatedMonthName.cs" />
<Compile Include="..\DateTimeFormatInfo\DateTimeFormatInfoGetDayName.cs" />
<Compile Include="..\DateTimeFormatInfo\DateTimeFormatInfoGetEraName.cs" />
<Compile Include="..\DateTimeFormatInfo\DateTimeFormatInfoGetFormat.cs" />
<Compile Include="..\DateTimeFormatInfo\DateTimeFormatInfoGetInstance.cs" />
<Compile Include="..\DateTimeFormatInfo\DateTimeFormatInfoGetMonthName.cs" />
<Compile Include="..\DateTimeFormatInfo\DateTimeFormatInfoLongDatePattern.cs" />
<Compile Include="..\DateTimeFormatInfo\DateTimeFormatInfoLongTimePattern.cs" />
<Compile Include="..\DateTimeFormatInfo\DateTimeFormatInfoMonthDayPattern.cs" />
<Compile Include="..\DateTimeFormatInfo\DateTimeFormatInfoMonthGenitiveNames.cs" />
<Compile Include="..\DateTimeFormatInfo\DateTimeFormatInfoMonthNames.cs" />
<Compile Include="..\DateTimeFormatInfo\DateTimeFormatInfoPMDesignator.cs" />
<Compile Include="..\DateTimeFormatInfo\DateTimeFormatInfoReadOnly.cs" />
<Compile Include="..\DateTimeFormatInfo\DateTimeFormatInfoRFC1123Pattern.cs" />
<Compile Include="..\DateTimeFormatInfo\DateTimeFormatInfoShortDatePattern.cs" />
<Compile Include="..\DateTimeFormatInfo\DateTimeFormatInfoShortestDayNames.cs" />
<Compile Include="..\DateTimeFormatInfo\DateTimeFormatInfoShortTimePattern.cs" />
<Compile Include="..\DateTimeFormatInfo\DateTimeFormatInfoSortableDateTimePattern.cs" />
<Compile Include="..\DateTimeFormatInfo\DateTimeFormatInfoTests.cs" />
<Compile Include="..\DateTimeFormatInfo\DateTimeFormatInfoUniversalSortableDateTimePattern.cs" />
<Compile Include="..\DateTimeFormatInfo\DateTimeFormatInfoYearMonthPattern.cs" />
<Compile Include="..\NumberFormatInfo\NumberFormatInfoCurrencySymbol.cs" />
<Compile Include="..\NumberFormatInfo\NumberFormatInfoData.cs" />
<Compile Include="..\NumberFormatInfo\NumberFormatInfoNaNSymbol.cs" />
......
......@@ -320,6 +320,7 @@
<Compile Include="$(MSBuildThisFileDirectory)System\Globalization\CalendarAlgorithmType.cs" />
<Compile Include="$(MSBuildThisFileDirectory)System\Globalization\CalendarData.cs" />
<Compile Include="$(MSBuildThisFileDirectory)System\Globalization\CalendarData.Browser.cs" Condition="'$(TargetsBrowser)' == 'true'" />
<Compile Include="$(MSBuildThisFileDirectory)System\Globalization\CalendarData.iOS.cs" Condition="'$(IsiOSLike)' == 'true'" />
<Compile Include="$(MSBuildThisFileDirectory)System\Globalization\CalendarData.Icu.cs" />
<Compile Include="$(MSBuildThisFileDirectory)System\Globalization\CalendarData.Nls.cs" />
<Compile Include="$(MSBuildThisFileDirectory)System\Globalization\CalendarWeekRule.cs" />
......@@ -1295,6 +1296,9 @@
<Compile Include="$(CommonPath)Interop\Interop.Calendar.cs">
<Link>Common\Interop\Interop.Calendar.cs</Link>
</Compile>
<Compile Include="$(CommonPath)Interop\Interop.Calendar.iOS.cs" Condition="'$(IsiOSLike)' == 'true'">
<Link>Common\Interop\Interop.Calendar.iOS.cs</Link>
</Compile>
<Compile Include="$(CommonPath)Interop\Interop.Casing.cs">
<Link>Common\Interop\Interop.Casing.cs</Link>
</Compile>
......
......@@ -13,6 +13,10 @@ private bool LoadCalendarDataFromSystemCore(string localeName, CalendarId calend
return GlobalizationMode.Hybrid ?
JSLoadCalendarDataFromBrowser(localeName, calendarId) :
IcuLoadCalendarDataFromSystem(localeName, calendarId);
#elif TARGET_MACCATALYST || TARGET_IOS || TARGET_TVOS
return GlobalizationMode.Hybrid ?
LoadCalendarDataFromNative(localeName, calendarId) :
IcuLoadCalendarDataFromSystem(localeName, calendarId);
#else
return IcuLoadCalendarDataFromSystem(localeName, calendarId);
#endif
......
// 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;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
using System.Text;
namespace System.Globalization
{
internal sealed partial class CalendarData
{
private bool LoadCalendarDataFromNative(string localeName, CalendarId calendarId)
{
Debug.Assert(!GlobalizationMode.UseNls);
sNativeName = GetCalendarInfoNative(localeName, calendarId, CalendarDataType.NativeName);
sMonthDay = GetCalendarInfoNative(localeName, calendarId, CalendarDataType.MonthDay);
saShortDates = GetCalendarInfoNative(localeName, calendarId, CalendarDataType.ShortDates).Split("||");
saLongDates = GetCalendarInfoNative(localeName, calendarId, CalendarDataType.LongDates).Split("||");
saYearMonths = GetCalendarInfoNative(localeName, calendarId, CalendarDataType.YearMonths).Split("||");
saDayNames = GetCalendarInfoNative(localeName, calendarId, CalendarDataType.DayNames).Split("||");
saAbbrevDayNames = GetCalendarInfoNative(localeName, calendarId, CalendarDataType.AbbrevDayNames).Split("||");
saSuperShortDayNames = GetCalendarInfoNative(localeName, calendarId, CalendarDataType.SuperShortDayNames).Split("||");
string? leapHebrewMonthName = null;
saMonthNames = NormalizeMonthArray(GetCalendarInfoNative(localeName, calendarId, CalendarDataType.MonthNames).Split("||"), calendarId, ref leapHebrewMonthName);
if (leapHebrewMonthName != null)
{
Debug.Assert(saMonthNames != null);
// In Hebrew calendar, get the leap month name Adar II and override the non-leap month 7
Debug.Assert(calendarId == CalendarId.HEBREW && saMonthNames.Length == 13);
saLeapYearMonthNames = (string[]) saMonthNames.Clone();
saLeapYearMonthNames[6] = leapHebrewMonthName;
// The returned data has 6th month name as 'Adar I' and 7th month name as 'Adar'
// We need to adjust that in the list used with non-leap year to have 6th month as 'Adar' and 7th month as 'Adar II'
// note that when formatting non-leap year dates, 7th month shouldn't get used at all.
saMonthNames[5] = saMonthNames[6];
saMonthNames[6] = leapHebrewMonthName;
}
saAbbrevMonthNames = NormalizeMonthArray(GetCalendarInfoNative(localeName, calendarId, CalendarDataType.AbbrevMonthNames).Split("||"), calendarId, ref leapHebrewMonthName);
saMonthGenitiveNames = NormalizeMonthArray(GetCalendarInfoNative(localeName, calendarId, CalendarDataType.MonthGenitiveNames).Split("||"), calendarId, ref leapHebrewMonthName);
saAbbrevMonthGenitiveNames = NormalizeMonthArray(GetCalendarInfoNative(localeName, calendarId, CalendarDataType.AbbrevMonthGenitiveNames).Split("||"), calendarId, ref leapHebrewMonthName);
saEraNames = NormalizeEraNames(calendarId, GetCalendarInfoNative(localeName, calendarId, CalendarDataType.EraNames).Split("||"));
saAbbrevEraNames = Array.Empty<string>();
return sNativeName != null && saShortDates != null && saLongDates != null && saYearMonths != null &&
saDayNames != null && saAbbrevDayNames != null && saSuperShortDayNames != null && saMonthNames != null &&
saAbbrevMonthNames != null && saMonthGenitiveNames != null && saAbbrevMonthGenitiveNames != null &&
saEraNames != null && saAbbrevEraNames != null;
}
private static string[] NormalizeEraNames(CalendarId calendarId, string[]? eraNames)
{
// .NET expects that only the Japanese calendars have more than 1 era.
// So for other calendars, only return the latest era.
if (calendarId != CalendarId.JAPAN && calendarId != CalendarId.JAPANESELUNISOLAR && eraNames?.Length > 0)
return new string[] { eraNames![eraNames.Length - 1] };
return eraNames ?? Array.Empty<string>();
}
private static string[] NormalizeMonthArray(string[] months, CalendarId calendarId, ref string? leapHebrewMonthName)
{
if (months.Length == 13)
return months;
string[] normalizedMonths = new string[13];
// the month-name arrays are expected to have 13 elements. If only returns 12, add an
// extra empty string to fill the array.
if (months.Length == 12)
{
normalizedMonths[12] = "";
months.CopyTo(normalizedMonths, 0);
return normalizedMonths;
}
if (months.Length > 13)
{
Debug.Assert(calendarId == CalendarId.HEBREW && months.Length == 14);
if (calendarId == CalendarId.HEBREW)
{
leapHebrewMonthName = months[13];
}
for (int i = 0; i < 13; i++)
{
normalizedMonths[i] = months[i];
}
return normalizedMonths;
}
throw new Exception("CalendarData.GetCalendarInfoNative() returned an unexpected number of month names.");
}
private static string GetCalendarInfoNative(string localeName, CalendarId calendarId, CalendarDataType calendarDataType)
{
Debug.Assert(localeName != null);
return Interop.Globalization.GetCalendarInfoNative(localeName, calendarId, calendarDataType);
}
}
}
......@@ -72,7 +72,8 @@ if(HAVE_SYS_ICU)
${icu_shim_sources_base}
pal_locale.m
pal_collation.m
pal_casing.m)
pal_casing.m
pal_calendarData.m)
endif()
addprefix(icu_shim_sources "${ICU_SHIM_PATH}" "${icu_shim_sources_base}")
......
......@@ -93,8 +93,8 @@ else()
endif()
if (CLR_CMAKE_TARGET_APPLE)
set(NATIVEGLOBALIZATION_SOURCES ${NATIVEGLOBALIZATION_SOURCES} pal_locale.m pal_collation.m pal_casing.m)
set_source_files_properties(pal_locale.m pal_collation.m pal_casing.m PROPERTIES COMPILE_FLAGS ${CLR_CMAKE_COMMON_OBJC_FLAGS})
set(NATIVEGLOBALIZATION_SOURCES ${NATIVEGLOBALIZATION_SOURCES} pal_locale.m pal_collation.m pal_casing.m pal_calendarData.m)
set_source_files_properties(pal_locale.m pal_collation.m pal_casing.m pal_calendarData.m PROPERTIES COMPILE_FLAGS ${CLR_CMAKE_COMMON_OBJC_FLAGS})
endif()
# time zone names are filtered out of icu data for the browser and associated functionality is disabled
......
......@@ -63,6 +63,7 @@ static const Entry s_globalizationNative[] =
DllImportEntry(GlobalizationNative_ChangeCaseNative)
DllImportEntry(GlobalizationNative_CompareStringNative)
DllImportEntry(GlobalizationNative_EndsWithNative)
DllImportEntry(GlobalizationNative_GetCalendarInfoNative)
DllImportEntry(GlobalizationNative_GetLocaleInfoIntNative)
DllImportEntry(GlobalizationNative_GetLocaleInfoPrimaryGroupingSizeNative)
DllImportEntry(GlobalizationNative_GetLocaleInfoSecondaryGroupingSizeNative)
......
......@@ -91,3 +91,9 @@ PALEXPORT int32_t GlobalizationNative_GetJapaneseEraStartDate(int32_t era,
int32_t* startYear,
int32_t* startMonth,
int32_t* startDay);
#ifdef __APPLE__
PALEXPORT const char* GlobalizationNative_GetCalendarInfoNative(const char* localeName,
CalendarId calendarId,
CalendarDataType dataType);
#endif
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.
#include <assert.h>
#include "pal_icushim_internal.h"
#include "pal_calendarData.h"
#import <Foundation/Foundation.h>
#if defined(TARGET_MACCATALYST) || defined(TARGET_IOS) || defined(TARGET_TVOS)
/*
Function:
GetCalendarIdentifier
Gets the associated NSCalendarIdentifier for the CalendarId.
*/
static NSString* GetCalendarIdentifier(CalendarId calendarId)
{
NSString *calendarIdentifier = NSCalendarIdentifierGregorian;
switch (calendarId)
{
case JAPAN:
calendarIdentifier = NSCalendarIdentifierJapanese;
break;
case THAI:
calendarIdentifier = NSCalendarIdentifierBuddhist;
break;
case HEBREW:
calendarIdentifier = NSCalendarIdentifierHebrew;
break;
case PERSIAN:
calendarIdentifier = NSCalendarIdentifierPersian;
break;
case HIJRI:
calendarIdentifier = NSCalendarIdentifierIslamic;
break;
case UMALQURA:
calendarIdentifier = NSCalendarIdentifierIslamicUmmAlQura;
break;
case TAIWAN:
calendarIdentifier = NSCalendarIdentifierRepublicOfChina;
break;
default:
break;
}
return calendarIdentifier;
}
/*
Function:
GlobalizationNative_GetCalendarInfoNative
Gets a single string of calendar information for a given locale, calendar, and calendar data type.
with the requested value.
*/
const char* GlobalizationNative_GetCalendarInfoNative(const char* localeName, CalendarId calendarId, CalendarDataType dataType)
{
NSString *locName = [NSString stringWithFormat:@"%s", localeName];
NSLocale *currentLocale = [[NSLocale alloc] initWithLocaleIdentifier:locName];
if (dataType == CalendarData_MonthDay)
{
NSString *formatString = [NSDateFormatter dateFormatFromTemplate:@"MMMMd" options:0 locale:currentLocale];
return formatString ? strdup([formatString UTF8String]) : NULL;
}
else if (dataType == CalendarData_YearMonths)
{
NSString *formatString = [NSDateFormatter dateFormatFromTemplate:@"MMMM yyyy" options:0 locale:currentLocale];
return formatString ? strdup([formatString UTF8String]) : NULL;
}
NSString *calendarIdentifier = GetCalendarIdentifier(calendarId);
NSCalendar *calendar = [[NSCalendar alloc] initWithCalendarIdentifier:calendarIdentifier];
if (dataType == CalendarData_NativeName)
return calendar ? strdup([[calendar calendarIdentifier] UTF8String]) : NULL;
NSDateFormatter *dateFormat = [[NSDateFormatter alloc] init];
dateFormat.locale = currentLocale;
dateFormat.calendar = calendar;
NSArray *result;
switch (dataType)
{
case CalendarData_ShortDates:
{
[dateFormat setDateStyle:NSDateFormatterShortStyle];
NSString *shortFormatString = [dateFormat dateFormat];
[dateFormat setDateStyle:NSDateFormatterMediumStyle];
NSString *mediumFormatString = [dateFormat dateFormat];
NSString *yearMonthDayFormat = [NSDateFormatter dateFormatFromTemplate:@"yMd" options:0 locale:currentLocale];
result = @[shortFormatString, mediumFormatString, yearMonthDayFormat];
break;
}
case CalendarData_LongDates:
{
[dateFormat setDateStyle:NSDateFormatterLongStyle];
NSString *longFormatString = [dateFormat dateFormat];
[dateFormat setDateStyle:NSDateFormatterFullStyle];
NSString *fullFormatString = [dateFormat dateFormat];
result = @[longFormatString, fullFormatString];
break;
}
case CalendarData_DayNames:
result = [dateFormat standaloneWeekdaySymbols];
break;
case CalendarData_AbbrevDayNames:
result = [dateFormat shortStandaloneWeekdaySymbols];
break;
case CalendarData_MonthNames:
result = [dateFormat standaloneMonthSymbols];
break;
case CalendarData_AbbrevMonthNames:
result = [dateFormat shortStandaloneMonthSymbols];
break;
case CalendarData_SuperShortDayNames:
result = [dateFormat veryShortStandaloneWeekdaySymbols];
break;
case CalendarData_MonthGenitiveNames:
result = [dateFormat monthSymbols];
break;
case CalendarData_AbbrevMonthGenitiveNames:
result = [dateFormat shortMonthSymbols];
break;
case CalendarData_EraNames:
case CalendarData_AbbrevEraNames:
result = [dateFormat eraSymbols];
break;
default:
assert(false);
return NULL;
}
NSString *arrayToString = [[result valueForKey:@"description"] componentsJoinedByString:@"||"];
return arrayToString ? strdup([arrayToString UTF8String]) : NULL;
}
#endif
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册