Update Reference Sources to .NET Framework 4.6.1
[mono.git] / mcs / class / referencesource / mscorlib / system / globalization / umalquracalendar.cs
1 // ==++==
2 //
3 //   Copyright (c) Microsoft Corporation.  All rights reserved.
4 //
5 // ==--==
6 namespace System.Globalization {
7     using System;
8     using System.Diagnostics.Contracts;
9
10
11     ////////////////////////////////////////////////////////////////////////////
12     //
13     //  Notes about UmAlQuraCalendar
14     //
15     ////////////////////////////////////////////////////////////////////////////
16      /*
17      **  Calendar support range:
18      **      Calendar    Minimum     Maximum
19      **      ==========  ==========  ==========
20      **      Gregorian   1900/04/30   2077/11/17
21      **      UmAlQura    1318/01/01   1500/12/30
22      */
23
24     [Serializable]
25     public class UmAlQuraCalendar : Calendar {
26
27         internal const int MinCalendarYear = 1318;
28         internal const int MaxCalendarYear = 1500;
29
30         internal struct DateMapping
31         {
32             internal DateMapping(int MonthsLengthFlags, int GYear, int GMonth, int GDay) 
33             {
34                 HijriMonthsLengthFlags = MonthsLengthFlags;
35                 GregorianDate = new DateTime(GYear, GMonth, GDay);
36             }
37             internal int HijriMonthsLengthFlags;
38             internal DateTime GregorianDate;
39         }
40
41         static readonly DateMapping [] HijriYearInfo = InitDateMapping();
42
43         static DateMapping[] InitDateMapping()
44         {
45             short[] rawData = new short[] {
46 //These data is taken from Tables/Excel/UmAlQura.xls please make sure that the two places are in [....]
47 /*  DaysPerM     GY      GM     GD     D1   D2   D3   D4   D5   D6   D7   D8   D9   D10  D11  D12    
48 1318*/0x02EA,    1900,     4,    30,/* 0    1    0    1    0    1    1    1    0    1    0    0    4/30/1900
49 1319*/0x06E9,    1901,     4,    19,/* 1    0    0    1    0    1    1    1    0    1    1    0    4/19/1901
50 1320*/0x0ED2,    1902,     4,     9,/* 0    1    0    0    1    0    1    1    0    1    1    1    4/9/1902
51 1321*/0x0EA4,    1903,     3,    30,/* 0    0    1    0    0    1    0    1    0    1    1    1    3/30/1903
52 1322*/0x0D4A,    1904,     3,    18,/* 0    1    0    1    0    0    1    0    1    0    1    1    3/18/1904
53 1323*/0x0A96,    1905,     3,     7,/* 0    1    1    0    1    0    0    1    0    1    0    1    3/7/1905
54 1324*/0x0536,    1906,     2,    24,/* 0    1    1    0    1    1    0    0    1    0    1    0    2/24/1906
55 1325*/0x0AB5,    1907,     2,    13,/* 1    0    1    0    1    1    0    1    0    1    0    1    2/13/1907
56 1326*/0x0DAA,    1908,     2,     3,/* 0    1    0    1    0    1    0    1    1    0    1    1    2/3/1908
57 1327*/0x0BA4,    1909,     1,    23,/* 0    0    1    0    0    1    0    1    1    1    0    1    1/23/1909
58 1328*/0x0B49,    1910,     1,    12,/* 1    0    0    1    0    0    1    0    1    1    0    1    1/12/1910
59 1329*/0x0A93,    1911,     1,     1,/* 1    1    0    0    1    0    0    1    0    1    0    1    1/1/1911
60 1330*/0x052B,    1911,    12,    21,/* 1    1    0    1    0    1    0    0    1    0    1    0    12/21/1911
61 1331*/0x0A57,    1912,    12,     9,/* 1    1    1    0    1    0    1    0    0    1    0    1    12/9/1912
62 1332*/0x04B6,    1913,    11,    29,/* 0    1    1    0    1    1    0    1    0    0    1    0    11/29/1913
63 1333*/0x0AB5,    1914,    11,    18,/* 1    0    1    0    1    1    0    1    0    1    0    1    11/18/1914
64 1334*/0x05AA,    1915,    11,     8,/* 0    1    0    1    0    1    0    1    1    0    1    0    11/8/1915
65 1335*/0x0D55,    1916,    10,    27,/* 1    0    1    0    1    0    1    0    1    0    1    1    10/27/1916
66 1336*/0x0D2A,    1917,    10,    17,/* 0    1    0    1    0    1    0    0    1    0    1    1    10/17/1917
67 1337*/0x0A56,    1918,    10,     6,/* 0    1    1    0    1    0    1    0    0    1    0    1    10/6/1918
68 1338*/0x04AE,    1919,     9,    25,/* 0    1    1    1    0    1    0    1    0    0    1    0    9/25/1919
69 1339*/0x095D,    1920,     9,    13,/* 1    0    1    1    1    0    1    0    1    0    0    1    9/13/1920
70 1340*/0x02EC,    1921,     9,     3,/* 0    0    1    1    0    1    1    1    0    1    0    0    9/3/1921
71 1341*/0x06D5,    1922,     8,    23,/* 1    0    1    0    1    0    1    1    0    1    1    0    8/23/1922
72 1342*/0x06AA,    1923,     8,    13,/* 0    1    0    1    0    1    0    1    0    1    1    0    8/13/1923
73 1343*/0x0555,    1924,     8,     1,/* 1    0    1    0    1    0    1    0    1    0    1    0    8/1/1924
74 1344*/0x04AB,    1925,     7,    21,/* 1    1    0    1    0    1    0    1    0    0    1    0    7/21/1925
75 1345*/0x095B,    1926,     7,    10,/* 1    1    0    1    1    0    1    0    1    0    0    1    7/10/1926
76 1346*/0x02BA,    1927,     6,    30,/* 0    1    0    1    1    1    0    1    0    1    0    0    6/30/1927
77 1347*/0x0575,    1928,     6,    18,/* 1    0    1    0    1    1    1    0    1    0    1    0    6/18/1928
78 1348*/0x0BB2,    1929,     6,     8,/* 0    1    0    0    1    1    0    1    1    1    0    1    6/8/1929
79 1349*/0x0764,    1930,     5,    29,/* 0    0    1    0    0    1    1    0    1    1    1    0    5/29/1930
80 1350*/0x0749,    1931,     5,    18,/* 1    0    0    1    0    0    1    0    1    1    1    0    5/18/1931
81 1351*/0x0655,    1932,     5,     6,/* 1    0    1    0    1    0    1    0    0    1    1    0    5/6/1932
82 1352*/0x02AB,    1933,     4,    25,/* 1    1    0    1    0    1    0    1    0    1    0    0    4/25/1933
83 1353*/0x055B,    1934,     4,    14,/* 1    1    0    1    1    0    1    0    1    0    1    0    4/14/1934
84 1354*/0x0ADA,    1935,     4,     4,/* 0    1    0    1    1    0    1    1    0    1    0    1    4/4/1935
85 1355*/0x06D4,    1936,     3,    24,/* 0    0    1    0    1    0    1    1    0    1    1    0    3/24/1936
86 1356*/0x0EC9,    1937,     3,    13,/* 1    0    0    1    0    0    1    1    0    1    1    1    3/13/1937
87 1357*/0x0D92,    1938,     3,     3,/* 0    1    0    0    1    0    0    1    1    0    1    1    3/3/1938
88 1358*/0x0D25,    1939,     2,    20,/* 1    0    1    0    0    1    0    0    1    0    1    1    2/20/1939
89 1359*/0x0A4D,    1940,     2,     9,/* 1    0    1    1    0    0    1    0    0    1    0    1    2/9/1940
90 1360*/0x02AD,    1941,     1,    28,/* 1    0    1    1    0    1    0    1    0    1    0    0    1/28/1941
91 1361*/0x056D,    1942,     1,    17,/* 1    0    1    1    0    1    1    0    1    0    1    0    1/17/1942
92 1362*/0x0B6A,    1943,     1,     7,/* 0    1    0    1    0    1    1    0    1    1    0    1    1/7/1943
93 1363*/0x0B52,    1943,    12,    28,/* 0    1    0    0    1    0    1    0    1    1    0    1    12/28/1943
94 1364*/0x0AA5,    1944,    12,    16,/* 1    0    1    0    0    1    0    1    0    1    0    1    12/16/1944
95 1365*/0x0A4B,    1945,    12,     5,/* 1    1    0    1    0    0    1    0    0    1    0    1    12/5/1945
96 1366*/0x0497,    1946,    11,    24,/* 1    1    1    0    1    0    0    1    0    0    1    0    11/24/1946
97 1367*/0x0937,    1947,    11,    13,/* 1    1    1    0    1    1    0    0    1    0    0    1    11/13/1947
98 1368*/0x02B6,    1948,    11,     2,/* 0    1    1    0    1    1    0    1    0    1    0    0    11/2/1948
99 1369*/0x0575,    1949,    10,    22,/* 1    0    1    0    1    1    1    0    1    0    1    0    10/22/1949
100 1370*/0x0D6A,    1950,    10,    12,/* 0    1    0    1    0    1    1    0    1    0    1    1    10/12/1950
101 1371*/0x0D52,    1951,    10,     2,/* 0    1    0    0    1    0    1    0    1    0    1    1    10/2/1951
102 1372*/0x0A96,    1952,     9,    20,/* 0    1    1    0    1    0    0    1    0    1    0    1    9/20/1952
103 1373*/0x092D,    1953,     9,     9,/* 1    0    1    1    0    1    0    0    1    0    0    1    9/9/1953
104 1374*/0x025D,    1954,     8,    29,/* 1    0    1    1    1    0    1    0    0    1    0    0    8/29/1954
105 1375*/0x04DD,    1955,     8,    18,/* 1    0    1    1    1    0    1    1    0    0    1    0    8/18/1955
106 1376*/0x0ADA,    1956,     8,     7,/* 0    1    0    1    1    0    1    1    0    1    0    1    8/7/1956
107 1377*/0x05D4,    1957,     7,    28,/* 0    0    1    0    1    0    1    1    1    0    1    0    7/28/1957
108 1378*/0x0DA9,    1958,     7,    17,/* 1    0    0    1    0    1    0    1    1    0    1    1    7/17/1958
109 1379*/0x0D52,    1959,     7,     7,/* 0    1    0    0    1    0    1    0    1    0    1    1    7/7/1959
110 1380*/0x0AAA,    1960,     6,    25,/* 0    1    0    1    0    1    0    1    0    1    0    1    6/25/1960
111 1381*/0x04D6,    1961,     6,    14,/* 0    1    1    0    1    0    1    1    0    0    1    0    6/14/1961
112 1382*/0x09B6,    1962,     6,     3,/* 0    1    1    0    1    1    0    1    1    0    0    1    6/3/1962
113 1383*/0x0374,    1963,     5,    24,/* 0    0    1    0    1    1    1    0    1    1    0    0    5/24/1963
114 1384*/0x0769,    1964,     5,    12,/* 1    0    0    1    0    1    1    0    1    1    1    0    5/12/1964
115 1385*/0x0752,    1965,     5,     2,/* 0    1    0    0    1    0    1    0    1    1    1    0    5/2/1965
116 1386*/0x06A5,    1966,     4,    21,/* 1    0    1    0    0    1    0    1    0    1    1    0    4/21/1966
117 1387*/0x054B,    1967,     4,    10,/* 1    1    0    1    0    0    1    0    1    0    1    0    4/10/1967
118 1388*/0x0AAB,    1968,     3,    29,/* 1    1    0    1    0    1    0    1    0    1    0    1    3/29/1968
119 1389*/0x055A,    1969,     3,    19,/* 0    1    0    1    1    0    1    0    1    0    1    0    3/19/1969
120 1390*/0x0AD5,    1970,     3,     8,/* 1    0    1    0    1    0    1    1    0    1    0    1    3/8/1970
121 1391*/0x0DD2,    1971,     2,    26,/* 0    1    0    0    1    0    1    1    1    0    1    1    2/26/1971
122 1392*/0x0DA4,    1972,     2,    16,/* 0    0    1    0    0    1    0    1    1    0    1    1    2/16/1972
123 1393*/0x0D49,    1973,     2,     4,/* 1    0    0    1    0    0    1    0    1    0    1    1    2/4/1973
124 1394*/0x0A95,    1974,     1,    24,/* 1    0    1    0    1    0    0    1    0    1    0    1    1/24/1974
125 1395*/0x052D,    1975,     1,    13,/* 1    0    1    1    0    1    0    0    1    0    1    0    1/13/1975
126 1396*/0x0A5D,    1976,     1,     2,/* 1    0    1    1    1    0    1    0    0    1    0    1    1/2/1976
127 1397*/0x055A,    1976,    12,    22,/* 0    1    0    1    1    0    1    0    1    0    1    0    12/22/1976
128 1398*/0x0AD5,    1977,    12,    11,/* 1    0    1    0    1    0    1    1    0    1    0    1    12/11/1977
129 1399*/0x06AA,    1978,    12,     1,/* 0    1    0    1    0    1    0    1    0    1    1    0    12/1/1978
130 1400*/0x0695,    1979,    11,    20,/* 1    0    1    0    1    0    0    1    0    1    1    0    11/20/1979
131 1401*/0x052B,    1980,    11,     8,/* 1    1    0    1    0    1    0    0    1    0    1    0    11/8/1980
132 1402*/0x0A57,    1981,    10,    28,/* 1    1    1    0    1    0    1    0    0    1    0    1    10/28/1981
133 1403*/0x04AE,    1982,    10,    18,/* 0    1    1    1    0    1    0    1    0    0    1    0    10/18/1982
134 1404*/0x0976,    1983,    10,     7,/* 0    1    1    0    1    1    1    0    1    0    0    1    10/7/1983
135 1405*/0x056C,    1984,     9,    26,/* 0    0    1    1    0    1    1    0    1    0    1    0    9/26/1984
136 1406*/0x0B55,    1985,     9,    15,/* 1    0    1    0    1    0    1    0    1    1    0    1    9/15/1985
137 1407*/0x0AAA,    1986,     9,     5,/* 0    1    0    1    0    1    0    1    0    1    0    1    9/5/1986
138 1408*/0x0A55,    1987,     8,    25,/* 1    0    1    0    1    0    1    0    0    1    0    1    8/25/1987
139 1409*/0x04AD,    1988,     8,    13,/* 1    0    1    1    0    1    0    1    0    0    1    0    8/13/1988
140 1410*/0x095D,    1989,     8,     2,/* 1    0    1    1    1    0    1    0    1    0    0    1    8/2/1989
141 1411*/0x02DA,    1990,     7,    23,/* 0    1    0    1    1    0    1    1    0    1    0    0    7/23/1990
142 1412*/0x05D9,    1991,     7,    12,/* 1    0    0    1    1    0    1    1    1    0    1    0    7/12/1991
143 1413*/0x0DB2,    1992,     7,     1,/* 0    1    0    0    1    1    0    1    1    0    1    1    7/1/1992
144 1414*/0x0BA4,    1993,     6,    21,/* 0    0    1    0    0    1    0    1    1    1    0    1    6/21/1993
145 1415*/0x0B4A,    1994,     6,    10,/* 0    1    0    1    0    0    1    0    1    1    0    1    6/10/1994
146 1416*/0x0A55,    1995,     5,    30,/* 1    0    1    0    1    0    1    0    0    1    0    1    5/30/1995
147 1417*/0x02B5,    1996,     5,    18,/* 1    0    1    0    1    1    0    1    0    1    0    0    5/18/1996
148 1418*/0x0575,    1997,     5,     7,/* 1    0    1    0    1    1    1    0    1    0    1    0    5/7/1997
149 1419*/0x0B6A,    1998,     4,    27,/* 0    1    0    1    0    1    1    0    1    1    0    1    4/27/1998
150 1420*/0x0BD2,    1999,     4,    17,/* 0    1    0    0    1    0    1    1    1    1    0    1    4/17/1999
151 1421*/0x0BC4,    2000,     4,     6,/* 0    0    1    0    0    0    1    1    1    1    0    1    4/6/2000
152 1422*/0x0B89,    2001,     3,    26,/* 1    0    0    1    0    0    0    1    1    1    0    1    3/26/2001
153 1423*/0x0A95,    2002,     3,    15,/* 1    0    1    0    1    0    0    1    0    1    0    1    3/15/2002
154 1424*/0x052D,    2003,     3,     4,/* 1    0    1    1    0    1    0    0    1    0    1    0    3/4/2003
155 1425*/0x05AD,    2004,     2,    21,/* 1    0    1    1    0    1    0    1    1    0    1    0    2/21/2004
156 1426*/0x0B6A,    2005,     2,    10,/* 0    1    0    1    0    1    1    0    1    1    0    1    2/10/2005
157 1427*/0x06D4,    2006,     1,    31,/* 0    0    1    0    1    0    1    1    0    1    1    0    1/31/2006
158 1428*/0x0DC9,    2007,     1,    20,/* 1    0    0    1    0    0    1    1    1    0    1    1    1/20/2007
159 1429*/0x0D92,    2008,     1,    10,/* 0    1    0    0    1    0    0    1    1    0    1    1    1/10/2008
160 1430*/0x0AA6,    2008,    12,    29,/* 0    1    1    0    0    1    0    1    0    1    0    1    12/29/2008
161 1431*/0x0956,    2009,    12,    18,/* 0    1    1    0    1    0    1    0    1    0    0    1    12/18/2009
162 1432*/0x02AE,    2010,    12,     7,/* 0    1    1    1    0    1    0    1    0    1    0    0    12/7/2010
163 1433*/0x056D,    2011,    11,    26,/* 1    0    1    1    0    1    1    0    1    0    1    0    11/26/2011
164 1434*/0x036A,    2012,    11,    15,/* 0    1    0    1    0    1    1    0    1    1    0    0    11/15/2012
165 1435*/0x0B55,    2013,    11,     4,/* 1    0    1    0    1    0    1    0    1    1    0    1    11/4/2013
166 1436*/0x0AAA,    2014,    10,    25,/* 0    1    0    1    0    1    0    1    0    1    0    1    10/25/2014
167 1437*/0x094D,    2015,    10,    14,/* 1    0    1    1    0    0    1    0    1    0    0    1    10/14/2015
168 1438*/0x049D,    2016,    10,     2,/* 1    0    1    1    1    0    0    1    0    0    1    0    10/2/2016
169 1439*/0x095D,    2017,     9,    21,/* 1    0    1    1    1    0    1    0    1    0    0    1    9/21/2017
170 1440*/0x02BA,    2018,     9,    11,/* 0    1    0    1    1    1    0    1    0    1    0    0    9/11/2018
171 1441*/0x05B5,    2019,     8,    31,/* 1    0    1    0    1    1    0    1    1    0    1    0    8/31/2019
172 1442*/0x05AA,    2020,     8,    20,/* 0    1    0    1    0    1    0    1    1    0    1    0    8/20/2020
173 1443*/0x0D55,    2021,     8,     9,/* 1    0    1    0    1    0    1    0    1    0    1    1    8/9/2021
174 1444*/0x0A9A,    2022,     7,    30,/* 0    1    0    1    1    0    0    1    0    1    0    1    7/30/2022
175 1445*/0x092E,    2023,     7,    19,/* 0    1    1    1    0    1    0    0    1    0    0    1    7/19/2023
176 1446*/0x026E,    2024,     7,     7,/* 0    1    1    1    0    1    1    0    0    1    0    0    7/7/2024
177 1447*/0x055D,    2025,     6,    26,/* 1    0    1    1    1    0    1    0    1    0    1    0    6/26/2025
178 1448*/0x0ADA,    2026,     6,    16,/* 0    1    0    1    1    0    1    1    0    1    0    1    6/16/2026
179 1449*/0x06D4,    2027,     6,     6,/* 0    0    1    0    1    0    1    1    0    1    1    0    6/6/2027
180 1450*/0x06A5,    2028,     5,    25,/* 1    0    1    0    0    1    0    1    0    1    1    0    5/25/2028
181 1451*/0x054B,    2029,     5,    14,/* 1    1    0    1    0    0    1    0    1    0    1    0    5/14/2029
182 1452*/0x0A97,    2030,     5,     3,/* 1    1    1    0    1    0    0    1    0    1    0    1    5/3/2030
183 1453*/0x054E,    2031,     4,    23,/* 0    1    1    1    0    0    1    0    1    0    1    0    4/23/2031
184 1454*/0x0AAE,    2032,     4,    11,/* 0    1    1    1    0    1    0    1    0    1    0    1    4/11/2032
185 1455*/0x05AC,    2033,     4,     1,/* 0    0    1    1    0    1    0    1    1    0    1    0    4/1/2033
186 1456*/0x0BA9,    2034,     3,    21,/* 1    0    0    1    0    1    0    1    1    1    0    1    3/21/2034
187 1457*/0x0D92,    2035,     3,    11,/* 0    1    0    0    1    0    0    1    1    0    1    1    3/11/2035
188 1458*/0x0B25,    2036,     2,    28,/* 1    0    1    0    0    1    0    0    1    1    0    1    2/28/2036
189 1459*/0x064B,    2037,     2,    16,/* 1    1    0    1    0    0    1    0    0    1    1    0    2/16/2037
190 1460*/0x0CAB,    2038,     2,     5,/* 1    1    0    1    0    1    0    1    0    0    1    1    2/5/2038
191 1461*/0x055A,    2039,     1,    26,/* 0    1    0    1    1    0    1    0    1    0    1    0    1/26/2039
192 1462*/0x0B55,    2040,     1,    15,/* 1    0    1    0    1    0    1    0    1    1    0    1    1/15/2040
193 1463*/0x06D2,    2041,     1,     4,/* 0    1    0    0    1    0    1    1    0    1    1    0    1/4/2041
194 1464*/0x0EA5,    2041,     12,   24,/* 1    0    1    0    0    1    0    1    0    1    1    1    12/24/2041
195 1465*/0x0E4A,    2042,     12,   14,/* 0    1    0    1    0    0    1    0    0    1    1    1    12/14/2042
196 1466*/0x0A95,    2043,     12,    3,/* 1    0    1    0    1    0    0    1    0    1    0    1    12/3/2043
197 1467*/0x052D,    2044,     11,   21,/* 1    0    1    1    0    1    0    0    1    0    1    0    11/21/2044
198 1468*/0x0AAD,    2045,     11,   10,/* 1    0    1    1    0    1    0    1    0    1    0    1    11/10/2045
199 1469*/0x036C,    2046,     10,   31,/* 0    0    1    1    0    1    1    0    1    1    0    0    10/31/2046
200 1470*/0x0759,    2047,     10,   20,/* 1    0    0    1    1    0    1    0    1    1    1    0    10/20/2047
201 1471*/0x06D2,    2048,     10,    9,/* 0    1    0    0    1    0    1    1    0    1    1    0    10/9/2048
202 1472*/0x0695,    2049,     9,    28,/* 1    0    1    0    1    0    0    1    0    1    1    0    9/28/2049
203 1473*/0x052D,    2050,     9,    17,/* 1    0    1    1    0    1    0    0    1    0    1    0    9/17/2050
204 1474*/0x0A5B,    2051,     9,     6,/* 1    1    0    1    1    0    1    0    0    1    0    1    9/6/2051
205 1475*/0x04BA,    2052,     8,    26,/* 0    1    0    1    1    1    0    1    0    0    1    0    8/26/2052
206 1476*/0x09BA,    2053,     8,    15,/* 0    1    0    1    1    1    0    1    1    0    0    1    8/15/2053
207 1477*/0x03B4,    2054,     8,     5,/* 0    0    1    0    1    1    0    1    1    1    0    0    8/5/2054
208 1478*/0x0B69,    2055,     7,    25,/* 1    0    0    1    0    1    1    0    1    1    0    1    7/25/2055
209 1479*/0x0B52,    2056,     7,    14,/* 0    1    0    0    1    0    1    0    1    1    0    1    7/14/2056
210 1480*/0x0AA6,    2057,     7,     3,/* 0    1    1    0    0    1    0    1    0    1    0    1    7/3/2057
211 1481*/0x04B6,    2058,     6,    22,/* 0    1    1    0    1    1    0    1    0    0    1    0    6/22/2058
212 1482*/0x096D,    2059,     6,    11,/* 1    0    1    1    0    1    1    0    1    0    0    1    6/11/2059
213 1483*/0x02EC,    2060,     5,    31,/* 0    0    1    1    0    1    1    1    0    1    0    0    5/31/2060
214 1484*/0x06D9,    2061,     5,    20,/* 1    0    0    1    1    0    1    1    0    1    1    0    5/20/2061
215 1485*/0x0EB2,    2062,     5,    10,/* 0    1    0    0    1    1    0    1    0    1    1    1    5/10/2062
216 1486*/0x0D54,    2063,     4,    30,/* 0    0    1    0    1    0    1    0    1    0    1    1    4/30/2063
217 1487*/0x0D2A,    2064,     4,    18,/* 0    1    0    1    0    1    0    0    1    0    1    1    4/18/2064
218 1488*/0x0A56,    2065,     4,     7,/* 0    1    1    0    1    0    1    0    0    1    0    1    4/7/2065
219 1489*/0x04AE,    2066,     3,    27,/* 0    1    1    1    0    1    0    1    0    0    1    0    3/27/2066
220 1490*/0x096D,    2067,     3,    16,/* 1    0    1    1    0    1    1    0    1    0    0    1    3/16/2067
221 1491*/0x0D6A,    2068,     3,     5,/* 0    1    0    1    0    1    1    0    1    0    1    1    3/5/2068
222 1492*/0x0B54,    2069,     2,    23,/* 0    0    1    0    1    0    1    0    1    1    0    1    2/23/2069
223 1493*/0x0B29,    2070,     2,    12,/* 1    0    0    1    0    1    0    0    1    1    0    1    2/12/2070
224 1494*/0x0A93,    2071,     2,     1,/* 1    1    0    0    1    0    0    1    0    1    0    1    2/1/2071
225 1495*/0x052B,    2072,     1,    21,/* 1    1    0    1    0    1    0    0    1    0    1    0    1/21/2072
226 1496*/0x0A57,    2073,     1,     9,/* 1    1    1    0    1    0    1    0    0    1    0    1    1/9/2073
227 1497*/0x0536,    2073,     12,   30,/* 0    1    1    0    1    1    0    0    1    0    1    0    12/30/2073
228 1498*/0x0AB5,    2074,     12,   19,/* 1    0    1    0    1    1    0    1    0    1    0    1    12/19/2074
229 1499*/0x06AA,    2075,     12,    9,/* 0    1    0    1    0    1    0    1    0    1    1    0    12/9/2075
230 1500*/0x0E93,    2076,     11,   27,/* 1    1    0    0    1    0    0    1    0    1    1    1    11/27/2076
231 1501*/     0,    2077,     11,   17,/* 0    0    0    0    0    0    0    0    0    0    0    0    11/17/2077
232
233 */          };
234
235             // Direct inline initialization of DateMapping array would produce a lot of code bloat.
236
237             // We take advantage of C# compiler compiles inline initialization of primitive type array into very compact code.
238             // So we start with raw data stored in primitive type array, and initialize the DateMapping out of it
239
240             DateMapping[] mapping = new DateMapping[rawData.Length / 4];
241             for (int i = 0; i < mapping.Length; i++)
242                  mapping[i] = new DateMapping(rawData[i * 4], rawData[i * 4 + 1], rawData[i * 4 + 2], rawData[i * 4 + 3]);
243             return mapping;
244         }
245
246         public const int UmAlQuraEra = 1;
247
248         internal const int DateCycle = 30;
249         internal const int DatePartYear = 0;
250         internal const int DatePartDayOfYear = 1;
251         internal const int DatePartMonth = 2;
252         internal const int DatePartDay = 3;
253
254         //internal static Calendar m_defaultInstance;
255
256
257         // This is the minimal Gregorian date that we support in the UmAlQuraCalendar.
258         internal static DateTime minDate = new DateTime(1900, 4, 30);
259         internal static DateTime maxDate = new DateTime((new DateTime(2077, 11, 16, 23, 59, 59, 999)).Ticks + 9999);
260
261         /*=================================GetDefaultInstance==========================
262         **Action: Internal method to provide a default intance of UmAlQuraCalendar.  Used by NLS+ implementation
263         **       and other calendars.
264         **Returns:
265         **Arguments:
266         **Exceptions:
267         ============================================================================*/
268         /*
269         internal static Calendar GetDefaultInstance() {
270             if (m_defaultInstance == null) {
271                 m_defaultInstance = new UmAlQuraCalendar();
272             }
273             return (m_defaultInstance);
274         }
275         */
276
277
278
279         public override DateTime MinSupportedDateTime
280         {
281             get
282             {
283                 return (minDate);
284             }
285         }
286
287
288         public override DateTime MaxSupportedDateTime
289         {
290             get
291             {
292                 return (maxDate);
293             }
294         }
295
296
297         // Return the type of the UmAlQura calendar.
298         //
299
300
301         public override CalendarAlgorithmType AlgorithmType {
302             get {
303                 return CalendarAlgorithmType.LunarCalendar;
304             }
305         }
306
307         // Construct an instance of UmAlQura calendar.
308
309         public UmAlQuraCalendar() {
310         }
311
312         internal override int BaseCalendarID {
313             get {
314                 return (CAL_HIJRI);
315             }
316         }
317
318         internal override int ID {
319             get {
320                 return (CAL_UMALQURA);
321             }
322         }
323
324         protected override int DaysInYearBeforeMinSupportedYear
325         {
326             get
327             {
328                 // HijriCalendar has same number of days as UmAlQuraCalendar for any given year
329                 // HijriCalendar says year 1317 has 355 days.
330                 return 355;
331             }
332         }
333
334         /*==========================ConvertHijriToGregorian==========================
335         ** Purpose: convert Hdate(year,month,day) to Gdate(year,month,day)
336         ** Arguments:                                                                                                                
337         ** Input: Hijrah  date: year:HijriYear, month:HijriMonth, day:HijriDay                                                  
338         ** Output: Gregorian date: year:yg, month:mg, day:dg
339         =========================ConvertHijriToGregorian============================*/
340         static void ConvertHijriToGregorian(int HijriYear, int HijriMonth, int HijriDay, ref int yg, ref int mg, ref int dg)
341         {
342             Contract.Assert( (HijriYear >= MinCalendarYear) && (HijriYear <= MaxCalendarYear), "Hijri year is out of range.");
343             Contract.Assert( HijriMonth >= 1, "Hijri month is out of range.");
344             Contract.Assert( HijriDay >= 1, "Hijri day is out of range.");
345             int index, b, nDays = HijriDay-1;
346             DateTime dt;
347             
348
349             index = HijriYear - MinCalendarYear;
350             dt = HijriYearInfo[index].GregorianDate;
351
352
353             b = HijriYearInfo[index].HijriMonthsLengthFlags;
354
355             for(int m = 1; m < HijriMonth; m++)
356             {
357                 nDays += 29 + (b & 0x1);
358                 b = b >> 1;
359             }
360
361             dt = dt.AddDays(nDays);
362             yg = dt.Year;
363             mg = dt.Month;
364             dg = dt.Day;
365         }
366
367         /*=================================GetAbsoluteDateUmAlQura==========================
368         **Action: Gets the Absolute date for the given UmAlQura date.  The absolute date means
369         **       the number of days from January 1st, 1 A.D.
370         **Returns:
371         **Arguments:
372         **Exceptions:
373         ============================================================================*/
374         static long GetAbsoluteDateUmAlQura(int year, int month, int day) {
375             //Caller should check the validaty of year, month and day.
376
377             int yg=0,mg=0,dg=0;
378             ConvertHijriToGregorian(year, month, day, ref yg, ref mg, ref dg);
379             return GregorianCalendar.GetAbsoluteDate(yg,mg,dg);
380         }
381
382         static internal void CheckTicksRange(long ticks)  {
383             if (ticks < minDate.Ticks || ticks > maxDate.Ticks)  {
384                 throw new ArgumentOutOfRangeException(
385                             "time",
386                             String.Format(
387                                 CultureInfo.InvariantCulture,
388                                 Environment.GetResourceString("ArgumentOutOfRange_CalendarRange"),
389                                 minDate,
390                                 maxDate));
391             }
392         }
393
394         static internal void CheckEraRange(int era) {
395             if (era != CurrentEra && era != UmAlQuraEra) {
396                 throw new ArgumentOutOfRangeException("era", Environment.GetResourceString("ArgumentOutOfRange_InvalidEraValue"));
397             }
398         }
399
400         static internal void CheckYearRange(int year, int era)  {
401             CheckEraRange(era);
402             if (year < MinCalendarYear || year > MaxCalendarYear)  {
403                 throw new ArgumentOutOfRangeException(
404                             "year",
405                             String.Format(
406                                 CultureInfo.CurrentCulture,
407                                 Environment.GetResourceString("ArgumentOutOfRange_Range"),
408                                 MinCalendarYear,
409                                 MaxCalendarYear));
410             }
411         }
412
413         static internal void CheckYearMonthRange(int year, int month, int era)  {
414             CheckYearRange(year, era);
415             if (month < 1 || month > 12)  {
416                 throw new ArgumentOutOfRangeException("month", Environment.GetResourceString("ArgumentOutOfRange_Month"));
417             }
418         }
419
420         /*========================ConvertGregorianToHijri============================
421         ** Purpose: convert DateTime to Hdate(year,month,day)                                                   
422         ** Arguments:                                                                                                                
423         ** Input: DateTime                                                                                                         
424         ** Output: Hijrah  date: year:HijriYear, month:HijriMonth, day:HijriDay                                                          
425         ============================================================================*/
426         static void ConvertGregorianToHijri(DateTime time, ref int HijriYear, ref int HijriMonth, ref int HijriDay)
427         {
428
429             int index, b, DaysPerThisMonth;
430             double nDays;
431             TimeSpan ts;
432             int yh1=0, mh1=0, dh1=0;
433
434             Contract.Assert((time.Ticks >= minDate.Ticks) && (time.Ticks <= maxDate.Ticks), "Gregorian date is out of range.");
435
436             // Find the index where we should start our search by quessing the Hijri year that we will be in HijriYearInfo.
437             // A Hijri year is 354 or 355 days.  Use 355 days so that we will search from a lower index.
438             
439             index = (int)((time.Ticks - minDate.Ticks) / Calendar.TicksPerDay) / 355;
440             do 
441             {
442             } while (time.CompareTo(HijriYearInfo[++index].GregorianDate)>0); //while greater
443
444             if (time.CompareTo(HijriYearInfo[index].GregorianDate) != 0)
445             {
446                 index--;
447             }
448
449             ts = time.Subtract(HijriYearInfo[index].GregorianDate);
450             yh1 = index + MinCalendarYear;
451             
452             mh1 = 1;
453             dh1 = 1;
454             nDays = ts.TotalDays;
455             b = HijriYearInfo[index].HijriMonthsLengthFlags;
456             DaysPerThisMonth = 29 + (b&1);
457
458             while (nDays >= DaysPerThisMonth)
459             {
460                 nDays -= DaysPerThisMonth;
461                 b = b >> 1;
462                 DaysPerThisMonth = 29 + (b&1);
463                 mh1++;
464             }
465             dh1 += (int)nDays;
466
467             HijriDay = dh1;
468             HijriMonth = mh1;
469             HijriYear = yh1;
470         }
471
472         /*=================================GetDatePart==========================
473         **Action: Returns a given date part of this <i>DateTime</i>. This method is used
474         **       to compute the year, day-of-year, month, or day part.
475         **Returns:
476         **Arguments:
477         **Exceptions:  ArgumentException if part is incorrect.
478         **Notes:
479         **      First, we get the absolute date (the number of days from January 1st, 1 A.C) for the given ticks.
480         **      Use the formula (((AbsoluteDate - 226894) * 33) / (33 * 365 + 8)) + 1, we can a rough value for the UmAlQura year.
481         **      In order to get the exact UmAlQura year, we compare the exact absolute date for UmAlQuraYear and (UmAlQuraYear + 1).
482         **      From here, we can get the correct UmAlQura year.
483         ============================================================================*/
484
485         internal virtual int GetDatePart(DateTime time, int part) {
486             int UmAlQuraYear=0;              // UmAlQura year
487             int UmAlQuraMonth=0;             // UmAlQura month
488             int UmAlQuraDay=0;               // UmAlQura day
489             long ticks = time.Ticks;
490             CheckTicksRange(ticks);
491
492             ConvertGregorianToHijri(time, ref UmAlQuraYear, ref UmAlQuraMonth, ref UmAlQuraDay);
493
494             if (part == DatePartYear)
495                 return (UmAlQuraYear);
496
497             if (part == DatePartMonth)
498                 return (UmAlQuraMonth);
499
500             if (part == DatePartDay)
501                 return (UmAlQuraDay);
502
503             if (part == DatePartDayOfYear)
504                 return (int)(GetAbsoluteDateUmAlQura(UmAlQuraYear, UmAlQuraMonth, UmAlQuraDay) - GetAbsoluteDateUmAlQura(UmAlQuraYear, 1, 1) + 1);
505
506             // Incorrect part value.
507             throw new InvalidOperationException(Environment.GetResourceString("InvalidOperation_DateTimeParsing"));
508         }
509
510         // Returns the DateTime resulting from adding the given number of
511         // months to the specified DateTime. The result is computed by incrementing
512         // (or decrementing) the year and month parts of the specified DateTime by
513         // value months, and, if required, adjusting the day part of the
514         // resulting date downwards to the last day of the resulting month in the
515         // resulting year. The time-of-day part of the result is the same as the
516         // time-of-day part of the specified DateTime.
517         //
518         // In more precise terms, considering the specified DateTime to be of the
519         // form y / m / d + t, where y is the
520         // year, m is the month, d is the day, and t is the
521         // time-of-day, the result is y1 / m1 / d1 + t,
522         // where y1 and m1 are computed by adding value months
523         // to y and m, and d1 is the largest value less than
524         // or equal to d that denotes a valid day in month m1 of year
525         // y1.
526         //
527
528
529         public override DateTime AddMonths(DateTime time, int months)  {
530             if (months < -120000 || months > 120000)  {
531                 throw new ArgumentOutOfRangeException(
532                             "months",
533                             String.Format(
534                                 CultureInfo.CurrentCulture,
535                                 Environment.GetResourceString("ArgumentOutOfRange_Range"),
536                                 -120000,
537                                 120000));
538             }
539             Contract.EndContractBlock();
540             // Get the date in UmAlQura calendar.
541             int y = GetDatePart(time, DatePartYear);
542             int m = GetDatePart(time, DatePartMonth);
543             int d = GetDatePart(time, DatePartDay);
544             int i = m - 1 + months;
545
546             if (i >= 0)  {
547                 m = i % 12 + 1;
548                 y = y + i / 12;
549             }  else  {
550                 m = 12 + (i + 1) % 12;
551                 y = y + (i - 11) / 12;
552             }
553
554             if (d>29)
555             {
556                 int days = GetDaysInMonth(y, m);
557                 if (d > days) {
558                     d = days;
559                 }
560             }
561          CheckYearRange(y, UmAlQuraEra);            
562             DateTime dt = new DateTime(GetAbsoluteDateUmAlQura(y, m, d) * TicksPerDay + time.Ticks % TicksPerDay);
563             Calendar.CheckAddResult(dt.Ticks, MinSupportedDateTime, MaxSupportedDateTime);
564             return (dt);
565         }
566
567         // Returns the DateTime resulting from adding the given number of
568         // years to the specified DateTime. The result is computed by incrementing
569         // (or decrementing) the year part of the specified DateTime by value
570         // years. If the month and day of the specified DateTime is 2/29, and if the
571         // resulting year is not a leap year, the month and day of the resulting
572         // DateTime becomes 2/28. Otherwise, the month, day, and time-of-day
573         // parts of the result are the same as those of the specified DateTime.
574         //
575
576
577         public override DateTime AddYears(DateTime time, int years) {
578             return (AddMonths(time, years * 12));
579         }
580
581         // Returns the day-of-month part of the specified DateTime. The returned
582         // value is an integer between 1 and 31.
583         //
584
585
586         public override int GetDayOfMonth(DateTime time) {
587             return (GetDatePart(time, DatePartDay));
588         }
589
590         // Returns the day-of-week part of the specified DateTime. The returned value
591         // is an integer between 0 and 6, where 0 indicates Sunday, 1 indicates
592         // Monday, 2 indicates Tuesday, 3 indicates Wednesday, 4 indicates
593         // Thursday, 5 indicates Friday, and 6 indicates Saturday.
594         //
595
596
597         public override DayOfWeek GetDayOfWeek(DateTime time) {
598             return ((DayOfWeek)((int)(time.Ticks / TicksPerDay + 1) % 7));
599         }
600
601         // Returns the day-of-year part of the specified DateTime. The returned value
602         // is an integer between 1 and 354 or 355.
603         //
604
605
606         public override int GetDayOfYear(DateTime time) {
607             return (GetDatePart(time, DatePartDayOfYear));
608         }
609
610         /*
611         internal bool CouldBeLeapYear(int year)
612         {
613             return ((((year * 11) + 14) % 30) < 11);
614         }
615         */
616         
617         // Returns the number of days in the month given by the year and
618         // month arguments.
619         //
620
621
622         public override int GetDaysInMonth(int year, int month, int era) {
623             CheckYearMonthRange(year, month, era);
624
625             if ((HijriYearInfo[year-MinCalendarYear].HijriMonthsLengthFlags & (1<<month-1))==0)
626                 return 29;
627             else
628                 return 30;
629         }
630
631         static internal int RealGetDaysInYear(int year)
632         {
633             int days = 0, b;
634
635             Contract.Assert( (year >= MinCalendarYear) && (year <= MaxCalendarYear), "Hijri year is out of range.");
636
637             b = HijriYearInfo[year-MinCalendarYear].HijriMonthsLengthFlags;
638
639             for(int m = 1; m <= 12; m++)
640             {
641                 days += 29 + (b & 0x1);
642                 b = b >> 1;
643             }
644             Contract.Assert((days == 354)||(days == 355), "Hijri year has to be 354 or 355 days.");
645             return days;
646         }
647
648         // Returns the number of days in the year given by the year argument for the current era.
649         //
650
651
652         public override int GetDaysInYear(int year, int era)
653         {
654             CheckYearRange(year, era);
655             return (RealGetDaysInYear(year));
656         }
657
658         // Returns the era for the specified DateTime value.
659
660
661         public override int GetEra(DateTime time) {
662             CheckTicksRange(time.Ticks);
663             return (UmAlQuraEra);
664         }
665
666
667
668         public override int[] Eras {
669             get {
670                 return (new int[] {UmAlQuraEra});
671             }
672         }
673
674         // Returns the month part of the specified DateTime. The returned value is an
675         // integer between 1 and 12.
676         //
677
678
679         public override int GetMonth(DateTime time) {
680             return (GetDatePart(time, DatePartMonth));
681         }
682
683         // Returns the number of months in the specified year and era.
684
685
686         public override int GetMonthsInYear(int year, int era) {
687             CheckYearRange(year, era);
688             return (12);
689         }
690
691         // Returns the year part of the specified DateTime. The returned value is an
692         // integer between MinCalendarYear and MaxCalendarYear.
693         //
694
695
696         public override int GetYear(DateTime time) {
697             return (GetDatePart(time, DatePartYear));
698         }
699
700         // Checks whether a given day in the specified era is a leap day. This method returns true if
701         // the date is a leap day, or false if not.
702         //
703
704
705         public override bool IsLeapDay(int year, int month, int day, int era) {
706             if (day>=1 && day <=29)
707             {
708                 CheckYearMonthRange(year, month, era);
709                 return (false);
710             }
711
712             // The year/month/era value checking is done in GetDaysInMonth().
713             int daysInMonth = GetDaysInMonth(year, month, era);
714             if (day < 1 || day > daysInMonth) {
715                 throw new ArgumentOutOfRangeException(
716                             "day",
717                             String.Format(
718                                 CultureInfo.CurrentCulture,
719                                 Environment.GetResourceString("ArgumentOutOfRange_Day"),
720                                 daysInMonth,
721                                 month));
722             }
723             return (false);
724         }
725
726         // Returns  the leap month in a calendar year of the specified era. This method returns 0
727         // if this calendar does not have leap month, or this year is not a leap year.
728         //
729
730
731         public override int GetLeapMonth(int year, int era)
732         {
733             CheckYearRange(year, era);
734             return (0);
735         }
736
737         // Checks whether a given month in the specified era is a leap month. This method returns true if
738         // month is a leap month, or false if not.
739         //
740
741
742         public override bool IsLeapMonth(int year, int month, int era) {
743             CheckYearMonthRange(year, month, era);
744             return (false);
745         }
746
747         // Checks whether a given year in the specified era is a leap year. This method returns true if
748         // year is a leap year, or false if not.
749         //
750
751
752         public override bool IsLeapYear(int year, int era)
753         {
754             CheckYearRange(year, era);
755             if (RealGetDaysInYear(year) == 355)
756                 return true;
757             else
758                 return false;
759         }
760
761         // Returns the date and time converted to a DateTime value.  Throws an exception if the n-tuple is invalid.
762         //
763
764
765         public override DateTime ToDateTime(int year, int month, int day, int hour, int minute, int second, int millisecond, int era) {
766             if (day >= 1 && day <= 29)
767             {
768                 CheckYearMonthRange(year, month, era);
769                 goto DayInRang;
770             }
771
772             // The year/month/era value checking is done in GetDaysInMonth().
773              int daysInMonth = GetDaysInMonth(year, month, era);
774
775              if (day < 1 || day > daysInMonth) {
776                  BCLDebug.Log("year = " + year + ", month = " + month + ", day = " + day);
777                  throw new ArgumentOutOfRangeException(
778                             "day",
779                             String.Format(
780                                 CultureInfo.CurrentCulture,
781                                 Environment.GetResourceString("ArgumentOutOfRange_Day"),
782                                 daysInMonth,
783                                 month));
784              }
785 DayInRang:
786             long lDate = GetAbsoluteDateUmAlQura(year, month, day);
787
788             if (lDate >= 0) {
789                 return (new DateTime(lDate * GregorianCalendar.TicksPerDay + TimeToTicks(hour, minute, second, millisecond)));
790             } else {
791                 throw new ArgumentOutOfRangeException(null, Environment.GetResourceString("ArgumentOutOfRange_BadYearMonthDay"));
792             }
793         }
794
795         private const int DEFAULT_TWO_DIGIT_YEAR_MAX = 1451;
796
797
798
799         public override int TwoDigitYearMax {
800             get {
801                 if (twoDigitYearMax == -1) {
802                     twoDigitYearMax = GetSystemTwoDigitYearSetting(ID, DEFAULT_TWO_DIGIT_YEAR_MAX);
803                 }
804                 return (twoDigitYearMax);
805             }
806
807             set {
808                 if (value != 99 && (value < MinCalendarYear || value > MaxCalendarYear)) {
809                     throw new ArgumentOutOfRangeException(
810                                 "value",
811                                 String.Format(
812                                     CultureInfo.CurrentCulture,
813                                     Environment.GetResourceString("ArgumentOutOfRange_Range"),
814                                     MinCalendarYear,
815                                     MaxCalendarYear));
816                 }
817                 Contract.EndContractBlock();
818                 VerifyWritable();
819                 // We allow year 99 to be set so that one can make ToFourDigitYearMax a no-op by setting TwoDigitYearMax to 99.
820                 twoDigitYearMax = value;
821             }
822         }
823
824
825
826         public override int ToFourDigitYear(int year) {
827             if (year < 0) {
828                 throw new ArgumentOutOfRangeException("year",
829                     Environment.GetResourceString("ArgumentOutOfRange_NeedNonNegNum"));
830             }
831             Contract.EndContractBlock();
832
833             if (year < 100) {
834                 return (base.ToFourDigitYear(year));
835             }
836
837             if ((year < MinCalendarYear) || (year > MaxCalendarYear)) {
838                 throw new ArgumentOutOfRangeException(
839                             "year",
840                             String.Format(
841                                     CultureInfo.CurrentCulture,
842                                     Environment.GetResourceString("ArgumentOutOfRange_Range"),
843                                     MinCalendarYear,
844                                     MaxCalendarYear));
845             }
846             return (year);
847         }
848     }
849 }
850