summaryrefslogtreecommitdiff
path: root/src/mscorlib
diff options
context:
space:
mode:
authorStephen Toub <stoub@microsoft.com>2017-06-15 11:31:12 -0400
committerStephen Toub <stoub@microsoft.com>2017-06-15 11:31:12 -0400
commit17c23bed6395f3e12dc0b4471b2bb566c3aa136c (patch)
treee37c963852272d488ab5f062cc1713292e077e98 /src/mscorlib
parentb5914c8d1b20be898b8982a4dfcf9d8e9046b2ec (diff)
downloadcoreclr-17c23bed6395f3e12dc0b4471b2bb566c3aa136c.tar.gz
coreclr-17c23bed6395f3e12dc0b4471b2bb566c3aa136c.tar.bz2
coreclr-17c23bed6395f3e12dc0b4471b2bb566c3aa136c.zip
Avoid duplicated compuations with DateTime.GetDatePart
- Remove duplicate code in GregorianCalendar. GetDatePart is identical to the implementation in DateTime. Just reuse it via the Year/Month/Day properties. Also avoids an unnecessary virtual call. - Then copy GetDatePart into a version that returns year/month/day rather than just one of them. - And use that in several places throughout corelib where all three are retrieved, avoiding redoing all of the calculations three times.
Diffstat (limited to 'src/mscorlib')
-rw-r--r--src/mscorlib/shared/System/DateTime.cs49
-rw-r--r--src/mscorlib/shared/System/Globalization/DateTimeFormat.cs14
-rw-r--r--src/mscorlib/shared/System/Globalization/HebrewCalendar.cs4
-rw-r--r--src/mscorlib/shared/System/Globalization/UmAlQuraCalendar.cs4
-rw-r--r--src/mscorlib/src/System/Globalization/GregorianCalendar.cs69
-rw-r--r--src/mscorlib/src/System/TimeZoneInfo.TransitionTime.cs3
6 files changed, 63 insertions, 80 deletions
diff --git a/src/mscorlib/shared/System/DateTime.cs b/src/mscorlib/shared/System/DateTime.cs
index 4fd9727fcd..16a75fdfa6 100644
--- a/src/mscorlib/shared/System/DateTime.cs
+++ b/src/mscorlib/shared/System/DateTime.cs
@@ -453,9 +453,7 @@ namespace System
{
if (months < -120000 || months > 120000) throw new ArgumentOutOfRangeException(nameof(months), SR.ArgumentOutOfRange_DateTimeBadMonths);
Contract.EndContractBlock();
- int y = GetDatePart(DatePartYear);
- int m = GetDatePart(DatePartMonth);
- int d = GetDatePart(DatePartDay);
+ GetDatePart(out int y, out int m, out int d);
int i = m - 1 + months;
if (i >= 0)
{
@@ -859,6 +857,51 @@ namespace System
return n - days[m - 1] + 1;
}
+ // Exactly the same as GetDatePart(int part), except computing all of
+ // year/month/day rather than just one of them. Used when all three
+ // are needed rather than redoing the computations for each.
+ internal void GetDatePart(out int year, out int month, out int day)
+ {
+ Int64 ticks = InternalTicks;
+ // n = number of days since 1/1/0001
+ int n = (int)(ticks / TicksPerDay);
+ // y400 = number of whole 400-year periods since 1/1/0001
+ int y400 = n / DaysPer400Years;
+ // n = day number within 400-year period
+ n -= y400 * DaysPer400Years;
+ // y100 = number of whole 100-year periods within 400-year period
+ int y100 = n / DaysPer100Years;
+ // Last 100-year period has an extra day, so decrement result if 4
+ if (y100 == 4) y100 = 3;
+ // n = day number within 100-year period
+ n -= y100 * DaysPer100Years;
+ // y4 = number of whole 4-year periods within 100-year period
+ int y4 = n / DaysPer4Years;
+ // n = day number within 4-year period
+ n -= y4 * DaysPer4Years;
+ // y1 = number of whole years within 4-year period
+ int y1 = n / DaysPerYear;
+ // Last year has an extra day, so decrement result if 4
+ if (y1 == 4) y1 = 3;
+ // compute year
+ year = y400 * 400 + y100 * 100 + y4 * 4 + y1 + 1;
+ // n = day number within year
+ n -= y1 * DaysPerYear;
+ // dayOfYear = n + 1;
+ // Leap year calculation looks different from IsLeapYear since y1, y4,
+ // and y100 are relative to year 1, not year 0
+ bool leapYear = y1 == 3 && (y4 != 24 || y100 == 3);
+ int[] days = leapYear ? s_daysToMonth366 : s_daysToMonth365;
+ // All months have less than 32 days, so n >> 5 is a good conservative
+ // estimate for the month
+ int m = (n >> 5) + 1;
+ // m = 1-based month number
+ while (n >= days[m]) m++;
+ // compute month and day
+ month = m;
+ day = n - days[m - 1] + 1;
+ }
+
// Returns the day-of-month part of this DateTime. The returned
// value is an integer between 1 and 31.
//
diff --git a/src/mscorlib/shared/System/Globalization/DateTimeFormat.cs b/src/mscorlib/shared/System/Globalization/DateTimeFormat.cs
index 840409f55a..d6afc1b099 100644
--- a/src/mscorlib/shared/System/Globalization/DateTimeFormat.cs
+++ b/src/mscorlib/shared/System/Globalization/DateTimeFormat.cs
@@ -1059,14 +1059,15 @@ namespace System
dateTime = dateTime - offset;
}
+ dateTime.GetDatePart(out int year, out int month, out int day);
result.Append(InvariantAbbreviatedDayNames[(int)dateTime.DayOfWeek]);
result.Append(',');
result.Append(' ');
- AppendNumber(result, dateTime.Day, 2);
+ AppendNumber(result, day, 2);
result.Append(' ');
- result.Append(InvariantAbbreviatedMonthNames[dateTime.Month - 1]);
+ result.Append(InvariantAbbreviatedMonthNames[month - 1]);
result.Append(' ');
- AppendNumber(result, dateTime.Year, 4);
+ AppendNumber(result, year, 4);
result.Append(' ');
AppendHHmmssTimeOfDay(result, dateTime);
result.Append(' ');
@@ -1081,11 +1082,12 @@ namespace System
const int roundTripFormatLength = 28;
StringBuilder result = StringBuilderCache.Acquire(roundTripFormatLength);
- AppendNumber(result, dateTime.Year, 4);
+ dateTime.GetDatePart(out int year, out int month, out int day);
+ AppendNumber(result, year, 4);
result.Append('-');
- AppendNumber(result, dateTime.Month, 2);
+ AppendNumber(result, month, 2);
result.Append('-');
- AppendNumber(result, dateTime.Day, 2);
+ AppendNumber(result, day, 2);
result.Append('T');
AppendHHmmssTimeOfDay(result, dateTime);
result.Append('.');
diff --git a/src/mscorlib/shared/System/Globalization/HebrewCalendar.cs b/src/mscorlib/shared/System/Globalization/HebrewCalendar.cs
index 6ba4f082f1..92f4cab4be 100644
--- a/src/mscorlib/shared/System/Globalization/HebrewCalendar.cs
+++ b/src/mscorlib/shared/System/Globalization/HebrewCalendar.cs
@@ -536,9 +536,7 @@ namespace System.Globalization
//
// Save the Gregorian date values.
//
- gregorianYear = time.Year;
- gregorianMonth = time.Month;
- gregorianDay = time.Day;
+ time.GetDatePart(out gregorianYear, out gregorianMonth, out gregorianDay);
__DateBuffer lunarDate = new __DateBuffer(); // lunar month and day for Jan 1
diff --git a/src/mscorlib/shared/System/Globalization/UmAlQuraCalendar.cs b/src/mscorlib/shared/System/Globalization/UmAlQuraCalendar.cs
index c03ac23d95..99b99d67c0 100644
--- a/src/mscorlib/shared/System/Globalization/UmAlQuraCalendar.cs
+++ b/src/mscorlib/shared/System/Globalization/UmAlQuraCalendar.cs
@@ -331,9 +331,7 @@ namespace System.Globalization
}
dt = dt.AddDays(nDays);
- yg = dt.Year;
- mg = dt.Month;
- dg = dt.Day;
+ dt.GetDatePart(out yg, out mg, out dg);
}
/*=================================GetAbsoluteDateUmAlQura==========================
diff --git a/src/mscorlib/src/System/Globalization/GregorianCalendar.cs b/src/mscorlib/src/System/Globalization/GregorianCalendar.cs
index 9115b12bd0..707a9d01b1 100644
--- a/src/mscorlib/src/System/Globalization/GregorianCalendar.cs
+++ b/src/mscorlib/src/System/Globalization/GregorianCalendar.cs
@@ -21,12 +21,6 @@ namespace System.Globalization
public const int ADEra = 1;
-
- internal const int DatePartYear = 0;
- internal const int DatePartDayOfYear = 1;
- internal const int DatePartMonth = 2;
- internal const int DatePartDay = 3;
-
//
// This is the max Gregorian year can be represented by DateTime class. The limitation
// is derived from DateTime class.
@@ -161,57 +155,6 @@ namespace System.Globalization
}
- // Returns a given date part of this DateTime. This method is used
- // to compute the year, day-of-year, month, or day part.
- internal virtual int GetDatePart(long ticks, int part)
- {
- // n = number of days since 1/1/0001
- int n = (int)(ticks / TicksPerDay);
- // y400 = number of whole 400-year periods since 1/1/0001
- int y400 = n / DaysPer400Years;
- // n = day number within 400-year period
- n -= y400 * DaysPer400Years;
- // y100 = number of whole 100-year periods within 400-year period
- int y100 = n / DaysPer100Years;
- // Last 100-year period has an extra day, so decrement result if 4
- if (y100 == 4) y100 = 3;
- // n = day number within 100-year period
- n -= y100 * DaysPer100Years;
- // y4 = number of whole 4-year periods within 100-year period
- int y4 = n / DaysPer4Years;
- // n = day number within 4-year period
- n -= y4 * DaysPer4Years;
- // y1 = number of whole years within 4-year period
- int y1 = n / DaysPerYear;
- // Last year has an extra day, so decrement result if 4
- if (y1 == 4) y1 = 3;
- // If year was requested, compute and return it
- if (part == DatePartYear)
- {
- return (y400 * 400 + y100 * 100 + y4 * 4 + y1 + 1);
- }
- // n = day number within year
- n -= y1 * DaysPerYear;
- // If day-of-year was requested, return it
- if (part == DatePartDayOfYear)
- {
- return (n + 1);
- }
- // Leap year calculation looks different from IsLeapYear since y1, y4,
- // and y100 are relative to year 1, not year 0
- bool leapYear = (y1 == 3 && (y4 != 24 || y100 == 3));
- int[] days = leapYear ? DaysToMonth366 : DaysToMonth365;
- // All months have less than 32 days, so n >> 5 is a good conservative
- // estimate for the month
- int m = (n >> 5) + 1;
- // m = 1-based month number
- while (n >= days[m]) m++;
- // If month was requested, return it
- if (part == DatePartMonth) return (m);
- // Return 1-based day-of-month
- return (n - days[m - 1] + 1);
- }
-
/*=================================GetAbsoluteDate==========================
**Action: Gets the absolute date for the given Gregorian date. The absolute date means
** the number of days from January 1st, 1 A.D.
@@ -283,9 +226,7 @@ namespace System.Globalization
120000));
}
Contract.EndContractBlock();
- int y = GetDatePart(time.Ticks, DatePartYear);
- int m = GetDatePart(time.Ticks, DatePartMonth);
- int d = GetDatePart(time.Ticks, DatePartDay);
+ time.GetDatePart(out int y, out int m, out int d);
int i = m - 1 + months;
if (i >= 0)
{
@@ -331,7 +272,7 @@ namespace System.Globalization
public override int GetDayOfMonth(DateTime time)
{
- return (GetDatePart(time.Ticks, DatePartDay));
+ return time.Day;
}
// Returns the day-of-week part of the specified DateTime. The returned value
@@ -351,7 +292,7 @@ namespace System.Globalization
public override int GetDayOfYear(DateTime time)
{
- return (GetDatePart(time.Ticks, DatePartDayOfYear));
+ return time.DayOfYear;
}
// Returns the number of days in the month given by the year and
@@ -422,7 +363,7 @@ namespace System.Globalization
public override int GetMonth(DateTime time)
{
- return (GetDatePart(time.Ticks, DatePartMonth));
+ return time.Month;
}
// Returns the number of months in the specified year and era.
@@ -452,7 +393,7 @@ namespace System.Globalization
public override int GetYear(DateTime time)
{
- return (GetDatePart(time.Ticks, DatePartYear));
+ return time.Year;
}
// Checks whether a given day in the specified era is a leap day. This method returns true if
diff --git a/src/mscorlib/src/System/TimeZoneInfo.TransitionTime.cs b/src/mscorlib/src/System/TimeZoneInfo.TransitionTime.cs
index 0fe3dab0b6..90304c92ea 100644
--- a/src/mscorlib/src/System/TimeZoneInfo.TransitionTime.cs
+++ b/src/mscorlib/src/System/TimeZoneInfo.TransitionTime.cs
@@ -103,7 +103,8 @@ namespace System
}
Contract.EndContractBlock();
- if (timeOfDay.Year != 1 || timeOfDay.Month != 1 || timeOfDay.Day != 1 || (timeOfDay.Ticks % TimeSpan.TicksPerMillisecond != 0))
+ timeOfDay.GetDatePart(out int timeOfDayYear, out int timeOfDayMonth, out int timeOfDayDay);
+ if (timeOfDayYear != 1 || timeOfDayMonth != 1 || timeOfDayDay != 1 || (timeOfDay.Ticks % TimeSpan.TicksPerMillisecond != 0))
{
throw new ArgumentException(SR.Argument_DateTimeHasTicks, nameof(timeOfDay));
}