$"Parsing '{formattedDateWithGannen}' result should match if '{formattedDate}' has Gan-nen symbol"
);
}
+
+ [Fact]
+ public void JapaneseAbbreviatedEnglishEraNamesTest()
+ {
+ string [] eraNames = { "M", "T", "S", "H", "R" };
+
+ var ci = new CultureInfo("ja-JP") { DateTimeFormat = { Calendar = new JapaneseCalendar() }};
+
+ int eraNumber = ci.DateTimeFormat.GetEra("Q");
+ if (eraNumber == 4 || eraNumber == 5)
+ {
+ // Skip the test on Windows versions which have wrong Japanese Era information.
+ // Windows at some point used "Q" as fake era name before getting the official name.
+ return;
+ }
+
+ int numberOfErasToTest = Math.Min(eraNames.Length, ci.DateTimeFormat.Calendar.Eras.Length);
+ for (int i = 0; i < numberOfErasToTest; i++)
+ {
+ Assert.Equal(i + 1, ci.DateTimeFormat.GetEra(eraNames[i]));
+ }
+ }
}
}
{
public partial class JapaneseCalendar : Calendar
{
+ private static readonly string [] s_abbreviatedEnglishEraNames = { "M", "T", "S", "H", "R" };
+
private static EraInfo[]? IcuGetJapaneseEras()
{
if (GlobalizationMode.Invariant)
return null;
}
- string[]? abbrevEnglishEraNames;
- if (!CalendarData.EnumCalendarInfo("en", CalendarId.JAPAN, CalendarDataType.AbbrevEraNames, out abbrevEnglishEraNames))
- {
- return null;
- }
-
List<EraInfo> eras = new List<EraInfo>();
int lastMaxYear = GregorianCalendar.MaxYear;
int latestEra = Interop.Globalization.GetLatestJapaneseEra();
+
for (int i = latestEra; i >= 0; i--)
{
DateTime dt;
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), abbrevEnglishEraNames![i]));
+ 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;
+ if (!CalendarData.EnumCalendarInfo("ja", CalendarId.JAPAN, CalendarDataType.AbbrevEraNames, out abbrevEnglishEraNames!))
+ {
+ // 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();
{
/// <summary>
/// JapaneseCalendar is based on Gregorian calendar. The month and day values are the same as
- /// Gregorian calendar. However, the year value is an offset to the Gregorian
+ /// Gregorian calendar. However, the year value is an offset to the Gregorian
/// year based on the era.
///
/// This system is adopted by Emperor Meiji in 1868. The year value is counted based on the reign of an emperor,
/// and the era begins on the day an emperor ascends the throne and continues until his death.
/// The era changes at 12:00AM.
///
- /// For example, the current era is Reiwa. It started on 2019/5/1 A.D. Therefore, Gregorian year 2019 is also Reiwa 1st.
+ /// For example, the current era is Reiwa. It started on 2019/5/1 A.D. Therefore, Gregorian year 2019 is also Reiwa 1st.
/// 2019/5/1 A.D. is also Reiwa 1st 5/1.
///
- /// Any date in the year during which era is changed can be reckoned in either era. For example,
+ /// Any date in the year during which era is changed can be reckoned in either era. For example,
/// 2019/1/1 can be 1/1 Reiwa 1st year or 1/1 Heisei 31st year.
///
/// Note:
//
// We know about 4 built-in eras, however users may add additional era(s) from the
// registry, by adding values to HKLM\SYSTEM\CurrentControlSet\Control\Nls\Calendars\Japanese\Eras
- // we don't read the registry and instead we call WinRT to get the needed informatio
+ // we don't read the registry and instead we call WinRT to get the needed information
//
// Registry values look like:
// yyyy.mm.dd=era_abbrev_english_englishabbrev