mscorlib(4.0.0.0) API with additions
PersianCalendar.cs
1 namespace System.Globalization
2 {
5  public class PersianCalendar : Calendar
6  {
8  public static readonly int PersianEra = 1;
9 
10  internal static long PersianEpoch = new DateTime(622, 3, 22).Ticks / 864000000000L;
11 
12  private const int ApproximateHalfYear = 180;
13 
14  internal const int DatePartYear = 0;
15 
16  internal const int DatePartDayOfYear = 1;
17 
18  internal const int DatePartMonth = 2;
19 
20  internal const int DatePartDay = 3;
21 
22  internal const int MonthsPerYear = 12;
23 
24  internal static int[] DaysToMonth = new int[13]
25  {
26  0,
27  31,
28  62,
29  93,
30  124,
31  155,
32  186,
33  216,
34  246,
35  276,
36  306,
37  336,
38  366
39  };
40 
41  internal const int MaxCalendarYear = 9378;
42 
43  internal const int MaxCalendarMonth = 10;
44 
45  internal const int MaxCalendarDay = 13;
46 
47  internal static DateTime minDate = new DateTime(622, 3, 22);
48 
49  internal static DateTime maxDate = DateTime.MaxValue;
50 
51  private const int DEFAULT_TWO_DIGIT_YEAR_MAX = 1410;
52 
55  public override DateTime MinSupportedDateTime => minDate;
56 
59  public override DateTime MaxSupportedDateTime => maxDate;
60 
63  public override CalendarAlgorithmType AlgorithmType => CalendarAlgorithmType.SolarCalendar;
64 
65  internal override int BaseCalendarID => 1;
66 
67  internal override int ID => 22;
68 
71  public override int[] Eras => new int[1]
72  {
74  };
75 
80  public override int TwoDigitYearMax
81  {
82  get
83  {
84  if (twoDigitYearMax == -1)
85  {
86  twoDigitYearMax = Calendar.GetSystemTwoDigitYearSetting(ID, 1410);
87  }
88  return twoDigitYearMax;
89  }
90  set
91  {
92  VerifyWritable();
93  if (value < 99 || value > 9378)
94  {
95  throw new ArgumentOutOfRangeException("value", string.Format(CultureInfo.CurrentCulture, Environment.GetResourceString("ArgumentOutOfRange_Range"), 99, 9378));
96  }
97  twoDigitYearMax = value;
98  }
99  }
100 
101  private long GetAbsoluteDatePersian(int year, int month, int day)
102  {
103  if (year >= 1 && year <= 9378 && month >= 1 && month <= 12)
104  {
105  int num = DaysInPreviousMonths(month) + day - 1;
106  int num2 = (int)(365.242189 * (double)(year - 1));
107  long num3 = CalendricalCalculationsHelper.PersianNewYearOnOrBefore(PersianEpoch + num2 + 180);
108  return num3 + num;
109  }
110  throw new ArgumentOutOfRangeException(null, Environment.GetResourceString("ArgumentOutOfRange_BadYearMonthDay"));
111  }
112 
113  internal static void CheckTicksRange(long ticks)
114  {
115  if (ticks < minDate.Ticks || ticks > maxDate.Ticks)
116  {
117  throw new ArgumentOutOfRangeException("time", string.Format(CultureInfo.InvariantCulture, Environment.GetResourceString("ArgumentOutOfRange_CalendarRange"), minDate, maxDate));
118  }
119  }
120 
121  internal static void CheckEraRange(int era)
122  {
123  if (era != 0 && era != PersianEra)
124  {
125  throw new ArgumentOutOfRangeException("era", Environment.GetResourceString("ArgumentOutOfRange_InvalidEraValue"));
126  }
127  }
128 
129  internal static void CheckYearRange(int year, int era)
130  {
131  CheckEraRange(era);
132  if (year < 1 || year > 9378)
133  {
134  throw new ArgumentOutOfRangeException("year", string.Format(CultureInfo.CurrentCulture, Environment.GetResourceString("ArgumentOutOfRange_Range"), 1, 9378));
135  }
136  }
137 
138  internal static void CheckYearMonthRange(int year, int month, int era)
139  {
140  CheckYearRange(year, era);
141  if (year == 9378 && month > 10)
142  {
143  throw new ArgumentOutOfRangeException("month", string.Format(CultureInfo.CurrentCulture, Environment.GetResourceString("ArgumentOutOfRange_Range"), 1, 10));
144  }
145  if (month < 1 || month > 12)
146  {
147  throw new ArgumentOutOfRangeException("month", Environment.GetResourceString("ArgumentOutOfRange_Month"));
148  }
149  }
150 
151  private static int MonthFromOrdinalDay(int ordinalDay)
152  {
153  int i;
154  for (i = 0; ordinalDay > DaysToMonth[i]; i++)
155  {
156  }
157  return i;
158  }
159 
160  private static int DaysInPreviousMonths(int month)
161  {
162  month--;
163  return DaysToMonth[month];
164  }
165 
166  internal int GetDatePart(long ticks, int part)
167  {
168  CheckTicksRange(ticks);
169  long num = ticks / 864000000000L + 1;
170  long num2 = CalendricalCalculationsHelper.PersianNewYearOnOrBefore(num);
171  int num3 = (int)Math.Floor((double)(num2 - PersianEpoch) / 365.242189 + 0.5) + 1;
172  if (part == 0)
173  {
174  return num3;
175  }
176  int num4 = (int)(num - CalendricalCalculationsHelper.GetNumberOfDays(ToDateTime(num3, 1, 1, 0, 0, 0, 0, 1)));
177  if (part == 1)
178  {
179  return num4;
180  }
181  int num5 = MonthFromOrdinalDay(num4);
182  if (part == 2)
183  {
184  return num5;
185  }
186  int result = num4 - DaysInPreviousMonths(num5);
187  if (part == 3)
188  {
189  return result;
190  }
191  throw new InvalidOperationException(Environment.GetResourceString("InvalidOperation_DateTimeParsing"));
192  }
193 
201  public override DateTime AddMonths(DateTime time, int months)
202  {
203  if (months < -120000 || months > 120000)
204  {
205  throw new ArgumentOutOfRangeException("months", string.Format(CultureInfo.CurrentCulture, Environment.GetResourceString("ArgumentOutOfRange_Range"), -120000, 120000));
206  }
207  int datePart = GetDatePart(time.Ticks, 0);
208  int datePart2 = GetDatePart(time.Ticks, 2);
209  int num = GetDatePart(time.Ticks, 3);
210  int num2 = datePart2 - 1 + months;
211  if (num2 >= 0)
212  {
213  datePart2 = num2 % 12 + 1;
214  datePart += num2 / 12;
215  }
216  else
217  {
218  datePart2 = 12 + (num2 + 1) % 12;
219  datePart += (num2 - 11) / 12;
220  }
221  int daysInMonth = GetDaysInMonth(datePart, datePart2);
222  if (num > daysInMonth)
223  {
224  num = daysInMonth;
225  }
226  long ticks = GetAbsoluteDatePersian(datePart, datePart2, num) * 864000000000L + time.Ticks % 864000000000L;
227  Calendar.CheckAddResult(ticks, MinSupportedDateTime, MaxSupportedDateTime);
228  return new DateTime(ticks);
229  }
230 
238  public override DateTime AddYears(DateTime time, int years)
239  {
240  return AddMonths(time, years * 12);
241  }
242 
247  public override int GetDayOfMonth(DateTime time)
248  {
249  return GetDatePart(time.Ticks, 3);
250  }
251 
255  public override DayOfWeek GetDayOfWeek(DateTime time)
256  {
257  return (DayOfWeek)((int)(time.Ticks / 864000000000L + 1) % 7);
258  }
259 
264  public override int GetDayOfYear(DateTime time)
265  {
266  return GetDatePart(time.Ticks, 1);
267  }
268 
276  public override int GetDaysInMonth(int year, int month, int era)
277  {
278  CheckYearMonthRange(year, month, era);
279  if (month == 10 && year == 9378)
280  {
281  return 13;
282  }
283  int num = DaysToMonth[month] - DaysToMonth[month - 1];
284  if (month == 12 && !IsLeapYear(year))
285  {
286  num--;
287  }
288  return num;
289  }
290 
297  public override int GetDaysInYear(int year, int era)
298  {
299  CheckYearRange(year, era);
300  if (year == 9378)
301  {
302  return DaysToMonth[9] + 13;
303  }
304  if (!IsLeapYear(year, 0))
305  {
306  return 365;
307  }
308  return 366;
309  }
310 
315  public override int GetEra(DateTime time)
316  {
317  CheckTicksRange(time.Ticks);
318  return PersianEra;
319  }
320 
325  public override int GetMonth(DateTime time)
326  {
327  return GetDatePart(time.Ticks, 2);
328  }
329 
336  public override int GetMonthsInYear(int year, int era)
337  {
338  CheckYearRange(year, era);
339  if (year == 9378)
340  {
341  return 10;
342  }
343  return 12;
344  }
345 
350  public override int GetYear(DateTime time)
351  {
352  return GetDatePart(time.Ticks, 0);
353  }
354 
364  public override bool IsLeapDay(int year, int month, int day, int era)
365  {
366  int daysInMonth = GetDaysInMonth(year, month, era);
367  if (day < 1 || day > daysInMonth)
368  {
369  throw new ArgumentOutOfRangeException("day", string.Format(CultureInfo.CurrentCulture, Environment.GetResourceString("ArgumentOutOfRange_Day"), daysInMonth, month));
370  }
371  if (IsLeapYear(year, era) && month == 12)
372  {
373  return day == 30;
374  }
375  return false;
376  }
377 
384  public override int GetLeapMonth(int year, int era)
385  {
386  CheckYearRange(year, era);
387  return 0;
388  }
389 
397  public override bool IsLeapMonth(int year, int month, int era)
398  {
399  CheckYearMonthRange(year, month, era);
400  return false;
401  }
402 
410  public override bool IsLeapYear(int year, int era)
411  {
412  CheckYearRange(year, era);
413  if (year == 9378)
414  {
415  return false;
416  }
417  return GetAbsoluteDatePersian(year + 1, 1, 1) - GetAbsoluteDatePersian(year, 1, 1) == 366;
418  }
419 
432  public override DateTime ToDateTime(int year, int month, int day, int hour, int minute, int second, int millisecond, int era)
433  {
434  int daysInMonth = GetDaysInMonth(year, month, era);
435  if (day < 1 || day > daysInMonth)
436  {
437  throw new ArgumentOutOfRangeException("day", string.Format(CultureInfo.CurrentCulture, Environment.GetResourceString("ArgumentOutOfRange_Day"), daysInMonth, month));
438  }
439  long absoluteDatePersian = GetAbsoluteDatePersian(year, month, day);
440  if (absoluteDatePersian >= 0)
441  {
442  return new DateTime(absoluteDatePersian * 864000000000L + Calendar.TimeToTicks(hour, minute, second, millisecond));
443  }
444  throw new ArgumentOutOfRangeException(null, Environment.GetResourceString("ArgumentOutOfRange_BadYearMonthDay"));
445  }
446 
452  public override int ToFourDigitYear(int year)
453  {
454  if (year < 0)
455  {
456  throw new ArgumentOutOfRangeException("year", Environment.GetResourceString("ArgumentOutOfRange_NeedNonNegNum"));
457  }
458  if (year < 100)
459  {
460  return base.ToFourDigitYear(year);
461  }
462  if (year > 9378)
463  {
464  throw new ArgumentOutOfRangeException("year", string.Format(CultureInfo.CurrentCulture, Environment.GetResourceString("ArgumentOutOfRange_Range"), 1, 9378));
465  }
466  return year;
467  }
468  }
469 }
override int GetDayOfMonth(DateTime time)
Returns the day of the month in the specified T:System.DateTime object.
override DateTime AddMonths(DateTime time, int months)
Returns a T:System.DateTime object that is offset the specified number of months from the specified T...
Represents time in divisions, such as weeks, months, and years.
Definition: Calendar.cs:11
override int GetMonthsInYear(int year, int era)
Returns the number of months in the specified year of the specified era.
override bool IsLeapYear(int year, int era)
Determines whether the specified year in the specified era is a leap year.
The exception that is thrown when the value of an argument is outside the allowable range of values a...
override int TwoDigitYearMax
Gets or sets the last year of a 100-year range that can be represented by a 2-digit year.
Represents an instant in time, typically expressed as a date and time of day. To browse the ....
Definition: DateTime.cs:13
override int GetYear(DateTime time)
Returns the year in the specified T:System.DateTime object.
override DayOfWeek GetDayOfWeek(DateTime time)
Returns the day of the week in the specified T:System.DateTime object.
override int ToFourDigitYear(int year)
Converts the specified year to a four-digit year representation.
Provides information about, and means to manipulate, the current environment and platform....
Definition: Environment.cs:21
override int GetLeapMonth(int year, int era)
Returns the leap month for a specified year and era.
override int GetEra(DateTime time)
Returns the era in the specified T:System.DateTime object.
override bool IsLeapDay(int year, int month, int day, int era)
Determines whether the specified date is a leap day.
override CalendarAlgorithmType AlgorithmType
Gets a value indicating whether the current calendar is solar-based, lunar-based, or lunisolar-based.
static readonly DateTime MaxValue
Represents the largest possible value of T:System.DateTime. This field is read-only.
Definition: DateTime.cs:113
override DateTime MaxSupportedDateTime
Gets the latest date and time supported by the T:System.Globalization.PersianCalendar class.
override DateTime AddYears(DateTime time, int years)
Returns a T:System.DateTime object that is offset the specified number of years from the specified T:...
Format character that affects the layout of text or the operation of text processes,...
override int GetDayOfYear(DateTime time)
Returns the day of the year in the specified T:System.DateTime object.
static CultureInfo CurrentCulture
Gets or sets the T:System.Globalization.CultureInfo object that represents the culture used by the cu...
Definition: CultureInfo.cs:120
override int GetDaysInMonth(int year, int month, int era)
Returns the number of days in the specified month of the specified year and era.
static readonly int PersianEra
Represents the current era. This field is constant.
Represents the Persian calendar.
CalendarAlgorithmType
Specifies whether a calendar is solar-based, lunar-based, or lunisolar-based.
Specifies that the class can be serialized.
override bool IsLeapMonth(int year, int month, int era)
Determines whether the specified month in the specified year and era is a leap month.
override int GetMonth(DateTime time)
Returns the month in the specified T:System.DateTime object.
override DateTime ToDateTime(int year, int month, int day, int hour, int minute, int second, int millisecond, int era)
Returns a T:System.DateTime object that is set to the specified date, time, and era.
Provides information about a specific culture (called a locale for unmanaged code development)....
Definition: CultureInfo.cs:16
override int [] Eras
Gets the list of eras in a T:System.Globalization.PersianCalendar object.
DayOfWeek
Specifies the day of the week.
Definition: DayOfWeek.cs:9
override DateTime MinSupportedDateTime
Gets the earliest date and time supported by the T:System.Globalization.PersianCalendar class.
long Ticks
Gets the number of ticks that represent the date and time of this instance.
Definition: DateTime.cs:315
override int GetDaysInYear(int year, int era)
Returns the number of days in the specified year of the specified era.