private bool LoadCalendarDataFromSystemCore(string localeName, CalendarId calendarId) { Debug.Assert(!GlobalizationMode.Invariant); if (GlobalizationMode.UseNls) { return(NlsLoadCalendarDataFromSystem(localeName, calendarId)); } // If running using ICU on Windows we should honor user overrides using NLS and the rest from ICU bool result = IcuLoadCalendarDataFromSystem(localeName, calendarId); if (result && bUseUserOverrides) { NormalizeCalendarId(ref calendarId, ref localeName); result &= CallGetCalendarInfoEx(localeName, calendarId, CAL_ITWODIGITYEARMAX, out this.iTwoDigitYearMax); // They want user overrides, see if the user calendar matches the input calendar CalendarId userCalendar = (CalendarId)CultureData.GetLocaleInfoExInt(localeName, LOCALE_ICALENDARTYPE); // If the calendars were the same, see if the locales were the same if (userCalendar == calendarId) { string?shortDateOverride = CultureData.ReescapeWin32String(CultureData.GetLocaleInfoEx(localeName, LOCALE_SSHORTDATE)); string?longDateOverride = CultureData.ReescapeWin32String(CultureData.GetLocaleInfoEx(localeName, LOCALE_SLONGDATE)); InsertOrSwapOverride(shortDateOverride, ref this.saShortDates); InsertOrSwapOverride(longDateOverride, ref this.saLongDates); } } return(result); }
private bool NlsLoadCalendarDataFromSystem(string localeName, CalendarId calendarId) { bool ret = true; uint useOverrides = bUseUserOverrides ? 0 : CAL_NOUSEROVERRIDE; NormalizeCalendarId(ref calendarId, ref localeName); // Numbers ret &= CallGetCalendarInfoEx(localeName, calendarId, CAL_ITWODIGITYEARMAX | useOverrides, out this.iTwoDigitYearMax); // Strings ret &= CallGetCalendarInfoEx(localeName, calendarId, CAL_SCALNAME, out this.sNativeName); ret &= CallGetCalendarInfoEx(localeName, calendarId, CAL_SMONTHDAY, out this.sMonthDay); // String Arrays // Formats ret &= CallEnumCalendarInfo(localeName, calendarId, CAL_SSHORTDATE, LOCALE_SSHORTDATE | useOverrides, out this.saShortDates !); ret &= CallEnumCalendarInfo(localeName, calendarId, CAL_SLONGDATE, LOCALE_SLONGDATE | useOverrides, out this.saLongDates !); // Get the YearMonth pattern. ret &= CallEnumCalendarInfo(localeName, calendarId, CAL_SYEARMONTH, LOCALE_SYEARMONTH, out this.saYearMonths !); // Day & Month Names // These are all single calType entries, 1 per day, so we have to make 7 or 13 calls to collect all the names // Day // Note that we're off-by-one since managed starts on sunday and windows starts on monday ret &= GetCalendarDayInfo(localeName, calendarId, CAL_SDAYNAME7, out this.saDayNames); ret &= GetCalendarDayInfo(localeName, calendarId, CAL_SABBREVDAYNAME7, out this.saAbbrevDayNames); // Month names ret &= GetCalendarMonthInfo(localeName, calendarId, CAL_SMONTHNAME1, out this.saMonthNames); ret &= GetCalendarMonthInfo(localeName, calendarId, CAL_SABBREVMONTHNAME1, out this.saAbbrevMonthNames); // // The following LCTYPE are not supported in some platforms. If the call fails, // don't return a failure. // GetCalendarDayInfo(localeName, calendarId, CAL_SSHORTESTDAYNAME7, out this.saSuperShortDayNames); // Gregorian may have genitive month names if (calendarId == CalendarId.GREGORIAN) { GetCalendarMonthInfo(localeName, calendarId, CAL_SMONTHNAME1 | CAL_RETURN_GENITIVE_NAMES, out this.saMonthGenitiveNames); GetCalendarMonthInfo(localeName, calendarId, CAL_SABBREVMONTHNAME1 | CAL_RETURN_GENITIVE_NAMES, out this.saAbbrevMonthGenitiveNames); } // Calendar Parts Names // This doesn't get always get localized names for gregorian (not available in windows < 7) // so: eg: coreclr on win < 7 won't get these CallEnumCalendarInfo(localeName, calendarId, CAL_SERASTRING, 0, out this.saEraNames !); CallEnumCalendarInfo(localeName, calendarId, CAL_SABBREVERASTRING, 0, out this.saAbbrevEraNames !); // // Calendar Era Info // Note that calendar era data (offsets, etc) is hard coded for each calendar since this // data is implementation specific and not dynamic (except perhaps Japanese) // // Clean up the escaping of the formats this.saShortDates = CultureData.ReescapeWin32Strings(this.saShortDates) !; this.saLongDates = CultureData.ReescapeWin32Strings(this.saLongDates) !; this.saYearMonths = CultureData.ReescapeWin32Strings(this.saYearMonths) !; this.sMonthDay = CultureData.ReescapeWin32String(this.sMonthDay) !; return(ret); }
// // Get a bunch of data for a calendar // internal CalendarData(String localeName, int calendarId, bool bUseUserOverrides) { // Call nativeGetCalendarData to populate the data this.bUseUserOverrides = bUseUserOverrides; if (!nativeGetCalendarData(this, localeName, calendarId)) { Contract.Assert(false, "[CalendarData] nativeGetCalendarData call isn't expected to fail for calendar " + calendarId + " locale " + localeName); // Something failed, try invariant for missing parts // This is really not good, but we don't want the callers to crash. if (this.sNativeName == null) { this.sNativeName = String.Empty; // Calendar Name for the locale. } // Formats if (this.saShortDates == null) { this.saShortDates = Invariant.saShortDates; // Short Data format, default first } if (this.saYearMonths == null) { this.saYearMonths = Invariant.saYearMonths; // Year/Month Data format, default first } if (this.saLongDates == null) { this.saLongDates = Invariant.saLongDates; // Long Data format, default first } if (this.sMonthDay == null) { this.sMonthDay = Invariant.sMonthDay; // Month/Day format } // Calendar Parts Names if (this.saEraNames == null) { this.saEraNames = Invariant.saEraNames; // Names of Eras } if (this.saAbbrevEraNames == null) { this.saAbbrevEraNames = Invariant.saAbbrevEraNames; // Abbreviated Era Names } if (this.saAbbrevEnglishEraNames == null) { this.saAbbrevEnglishEraNames = Invariant.saAbbrevEnglishEraNames; // Abbreviated Era Names in English } if (this.saDayNames == null) { this.saDayNames = Invariant.saDayNames; // Day Names, null to use locale data, starts on Sunday } if (this.saAbbrevDayNames == null) { this.saAbbrevDayNames = Invariant.saAbbrevDayNames; // Abbrev Day Names, null to use locale data, starts on Sunday } if (this.saSuperShortDayNames == null) { this.saSuperShortDayNames = Invariant.saSuperShortDayNames; // Super short Day of week names } if (this.saMonthNames == null) { this.saMonthNames = Invariant.saMonthNames; // Month Names (13) } if (this.saAbbrevMonthNames == null) { this.saAbbrevMonthNames = Invariant.saAbbrevMonthNames; // Abbrev Month Names (13) } // Genitive and Leap names can follow the fallback below } // Clean up the escaping of the formats this.saShortDates = CultureData.ReescapeWin32Strings(this.saShortDates); this.saLongDates = CultureData.ReescapeWin32Strings(this.saLongDates); this.saYearMonths = CultureData.ReescapeWin32Strings(this.saYearMonths); this.sMonthDay = CultureData.ReescapeWin32String(this.sMonthDay); if ((CalendarId)calendarId == CalendarId.TAIWAN) { if (CultureInfo.IsTaiwanSku) { // We got the month/day names from the OS (same as gregorian), but the native name is wrong this.sNativeName = "\x4e2d\x83ef\x6c11\x570b\x66c6"; } else { this.sNativeName = String.Empty; } } // Check for null genitive names (in case unmanaged side skips it for non-gregorian calendars, etc) if (this.saMonthGenitiveNames == null || String.IsNullOrEmpty(this.saMonthGenitiveNames[0])) { this.saMonthGenitiveNames = this.saMonthNames; // Genitive month names (same as month names for invariant) } if (this.saAbbrevMonthGenitiveNames == null || String.IsNullOrEmpty(this.saAbbrevMonthGenitiveNames[0])) { this.saAbbrevMonthGenitiveNames = this.saAbbrevMonthNames; // Abbreviated genitive month names (same as abbrev month names for invariant) } if (this.saLeapYearMonthNames == null || String.IsNullOrEmpty(this.saLeapYearMonthNames[0])) { this.saLeapYearMonthNames = this.saMonthNames; } InitializeEraNames(localeName, calendarId); InitializeAbbreviatedEraNames(localeName, calendarId); // Abbreviated English Era Names are only used for the Japanese calendar. if (calendarId == (int)CalendarId.JAPAN) { this.saAbbrevEnglishEraNames = JapaneseCalendar.EnglishEraNames(); } else { // For all others just use the an empty string (doesn't matter we'll never ask for it for other calendars) this.saAbbrevEnglishEraNames = new String[] { "" }; } // Japanese is the only thing with > 1 era. Its current era # is how many ever // eras are in the array. (And the others all have 1 string in the array) this.iCurrentEra = this.saEraNames.Length; }
private bool NlsLoadCalendarDataFromSystem(string localeName, CalendarId calendarId) { Debug.Assert(!GlobalizationMode.Invariant); Debug.Assert(GlobalizationMode.UseNls); bool ret = true; uint useOverrides = this.bUseUserOverrides ? 0 : CAL_NOUSEROVERRIDE; // // Windows doesn't support some calendars right now, so remap those. // switch (calendarId) { case CalendarId.JAPANESELUNISOLAR: // Data looks like Japanese calendarId = CalendarId.JAPAN; break; case CalendarId.JULIAN: // Data looks like gregorian US case CalendarId.CHINESELUNISOLAR: // Algorithmic, so actual data is irrelevent case CalendarId.SAKA: // reserved to match Office but not implemented in our code, so data is irrelevent case CalendarId.LUNAR_ETO_CHN: // reserved to match Office but not implemented in our code, so data is irrelevent case CalendarId.LUNAR_ETO_KOR: // reserved to match Office but not implemented in our code, so data is irrelevent case CalendarId.LUNAR_ETO_ROKUYOU: // reserved to match Office but not implemented in our code, so data is irrelevent case CalendarId.KOREANLUNISOLAR: // Algorithmic, so actual data is irrelevent case CalendarId.TAIWANLUNISOLAR: // Algorithmic, so actual data is irrelevent calendarId = CalendarId.GREGORIAN_US; break; } // // Special handling for some special calendar due to OS limitation. // This includes calendar like Taiwan calendar, UmAlQura calendar, etc. // CheckSpecialCalendar(ref calendarId, ref localeName); // Numbers ret &= CallGetCalendarInfoEx(localeName, calendarId, CAL_ITWODIGITYEARMAX | useOverrides, out this.iTwoDigitYearMax); // Strings ret &= CallGetCalendarInfoEx(localeName, calendarId, CAL_SCALNAME, out this.sNativeName); ret &= CallGetCalendarInfoEx(localeName, calendarId, CAL_SMONTHDAY | useOverrides, out this.sMonthDay); // String Arrays // Formats ret &= CallEnumCalendarInfo(localeName, calendarId, CAL_SSHORTDATE, LOCALE_SSHORTDATE | useOverrides, out this.saShortDates !); ret &= CallEnumCalendarInfo(localeName, calendarId, CAL_SLONGDATE, LOCALE_SLONGDATE | useOverrides, out this.saLongDates !); // Get the YearMonth pattern. ret &= CallEnumCalendarInfo(localeName, calendarId, CAL_SYEARMONTH, LOCALE_SYEARMONTH, out this.saYearMonths !); // Day & Month Names // These are all single calType entries, 1 per day, so we have to make 7 or 13 calls to collect all the names // Day // Note that we're off-by-one since managed starts on sunday and windows starts on monday ret &= GetCalendarDayInfo(localeName, calendarId, CAL_SDAYNAME7, out this.saDayNames); ret &= GetCalendarDayInfo(localeName, calendarId, CAL_SABBREVDAYNAME7, out this.saAbbrevDayNames); // Month names ret &= GetCalendarMonthInfo(localeName, calendarId, CAL_SMONTHNAME1, out this.saMonthNames); ret &= GetCalendarMonthInfo(localeName, calendarId, CAL_SABBREVMONTHNAME1, out this.saAbbrevMonthNames); // // The following LCTYPE are not supported in some platforms. If the call fails, // don't return a failure. // GetCalendarDayInfo(localeName, calendarId, CAL_SSHORTESTDAYNAME7, out this.saSuperShortDayNames); // Gregorian may have genitive month names if (calendarId == CalendarId.GREGORIAN) { GetCalendarMonthInfo(localeName, calendarId, CAL_SMONTHNAME1 | CAL_RETURN_GENITIVE_NAMES, out this.saMonthGenitiveNames); GetCalendarMonthInfo(localeName, calendarId, CAL_SABBREVMONTHNAME1 | CAL_RETURN_GENITIVE_NAMES, out this.saAbbrevMonthGenitiveNames); } // Calendar Parts Names // This doesn't get always get localized names for gregorian (not available in windows < 7) // so: eg: coreclr on win < 7 won't get these CallEnumCalendarInfo(localeName, calendarId, CAL_SERASTRING, 0, out this.saEraNames !); CallEnumCalendarInfo(localeName, calendarId, CAL_SABBREVERASTRING, 0, out this.saAbbrevEraNames !); // // Calendar Era Info // Note that calendar era data (offsets, etc) is hard coded for each calendar since this // data is implementation specific and not dynamic (except perhaps Japanese) // // Clean up the escaping of the formats this.saShortDates = CultureData.ReescapeWin32Strings(this.saShortDates) !; this.saLongDates = CultureData.ReescapeWin32Strings(this.saLongDates) !; this.saYearMonths = CultureData.ReescapeWin32Strings(this.saYearMonths) !; this.sMonthDay = CultureData.ReescapeWin32String(this.sMonthDay) !; return(ret); }
internal CalendarData(string localeName, int calendarId, bool bUseUserOverrides) { this.bUseUserOverrides = bUseUserOverrides; if (!CalendarData.nativeGetCalendarData(this, localeName, calendarId)) { if (this.sNativeName == null) { this.sNativeName = string.Empty; } if (this.saShortDates == null) { this.saShortDates = CalendarData.Invariant.saShortDates; } if (this.saYearMonths == null) { this.saYearMonths = CalendarData.Invariant.saYearMonths; } if (this.saLongDates == null) { this.saLongDates = CalendarData.Invariant.saLongDates; } if (this.sMonthDay == null) { this.sMonthDay = CalendarData.Invariant.sMonthDay; } if (this.saEraNames == null) { this.saEraNames = CalendarData.Invariant.saEraNames; } if (this.saAbbrevEraNames == null) { this.saAbbrevEraNames = CalendarData.Invariant.saAbbrevEraNames; } if (this.saAbbrevEnglishEraNames == null) { this.saAbbrevEnglishEraNames = CalendarData.Invariant.saAbbrevEnglishEraNames; } if (this.saDayNames == null) { this.saDayNames = CalendarData.Invariant.saDayNames; } if (this.saAbbrevDayNames == null) { this.saAbbrevDayNames = CalendarData.Invariant.saAbbrevDayNames; } if (this.saSuperShortDayNames == null) { this.saSuperShortDayNames = CalendarData.Invariant.saSuperShortDayNames; } if (this.saMonthNames == null) { this.saMonthNames = CalendarData.Invariant.saMonthNames; } if (this.saAbbrevMonthNames == null) { this.saAbbrevMonthNames = CalendarData.Invariant.saAbbrevMonthNames; } } this.saShortDates = CultureData.ReescapeWin32Strings(this.saShortDates); this.saLongDates = CultureData.ReescapeWin32Strings(this.saLongDates); this.saYearMonths = CultureData.ReescapeWin32Strings(this.saYearMonths); this.sMonthDay = CultureData.ReescapeWin32String(this.sMonthDay); if ((int)(ushort)calendarId == 4) { this.sNativeName = !CultureInfo.IsTaiwanSku ? string.Empty : "中華民國曆"; } if (this.saMonthGenitiveNames == null || string.IsNullOrEmpty(this.saMonthGenitiveNames[0])) { this.saMonthGenitiveNames = this.saMonthNames; } if (this.saAbbrevMonthGenitiveNames == null || string.IsNullOrEmpty(this.saAbbrevMonthGenitiveNames[0])) { this.saAbbrevMonthGenitiveNames = this.saAbbrevMonthNames; } if (this.saLeapYearMonthNames == null || string.IsNullOrEmpty(this.saLeapYearMonthNames[0])) { this.saLeapYearMonthNames = this.saMonthNames; } this.InitializeEraNames(localeName, calendarId); this.InitializeAbbreviatedEraNames(localeName, calendarId); if (calendarId == 3) { this.saAbbrevEnglishEraNames = JapaneseCalendar.EnglishEraNames(); } else { this.saAbbrevEnglishEraNames = new string[1] { "" } }; this.iCurrentEra = this.saEraNames.Length; }