Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/mono/corert.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
Diffstat (limited to 'src/System.Private.CoreLib/shared/System/Globalization/GregorianCalendarHelper.cs')
-rw-r--r--src/System.Private.CoreLib/shared/System/Globalization/GregorianCalendarHelper.cs129
1 files changed, 78 insertions, 51 deletions
diff --git a/src/System.Private.CoreLib/shared/System/Globalization/GregorianCalendarHelper.cs b/src/System.Private.CoreLib/shared/System/Globalization/GregorianCalendarHelper.cs
index 2842bd3a1..34206b380 100644
--- a/src/System.Private.CoreLib/shared/System/Globalization/GregorianCalendarHelper.cs
+++ b/src/System.Private.CoreLib/shared/System/Globalization/GregorianCalendarHelper.cs
@@ -19,9 +19,9 @@ namespace System.Globalization
// be affected by the DateTime.MinValue;
internal int maxEraYear; // Max year value in this era. (== the year length of the era + 1)
- internal String eraName; // The era name
- internal String abbrevEraName; // Abbreviated Era Name
- internal String englishEraName; // English era name
+ internal string eraName; // The era name
+ internal string abbrevEraName; // Abbreviated Era Name
+ internal string englishEraName; // English era name
internal EraInfo(int era, int startYear, int startMonth, int startDay, int yearOffset, int minEraYear, int maxEraYear)
{
@@ -33,7 +33,7 @@ namespace System.Globalization
}
internal EraInfo(int era, int startYear, int startMonth, int startDay, int yearOffset, int minEraYear, int maxEraYear,
- String eraName, String abbrevEraName, String englishEraName)
+ string eraName, string abbrevEraName, string englishEraName)
{
this.era = era;
this.yearOffset = yearOffset;
@@ -47,8 +47,8 @@ namespace System.Globalization
}
// This calendar recognizes two era values:
- // 0 CurrentEra (AD)
- // 1 BeforeCurrentEra (BC)
+ // 0 CurrentEra (AD)
+ // 1 BeforeCurrentEra (BC)
internal class GregorianCalendarHelper
{
// 1 tick = 100ns = 10E-7 second
@@ -87,7 +87,7 @@ namespace System.Globalization
//
// This is the max Gregorian year can be represented by DateTime class. The limitation
// is derived from DateTime class.
- //
+ //
internal int MaxYear
{
get
@@ -123,22 +123,19 @@ namespace System.Globalization
m_minYear = m_EraInfo[0].minEraYear; ;
}
- /*=================================GetGregorianYear==========================
- **Action: Get the Gregorian year value for the specified year in an era.
- **Returns: The Gregorian year value.
- **Arguments:
- ** year the year value in Japanese calendar
- ** era the Japanese emperor era value.
- **Exceptions:
- ** ArgumentOutOfRangeException if year value is invalid or era value is invalid.
- ============================================================================*/
-
- internal int GetGregorianYear(int year, int era)
+ // EraInfo.yearOffset: The offset to Gregorian year when the era starts. Gregorian Year = Era Year + yearOffset
+ // Era Year = Gregorian Year - yearOffset
+ // EraInfo.minEraYear: Min year value in this era. Generally, this value is 1, but this may be affected by the DateTime.MinValue;
+ // EraInfo.maxEraYear: Max year value in this era. (== the year length of the era + 1)
+ private int GetYearOffset(int year, int era, bool throwOnError)
{
if (year < 0)
{
- throw new ArgumentOutOfRangeException(nameof(year),
- SR.ArgumentOutOfRange_NeedNonNegNum);
+ if (throwOnError)
+ {
+ throw new ArgumentOutOfRangeException(nameof(year), SR.ArgumentOutOfRange_NeedNonNegNum);
+ }
+ return -1;
}
if (era == Calendar.CurrentEra)
@@ -150,48 +147,78 @@ namespace System.Globalization
{
if (era == m_EraInfo[i].era)
{
- if (year < m_EraInfo[i].minEraYear || year > m_EraInfo[i].maxEraYear)
+ if (year >= m_EraInfo[i].minEraYear)
+ {
+ if (year <= m_EraInfo[i].maxEraYear)
+ {
+ return m_EraInfo[i].yearOffset;
+ }
+ else if (!AppContextSwitches.EnforceJapaneseEraYearRanges)
+ {
+ // If we got the year number exceeding the era max year number, this still possible be valid as the date can be created before
+ // introducing new eras after the era we are checking. we'll loop on the eras after the era we have and ensure the year
+ // can exist in one of these eras. otherwise, we'll throw.
+ // Note, we always return the offset associated with the requested era.
+ //
+ // Here is some example:
+ // if we are getting the era number 4 (Heisei) and getting the year number 32. if the era 4 has year range from 1 to 31
+ // then year 32 exceeded the range of era 4 and we'll try to find out if the years difference (32 - 31 = 1) would lay in
+ // the subsequent eras (e.g era 5 and up)
+
+ int remainingYears = year - m_EraInfo[i].maxEraYear;
+
+ for (int j = i - 1; j >= 0; j--)
+ {
+ if (remainingYears <= m_EraInfo[j].maxEraYear)
+ {
+ return m_EraInfo[i].yearOffset;
+ }
+ remainingYears -= m_EraInfo[j].maxEraYear;
+ }
+ }
+ }
+
+ if (throwOnError)
{
throw new ArgumentOutOfRangeException(
nameof(year),
- String.Format(
+ string.Format(
CultureInfo.CurrentCulture,
SR.ArgumentOutOfRange_Range,
m_EraInfo[i].minEraYear,
m_EraInfo[i].maxEraYear));
}
- return (m_EraInfo[i].yearOffset + year);
+
+ break; // no need to iterate more on eras.
}
}
- throw new ArgumentOutOfRangeException(nameof(era), SR.ArgumentOutOfRange_InvalidEraValue);
- }
- internal bool IsValidYear(int year, int era)
- {
- if (year < 0)
+ if (throwOnError)
{
- return false;
+ throw new ArgumentOutOfRangeException(nameof(era), SR.ArgumentOutOfRange_InvalidEraValue);
}
+ return -1;
+ }
- if (era == Calendar.CurrentEra)
- {
- era = m_Cal.CurrentEraValue;
- }
+ /*=================================GetGregorianYear==========================
+ **Action: Get the Gregorian year value for the specified year in an era.
+ **Returns: The Gregorian year value.
+ **Arguments:
+ ** year the year value in Japanese calendar
+ ** era the Japanese emperor era value.
+ **Exceptions:
+ ** ArgumentOutOfRangeException if year value is invalid or era value is invalid.
+ ============================================================================*/
- for (int i = 0; i < m_EraInfo.Length; i++)
- {
- if (era == m_EraInfo[i].era)
- {
- if (year < m_EraInfo[i].minEraYear || year > m_EraInfo[i].maxEraYear)
- {
- return false;
- }
- return true;
- }
- }
- return false;
+ internal int GetGregorianYear(int year, int era)
+ {
+ return GetYearOffset(year, era, throwOnError: true) + year;
}
+ internal bool IsValidYear(int year, int era)
+ {
+ return GetYearOffset(year, era, throwOnError: false) >= 0;
+ }
// Returns a given date part of this DateTime. This method is used
// to compute the year, day-of-year, month, or day part.
@@ -297,7 +324,7 @@ namespace System.Globalization
{
throw new ArgumentOutOfRangeException(
nameof(millisecond),
- String.Format(
+ string.Format(
CultureInfo.CurrentCulture,
SR.ArgumentOutOfRange_Range,
0,
@@ -315,7 +342,7 @@ namespace System.Globalization
{
throw new ArgumentOutOfRangeException(
"time",
- String.Format(
+ string.Format(
CultureInfo.InvariantCulture,
SR.ArgumentOutOfRange_CalendarRange,
m_Cal.MinSupportedDateTime,
@@ -346,7 +373,7 @@ namespace System.Globalization
{
throw new ArgumentOutOfRangeException(
nameof(months),
- String.Format(
+ string.Format(
CultureInfo.CurrentCulture,
SR.ArgumentOutOfRange_Range,
-120000,
@@ -544,7 +571,7 @@ namespace System.Globalization
{
throw new ArgumentOutOfRangeException(
nameof(day),
- String.Format(
+ string.Format(
CultureInfo.CurrentCulture,
SR.ArgumentOutOfRange_Range,
1,
@@ -583,7 +610,7 @@ namespace System.Globalization
{
throw new ArgumentOutOfRangeException(
nameof(month),
- String.Format(
+ string.Format(
CultureInfo.CurrentCulture,
SR.ArgumentOutOfRange_Range,
1,
@@ -638,7 +665,7 @@ namespace System.Globalization
{
throw new ArgumentOutOfRangeException(
nameof(year),
- String.Format(
+ string.Format(
CultureInfo.CurrentCulture,
SR.ArgumentOutOfRange_Range, m_minYear, m_maxYear));
}