mscorlib(4.0.0.0) API with additions
HijriCalendar.cs
1 using Microsoft.Win32;
3 using System.Security;
4 
5 namespace System.Globalization
6 {
9  [ComVisible(true)]
10  public class HijriCalendar : Calendar
11  {
13  public static readonly int HijriEra = 1;
14 
15  internal const int DatePartYear = 0;
16 
17  internal const int DatePartDayOfYear = 1;
18 
19  internal const int DatePartMonth = 2;
20 
21  internal const int DatePartDay = 3;
22 
23  internal const int MinAdvancedHijri = -2;
24 
25  internal const int MaxAdvancedHijri = 2;
26 
27  internal static readonly int[] HijriMonthDays = new int[13]
28  {
29  0,
30  30,
31  59,
32  89,
33  118,
34  148,
35  177,
36  207,
37  236,
38  266,
39  295,
40  325,
41  355
42  };
43 
44  private const string InternationalRegKey = "Control Panel\\International";
45 
46  private const string HijriAdvanceRegKeyEntry = "AddHijriDate";
47 
48  private int m_HijriAdvance = int.MinValue;
49 
50  internal const int MaxCalendarYear = 9666;
51 
52  internal const int MaxCalendarMonth = 4;
53 
54  internal const int MaxCalendarDay = 3;
55 
56  internal static readonly DateTime calendarMinValue = new DateTime(622, 7, 18);
57 
58  internal static readonly DateTime calendarMaxValue = DateTime.MaxValue;
59 
60  private const int DEFAULT_TWO_DIGIT_YEAR_MAX = 1451;
61 
64  [ComVisible(false)]
65  public override DateTime MinSupportedDateTime
66  {
67  get
68  {
69  return calendarMinValue;
70  }
71  }
72 
75  [ComVisible(false)]
76  public override DateTime MaxSupportedDateTime
77  {
78  get
79  {
80  return calendarMaxValue;
81  }
82  }
83 
86  [ComVisible(false)]
87  public override CalendarAlgorithmType AlgorithmType
88  {
89  get
90  {
91  return CalendarAlgorithmType.LunarCalendar;
92  }
93  }
94 
95  internal override int ID => 6;
96 
99  protected override int DaysInYearBeforeMinSupportedYear => 354;
100 
104  public int HijriAdjustment
105  {
106  [SecuritySafeCritical]
107  get
108  {
109  if (m_HijriAdvance == int.MinValue)
110  {
111  m_HijriAdvance = GetAdvanceHijriDate();
112  }
113  return m_HijriAdvance;
114  }
115  set
116  {
117  if (value < -2 || value > 2)
118  {
119  throw new ArgumentOutOfRangeException("HijriAdjustment", string.Format(CultureInfo.CurrentCulture, Environment.GetResourceString("ArgumentOutOfRange_Bounds_Lower_Upper"), -2, 2));
120  }
121  VerifyWritable();
122  m_HijriAdvance = value;
123  }
124  }
125 
128  public override int[] Eras => new int[1]
129  {
130  HijriEra
131  };
132 
137  public override int TwoDigitYearMax
138  {
139  get
140  {
141  if (twoDigitYearMax == -1)
142  {
143  twoDigitYearMax = Calendar.GetSystemTwoDigitYearSetting(ID, 1451);
144  }
145  return twoDigitYearMax;
146  }
147  set
148  {
149  VerifyWritable();
150  if (value < 99 || value > 9666)
151  {
152  throw new ArgumentOutOfRangeException("value", string.Format(CultureInfo.CurrentCulture, Environment.GetResourceString("ArgumentOutOfRange_Range"), 99, 9666));
153  }
154  twoDigitYearMax = value;
155  }
156  }
157 
158  private long GetAbsoluteDateHijri(int y, int m, int d)
159  {
160  return DaysUpToHijriYear(y) + HijriMonthDays[m - 1] + d - 1 - HijriAdjustment;
161  }
162 
163  private long DaysUpToHijriYear(int HijriYear)
164  {
165  int num = (HijriYear - 1) / 30 * 30;
166  int num2 = HijriYear - num - 1;
167  long num3 = (long)num * 10631L / 30 + 227013;
168  while (num2 > 0)
169  {
170  num3 += 354 + (IsLeapYear(num2, 0) ? 1 : 0);
171  num2--;
172  }
173  return num3;
174  }
175 
176  [SecurityCritical]
177  private static int GetAdvanceHijriDate()
178  {
179  int result = 0;
180  RegistryKey registryKey = null;
181  try
182  {
183  registryKey = Registry.CurrentUser.InternalOpenSubKey("Control Panel\\International", writable: false);
184  }
185  catch (ObjectDisposedException)
186  {
187  return 0;
188  }
189  catch (ArgumentException)
190  {
191  return 0;
192  }
193  if (registryKey != null)
194  {
195  try
196  {
197  object obj = registryKey.InternalGetValue("AddHijriDate", null, doNotExpand: false, checkSecurity: false);
198  if (obj == null)
199  {
200  return 0;
201  }
202  string text = obj.ToString();
203  if (string.Compare(text, 0, "AddHijriDate", 0, "AddHijriDate".Length, StringComparison.OrdinalIgnoreCase) == 0)
204  {
205  if (text.Length != "AddHijriDate".Length)
206  {
207  text = text.Substring("AddHijriDate".Length);
208  try
209  {
210  int num = int.Parse(text.ToString(), CultureInfo.InvariantCulture);
211  if (num < -2)
212  {
213  return result;
214  }
215  if (num > 2)
216  {
217  return result;
218  }
219  result = num;
220  return result;
221  }
222  catch (ArgumentException)
223  {
224  return result;
225  }
226  catch (FormatException)
227  {
228  return result;
229  }
230  catch (OverflowException)
231  {
232  return result;
233  }
234  }
235  return -1;
236  }
237  return result;
238  }
239  finally
240  {
241  registryKey.Close();
242  }
243  }
244  return result;
245  }
246 
247  internal static void CheckTicksRange(long ticks)
248  {
249  if (ticks < calendarMinValue.Ticks || ticks > calendarMaxValue.Ticks)
250  {
251  throw new ArgumentOutOfRangeException("time", string.Format(CultureInfo.InvariantCulture, Environment.GetResourceString("ArgumentOutOfRange_CalendarRange"), calendarMinValue, calendarMaxValue));
252  }
253  }
254 
255  internal static void CheckEraRange(int era)
256  {
257  if (era != 0 && era != HijriEra)
258  {
259  throw new ArgumentOutOfRangeException("era", Environment.GetResourceString("ArgumentOutOfRange_InvalidEraValue"));
260  }
261  }
262 
263  internal static void CheckYearRange(int year, int era)
264  {
265  CheckEraRange(era);
266  if (year < 1 || year > 9666)
267  {
268  throw new ArgumentOutOfRangeException("year", string.Format(CultureInfo.CurrentCulture, Environment.GetResourceString("ArgumentOutOfRange_Range"), 1, 9666));
269  }
270  }
271 
272  internal static void CheckYearMonthRange(int year, int month, int era)
273  {
274  CheckYearRange(year, era);
275  if (year == 9666 && month > 4)
276  {
277  throw new ArgumentOutOfRangeException("month", string.Format(CultureInfo.CurrentCulture, Environment.GetResourceString("ArgumentOutOfRange_Range"), 1, 4));
278  }
279  if (month < 1 || month > 12)
280  {
281  throw new ArgumentOutOfRangeException("month", Environment.GetResourceString("ArgumentOutOfRange_Month"));
282  }
283  }
284 
285  internal virtual int GetDatePart(long ticks, int part)
286  {
287  CheckTicksRange(ticks);
288  long num = ticks / 864000000000L + 1;
289  num += HijriAdjustment;
290  int num2 = (int)((num - 227013) * 30 / 10631) + 1;
291  long num3 = DaysUpToHijriYear(num2);
292  long num4 = GetDaysInYear(num2, 0);
293  if (num < num3)
294  {
295  num3 -= num4;
296  num2--;
297  }
298  else if (num == num3)
299  {
300  num2--;
301  num3 -= GetDaysInYear(num2, 0);
302  }
303  else if (num > num3 + num4)
304  {
305  num3 += num4;
306  num2++;
307  }
308  if (part == 0)
309  {
310  return num2;
311  }
312  int i = 1;
313  num -= num3;
314  if (part == 1)
315  {
316  return (int)num;
317  }
318  for (; i <= 12 && num > HijriMonthDays[i - 1]; i++)
319  {
320  }
321  i--;
322  if (part == 2)
323  {
324  return i;
325  }
326  int result = (int)(num - HijriMonthDays[i - 1]);
327  if (part == 3)
328  {
329  return result;
330  }
331  throw new InvalidOperationException(Environment.GetResourceString("InvalidOperation_DateTimeParsing"));
332  }
333 
342  public override DateTime AddMonths(DateTime time, int months)
343  {
344  if (months < -120000 || months > 120000)
345  {
346  throw new ArgumentOutOfRangeException("months", string.Format(CultureInfo.CurrentCulture, Environment.GetResourceString("ArgumentOutOfRange_Range"), -120000, 120000));
347  }
348  int datePart = GetDatePart(time.Ticks, 0);
349  int datePart2 = GetDatePart(time.Ticks, 2);
350  int num = GetDatePart(time.Ticks, 3);
351  int num2 = datePart2 - 1 + months;
352  if (num2 >= 0)
353  {
354  datePart2 = num2 % 12 + 1;
355  datePart += num2 / 12;
356  }
357  else
358  {
359  datePart2 = 12 + (num2 + 1) % 12;
360  datePart += (num2 - 11) / 12;
361  }
362  int daysInMonth = GetDaysInMonth(datePart, datePart2);
363  if (num > daysInMonth)
364  {
365  num = daysInMonth;
366  }
367  long ticks = GetAbsoluteDateHijri(datePart, datePart2, num) * 864000000000L + time.Ticks % 864000000000L;
368  Calendar.CheckAddResult(ticks, MinSupportedDateTime, MaxSupportedDateTime);
369  return new DateTime(ticks);
370  }
371 
377  public override DateTime AddYears(DateTime time, int years)
378  {
379  return AddMonths(time, years * 12);
380  }
381 
385  public override int GetDayOfMonth(DateTime time)
386  {
387  return GetDatePart(time.Ticks, 3);
388  }
389 
393  public override DayOfWeek GetDayOfWeek(DateTime time)
394  {
395  return (DayOfWeek)((int)(time.Ticks / 864000000000L + 1) % 7);
396  }
397 
401  public override int GetDayOfYear(DateTime time)
402  {
403  return GetDatePart(time.Ticks, 1);
404  }
405 
415  public override int GetDaysInMonth(int year, int month, int era)
416  {
417  CheckYearMonthRange(year, month, era);
418  if (month == 12)
419  {
420  if (!IsLeapYear(year, 0))
421  {
422  return 29;
423  }
424  return 30;
425  }
426  if (month % 2 != 1)
427  {
428  return 29;
429  }
430  return 30;
431  }
432 
439  public override int GetDaysInYear(int year, int era)
440  {
441  CheckYearRange(year, era);
442  if (!IsLeapYear(year, 0))
443  {
444  return 354;
445  }
446  return 355;
447  }
448 
452  public override int GetEra(DateTime time)
453  {
454  CheckTicksRange(time.Ticks);
455  return HijriEra;
456  }
457 
461  public override int GetMonth(DateTime time)
462  {
463  return GetDatePart(time.Ticks, 2);
464  }
465 
473  public override int GetMonthsInYear(int year, int era)
474  {
475  CheckYearRange(year, era);
476  return 12;
477  }
478 
482  public override int GetYear(DateTime time)
483  {
484  return GetDatePart(time.Ticks, 0);
485  }
486 
499  public override bool IsLeapDay(int year, int month, int day, int era)
500  {
501  int daysInMonth = GetDaysInMonth(year, month, era);
502  if (day < 1 || day > daysInMonth)
503  {
504  throw new ArgumentOutOfRangeException("day", string.Format(CultureInfo.CurrentCulture, Environment.GetResourceString("ArgumentOutOfRange_Day"), daysInMonth, month));
505  }
506  if (IsLeapYear(year, era) && month == 12)
507  {
508  return day == 30;
509  }
510  return false;
511  }
512 
520  [ComVisible(false)]
521  public override int GetLeapMonth(int year, int era)
522  {
523  CheckYearRange(year, era);
524  return 0;
525  }
526 
536  public override bool IsLeapMonth(int year, int month, int era)
537  {
538  CheckYearMonthRange(year, month, era);
539  return false;
540  }
541 
550  public override bool IsLeapYear(int year, int era)
551  {
552  CheckYearRange(year, era);
553  return (year * 11 + 14) % 30 < 11;
554  }
555 
575  public override DateTime ToDateTime(int year, int month, int day, int hour, int minute, int second, int millisecond, int era)
576  {
577  int daysInMonth = GetDaysInMonth(year, month, era);
578  if (day < 1 || day > daysInMonth)
579  {
580  throw new ArgumentOutOfRangeException("day", string.Format(CultureInfo.CurrentCulture, Environment.GetResourceString("ArgumentOutOfRange_Day"), daysInMonth, month));
581  }
582  long absoluteDateHijri = GetAbsoluteDateHijri(year, month, day);
583  if (absoluteDateHijri >= 0)
584  {
585  return new DateTime(absoluteDateHijri * 864000000000L + Calendar.TimeToTicks(hour, minute, second, millisecond));
586  }
587  throw new ArgumentOutOfRangeException(null, Environment.GetResourceString("ArgumentOutOfRange_BadYearMonthDay"));
588  }
589 
595  public override int ToFourDigitYear(int year)
596  {
597  if (year < 0)
598  {
599  throw new ArgumentOutOfRangeException("year", Environment.GetResourceString("ArgumentOutOfRange_NeedNonNegNum"));
600  }
601  if (year < 100)
602  {
603  return base.ToFourDigitYear(year);
604  }
605  if (year > 9666)
606  {
607  throw new ArgumentOutOfRangeException("year", string.Format(CultureInfo.CurrentCulture, Environment.GetResourceString("ArgumentOutOfRange_Range"), 1, 9666));
608  }
609  return year;
610  }
611  }
612 }
override DateTime AddMonths(DateTime time, int months)
Returns a T:System.DateTime that is the specified number of months away from the specified T:System....
Represents time in divisions, such as weeks, months, and years.
Definition: Calendar.cs:11
override int GetDayOfMonth(DateTime time)
Returns the day of the month in the specified T:System.DateTime.
StringComparison
Specifies the culture, case, and sort rules to be used by certain overloads of the M:System....
Definition: __Canon.cs:3
override DayOfWeek GetDayOfWeek(DateTime time)
Returns the day of the week in the specified T:System.DateTime.
The exception that is thrown when the value of an argument is outside the allowable range of values a...
override int GetMonthsInYear(int year, int era)
Returns the number of months in the specified year and era.
override bool IsLeapYear(int year, int era)
Determines whether the specified year in the specified era is a leap year.
Represents an instant in time, typically expressed as a date and time of day. To browse the ....
Definition: DateTime.cs:13
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 GetLeapMonth(int year, int era)
Calculates the leap month for a specified year and era.
override int TwoDigitYearMax
Gets or sets the last year of a 100-year range that can be represented by a 2-digit year.
static readonly int HijriEra
Represents the current era. This field is constant.
override int DaysInYearBeforeMinSupportedYear
Gets the number of days in the year that precedes the year that is specified by the P:System....
override int [] Eras
Gets the list of eras in the T:System.Globalization.HijriCalendar.
override DateTime AddYears(DateTime time, int years)
Returns a T:System.DateTime that is the specified number of years away from the specified T:System....
Provides information about, and means to manipulate, the current environment and platform....
Definition: Environment.cs:21
override int GetEra(DateTime time)
Returns the era in the specified T:System.DateTime.
int HijriAdjustment
Gets or sets the number of days to add or subtract from the calendar to accommodate the variances in ...
static readonly DateTime MaxValue
Represents the largest possible value of T:System.DateTime. This field is read-only.
Definition: DateTime.cs:113
override bool IsLeapDay(int year, int month, int day, int era)
Determines whether the specified date is a leap day.
Format character that affects the layout of text or the operation of text processes,...
override int ToFourDigitYear(int year)
Converts the specified year to a four-digit year by using the P:System.Globalization....
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 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 GetDayOfYear(DateTime time)
Returns the day of the year in the specified T:System.DateTime.
CalendarAlgorithmType
Specifies whether a calendar is solar-based, lunar-based, or lunisolar-based.
Specifies that the class can be serialized.
Represents the Hijri calendar.
override CalendarAlgorithmType AlgorithmType
Gets a value that indicates whether the current calendar is solar-based, lunar-based,...
override int GetYear(DateTime time)
Returns the year in the specified T:System.DateTime.
override int GetDaysInYear(int year, int era)
Returns the number of days in the specified year and era.
override DateTime ToDateTime(int year, int month, int day, int hour, int minute, int second, int millisecond, int era)
Returns a T:System.DateTime 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 DateTime MinSupportedDateTime
Gets the earliest date and time supported by this calendar.
override DateTime MaxSupportedDateTime
Gets the latest date and time supported by this calendar.
DayOfWeek
Specifies the day of the week.
Definition: DayOfWeek.cs:9
long Ticks
Gets the number of ticks that represent the date and time of this instance.
Definition: DateTime.cs:315
override int GetMonth(DateTime time)
Returns the month in the specified T:System.DateTime.