The Labs \ Source Viewer \ SSCLI \ System.Globalization \ DateMapping

  1. // ==++==
  2. //
  3. //
  4. // Copyright (c) 2006 Microsoft Corporation. All rights reserved.
  5. //
  6. // The use and distribution terms for this software are contained in the file
  7. // named license.txt, which can be found in the root of this distribution.
  8. // By using this software in any fashion, you are agreeing to be bound by the
  9. // terms of this license.
  10. //
  11. // You must not remove this notice, or any other, from this software.
  12. //
  13. //
  14. // ==--==
  15. namespace System.Globalization
  16. {
  17.     using System;
  18.    
  19.    
  20.     ////////////////////////////////////////////////////////////////////////////
  21.     //
  22.     // Notes about UmAlQuraCalendar
  23.     //
  24.     ////////////////////////////////////////////////////////////////////////////
  25. /*
  26.     **  Calendar support range:
  27.     **      Calendar    Minimum    Maximum
  28.     **      ==========  ==========  ==========
  29.     **      Gregorian  1900/04/30  2029/05/13
  30.     **      UmAlQura    1318/01/01  1450/12/29
  31.     */   
  32.    
  33.     [Serializable()]
  34.     public class UmAlQuraCalendar : Calendar
  35.     {
  36.        
  37.         internal const int MinCalendarYear = 1318;
  38.         internal const int MaxCalendarYear = 1450;
  39.        
  40.         internal struct DateMapping
  41.         {
  42.             internal DateMapping(int MonthsLengthFlags, int GYear, int GMonth, int GDay)
  43.             {
  44.                 HijriMonthsLengthFlags = MonthsLengthFlags;
  45.                 GregorianDate = new DateTime(GYear, GMonth, GDay);
  46.             }
  47.             internal int HijriMonthsLengthFlags;
  48.             internal DateTime GregorianDate;
  49.         }
  50.        
  51.         //These data is taken from Tables/Excel/UmAlQura.xls please make sure that the two places are in sync
  52.         static readonly DateMapping[] HijriYearInfo = {new DateMapping(746, 1900, 4, 30), new DateMapping(1769, 1901, 4, 19), new DateMapping(3794, 1902, 4, 9), new DateMapping(3748, 1903, 3, 30), new DateMapping(3402, 1904, 3, 18), new DateMapping(2710, 1905, 3, 7), new DateMapping(1334, 1906, 2, 24), new DateMapping(2741, 1907, 2, 13), new DateMapping(3498, 1908, 2, 3), new DateMapping(2980, 1909, 1, 23),
  53.         new DateMapping(2889, 1910, 1, 12), new DateMapping(2707, 1911, 1, 1), new DateMapping(1323, 1911, 12, 21), new DateMapping(2647, 1912, 12, 9), new DateMapping(1206, 1913, 11, 29), new DateMapping(2741, 1914, 11, 18), new DateMapping(1450, 1915, 11, 8), new DateMapping(3413, 1916, 10, 27), new DateMapping(3370, 1917, 10, 17), new DateMapping(2646, 1918, 10, 6),
  54.         new DateMapping(1198, 1919, 9, 25), new DateMapping(2397, 1920, 9, 13), new DateMapping(748, 1921, 9, 3), new DateMapping(1749, 1922, 8, 23), new DateMapping(1706, 1923, 8, 13), new DateMapping(1365, 1924, 8, 1), new DateMapping(1195, 1925, 7, 21), new DateMapping(2395, 1926, 7, 10), new DateMapping(698, 1927, 6, 30), new DateMapping(1397, 1928, 6, 18),
  55.         new DateMapping(2994, 1929, 6, 8), new DateMapping(1892, 1930, 5, 29), new DateMapping(1865, 1931, 5, 18), new DateMapping(1621, 1932, 5, 6), new DateMapping(683, 1933, 4, 25), new DateMapping(1371, 1934, 4, 14), new DateMapping(2778, 1935, 4, 4), new DateMapping(1748, 1936, 3, 24), new DateMapping(3785, 1937, 3, 13), new DateMapping(3474, 1938, 3, 3),
  56.         new DateMapping(3365, 1939, 2, 20), new DateMapping(2637, 1940, 2, 9), new DateMapping(685, 1941, 1, 28), new DateMapping(1389, 1942, 1, 17), new DateMapping(2922, 1943, 1, 7), new DateMapping(2898, 1943, 12, 28), new DateMapping(2725, 1944, 12, 16), new DateMapping(2635, 1945, 12, 5), new DateMapping(1175, 1946, 11, 24), new DateMapping(2359, 1947, 11, 13),
  57.         new DateMapping(694, 1948, 11, 2), new DateMapping(1397, 1949, 10, 22), new DateMapping(3434, 1950, 10, 12), new DateMapping(3410, 1951, 10, 2), new DateMapping(2710, 1952, 9, 20), new DateMapping(2349, 1953, 9, 9), new DateMapping(605, 1954, 8, 29), new DateMapping(1245, 1955, 8, 18), new DateMapping(2778, 1956, 8, 7), new DateMapping(1492, 1957, 7, 28),
  58.         new DateMapping(3497, 1958, 7, 17), new DateMapping(3410, 1959, 7, 7), new DateMapping(2730, 1960, 6, 25), new DateMapping(1238, 1961, 6, 14), new DateMapping(2486, 1962, 6, 3), new DateMapping(884, 1963, 5, 24), new DateMapping(1897, 1964, 5, 12), new DateMapping(1874, 1965, 5, 2), new DateMapping(1701, 1966, 4, 21), new DateMapping(1355, 1967, 4, 10),
  59.         new DateMapping(2731, 1968, 3, 29), new DateMapping(1370, 1969, 3, 19), new DateMapping(2773, 1970, 3, 8), new DateMapping(3538, 1971, 2, 26), new DateMapping(3492, 1972, 2, 16), new DateMapping(3401, 1973, 2, 4), new DateMapping(2709, 1974, 1, 24), new DateMapping(1325, 1975, 1, 13), new DateMapping(2653, 1976, 1, 2), new DateMapping(1370, 1976, 12, 22),
  60.         new DateMapping(2773, 1977, 12, 11), new DateMapping(1706, 1978, 12, 1), new DateMapping(1685, 1979, 11, 20), new DateMapping(1323, 1980, 11, 8), new DateMapping(2647, 1981, 10, 28), new DateMapping(1198, 1982, 10, 18), new DateMapping(2422, 1983, 10, 7), new DateMapping(1388, 1984, 9, 26), new DateMapping(2901, 1985, 9, 15), new DateMapping(2730, 1986, 9, 5),
  61.         new DateMapping(2645, 1987, 8, 25), new DateMapping(1197, 1988, 8, 13), new DateMapping(2397, 1989, 8, 2), new DateMapping(730, 1990, 7, 23), new DateMapping(1497, 1991, 7, 12), new DateMapping(3506, 1992, 7, 1), new DateMapping(2980, 1993, 6, 21), new DateMapping(2890, 1994, 6, 10), new DateMapping(2645, 1995, 5, 30), new DateMapping(693, 1996, 5, 18),
  62.         new DateMapping(1397, 1997, 5, 7), new DateMapping(2922, 1998, 4, 27), new DateMapping(3026, 1999, 4, 17), new DateMapping(3012, 2000, 4, 6), new DateMapping(2953, 2001, 3, 26), new DateMapping(2709, 2002, 3, 15), new DateMapping(1325, 2003, 3, 4), new DateMapping(1453, 2004, 2, 21), new DateMapping(2922, 2005, 2, 10), new DateMapping(1748, 2006, 1, 31),
  63.         new DateMapping(3529, 2007, 1, 20), new DateMapping(3474, 2008, 1, 10), new DateMapping(2726, 2008, 12, 29), new DateMapping(2390, 2009, 12, 18), new DateMapping(686, 2010, 12, 7), new DateMapping(1389, 2011, 11, 26), new DateMapping(874, 2012, 11, 15), new DateMapping(2901, 2013, 11, 4), new DateMapping(2730, 2014, 10, 25), new DateMapping(2381, 2015, 10, 14),
  64.         new DateMapping(1181, 2016, 10, 2), new DateMapping(2397, 2017, 9, 21), new DateMapping(698, 2018, 9, 11), new DateMapping(1461, 2019, 8, 31), new DateMapping(1450, 2020, 8, 20), new DateMapping(3413, 2021, 8, 9), new DateMapping(2714, 2022, 7, 30), new DateMapping(2350, 2023, 7, 19), new DateMapping(622, 2024, 7, 7), new DateMapping(1373, 2025, 6, 26),
  65.             /*                    DaysPerM    GY      GM    GD    D1  D2  D3  D4  D5  D6  D7  D8  D9  D10  D11  D12   
  66. 1318*/            /* 0    1    0    1    0    1    1    1    0    1    0    0    4/30/1900
  67. 1319*/            /* 1    0    0    1    0    1    1    1    0    1    1    0    4/19/1901
  68. 1320*/            /* 0    1    0    0    1    0    1    1    0    1    1    1    4/9/1902
  69. 1321*/            /* 0    0    1    0    0    1    0    1    0    1    1    1    3/30/1903
  70. 1322*/            /* 0    1    0    1    0    0    1    0    1    0    1    1    3/18/1904
  71. 1323*/            /* 0    1    1    0    1    0    0    1    0    1    0    1    3/7/1905
  72. 1324*/            /* 0    1    1    0    1    1    0    0    1    0    1    0    2/24/1906
  73. 1325*/            /* 1    0    1    0    1    1    0    1    0    1    0    1    2/13/1907
  74. 1326*/            /* 0    1    0    1    0    1    0    1    1    0    1    1    2/3/1908
  75. 1327*/            /* 0    0    1    0    0    1    0    1    1    1    0    1    1/23/1909
  76. 1328*/            /* 1    0    0    1    0    0    1    0    1    1    0    1    1/12/1910
  77. 1329*/            /* 1    1    0    0    1    0    0    1    0    1    0    1    1/1/1911
  78. 1330*/            /* 1    1    0    1    0    1    0    0    1    0    1    0    12/21/1911
  79. 1331*/            /* 1    1    1    0    1    0    1    0    0    1    0    1    12/9/1912
  80. 1332*/            /* 0    1    1    0    1    1    0    1    0    0    1    0    11/29/1913
  81. 1333*/            /* 1    0    1    0    1    1    0    1    0    1    0    1    11/18/1914
  82. 1334*/            /* 0    1    0    1    0    1    0    1    1    0    1    0    11/8/1915
  83. 1335*/            /* 1    0    1    0    1    0    1    0    1    0    1    1    10/27/1916
  84. 1336*/            /* 0    1    0    1    0    1    0    0    1    0    1    1    10/17/1917
  85. 1337*/            /* 0    1    1    0    1    0    1    0    0    1    0    1    10/6/1918
  86. 1338*/            /* 0    1    1    1    0    1    0    1    0    0    1    0    9/25/1919
  87. 1339*/            /* 1    0    1    1    1    0    1    0    1    0    0    1    9/13/1920
  88. 1340*/            /* 0    0    1    1    0    1    1    1    0    1    0    0    9/3/1921
  89. 1341*/            /* 1    0    1    0    1    0    1    1    0    1    1    0    8/23/1922
  90. 1342*/            /* 0    1    0    1    0    1    0    1    0    1    1    0    8/13/1923
  91. 1343*/            /* 1    0    1    0    1    0    1    0    1    0    1    0    8/1/1924
  92. 1344*/            /* 1    1    0    1    0    1    0    1    0    0    1    0    7/21/1925
  93. 1345*/            /* 1    1    0    1    1    0    1    0    1    0    0    1    7/10/1926
  94. 1346*/            /* 0    1    0    1    1    1    0    1    0    1    0    0    6/30/1927
  95. 1347*/            /* 1    0    1    0    1    1    1    0    1    0    1    0    6/18/1928
  96. 1348*/            /* 0    1    0    0    1    1    0    1    1    1    0    1    6/8/1929
  97. 1349*/            /* 0    0    1    0    0    1    1    0    1    1    1    0    5/29/1930
  98. 1350*/            /* 1    0    0    1    0    0    1    0    1    1    1    0    5/18/1931
  99. 1351*/            /* 1    0    1    0    1    0    1    0    0    1    1    0    5/6/1932
  100. 1352*/            /* 1    1    0    1    0    1    0    1    0    1    0    0    4/25/1933
  101. 1353*/            /* 1    1    0    1    1    0    1    0    1    0    1    0    4/14/1934
  102. 1354*/            /* 0    1    0    1    1    0    1    1    0    1    0    1    4/4/1935
  103. 1355*/            /* 0    0    1    0    1    0    1    1    0    1    1    0    3/24/1936
  104. 1356*/            /* 1    0    0    1    0    0    1    1    0    1    1    1    3/13/1937
  105. 1357*/            /* 0    1    0    0    1    0    0    1    1    0    1    1    3/3/1938
  106. 1358*/            /* 1    0    1    0    0    1    0    0    1    0    1    1    2/20/1939
  107. 1359*/            /* 1    0    1    1    0    0    1    0    0    1    0    1    2/9/1940
  108. 1360*/            /* 1    0    1    1    0    1    0    1    0    1    0    0    1/28/1941
  109. 1361*/            /* 1    0    1    1    0    1    1    0    1    0    1    0    1/17/1942
  110. 1362*/            /* 0    1    0    1    0    1    1    0    1    1    0    1    1/7/1943
  111. 1363*/            /* 0    1    0    0    1    0    1    0    1    1    0    1    12/28/1943
  112. 1364*/            /* 1    0    1    0    0    1    0    1    0    1    0    1    12/16/1944
  113. 1365*/            /* 1    1    0    1    0    0    1    0    0    1    0    1    12/5/1945
  114. 1366*/            /* 1    1    1    0    1    0    0    1    0    0    1    0    11/24/1946
  115. 1367*/            /* 1    1    1    0    1    1    0    0    1    0    0    1    11/13/1947
  116. 1368*/            /* 0    1    1    0    1    1    0    1    0    1    0    0    11/2/1948
  117. 1369*/            /* 1    0    1    0    1    1    1    0    1    0    1    0    10/22/1949
  118. 1370*/            /* 0    1    0    1    0    1    1    0    1    0    1    1    10/12/1950
  119. 1371*/            /* 0    1    0    0    1    0    1    0    1    0    1    1    10/2/1951
  120. 1372*/            /* 0    1    1    0    1    0    0    1    0    1    0    1    9/20/1952
  121. 1373*/            /* 1    0    1    1    0    1    0    0    1    0    0    1    9/9/1953
  122. 1374*/            /* 1    0    1    1    1    0    1    0    0    1    0    0    8/29/1954
  123. 1375*/            /* 1    0    1    1    1    0    1    1    0    0    1    0    8/18/1955
  124. 1376*/            /* 0    1    0    1    1    0    1    1    0    1    0    1    8/7/1956
  125. 1377*/            /* 0    0    1    0    1    0    1    1    1    0    1    0    7/28/1957
  126. 1378*/            /* 1    0    0    1    0    1    0    1    1    0    1    1    7/17/1958
  127. 1379*/            /* 0    1    0    0    1    0    1    0    1    0    1    1    7/7/1959
  128. 1380*/            /* 0    1    0    1    0    1    0    1    0    1    0    1    6/25/1960
  129. 1381*/            /* 0    1    1    0    1    0    1    1    0    0    1    0    6/14/1961
  130. 1382*/            /* 0    1    1    0    1    1    0    1    1    0    0    1    6/3/1962
  131. 1383*/            /* 0    0    1    0    1    1    1    0    1    1    0    0    5/24/1963
  132. 1384*/            /* 1    0    0    1    0    1    1    0    1    1    1    0    5/12/1964
  133. 1385*/            /* 0    1    0    0    1    0    1    0    1    1    1    0    5/2/1965
  134. 1386*/            /* 1    0    1    0    0    1    0    1    0    1    1    0    4/21/1966
  135. 1387*/            /* 1    1    0    1    0    0    1    0    1    0    1    0    4/10/1967
  136. 1388*/            /* 1    1    0    1    0    1    0    1    0    1    0    1    3/29/1968
  137. 1389*/            /* 0    1    0    1    1    0    1    0    1    0    1    0    3/19/1969
  138. 1390*/            /* 1    0    1    0    1    0    1    1    0    1    0    1    3/8/1970
  139. 1391*/            /* 0    1    0    0    1    0    1    1    1    0    1    1    2/26/1971
  140. 1392*/            /* 0    0    1    0    0    1    0    1    1    0    1    1    2/16/1972
  141. 1393*/            /* 1    0    0    1    0    0    1    0    1    0    1    1    2/4/1973
  142. 1394*/            /* 1    0    1    0    1    0    0    1    0    1    0    1    1/24/1974
  143. 1395*/            /* 1    0    1    1    0    1    0    0    1    0    1    0    1/13/1975
  144. 1396*/            /* 1    0    1    1    1    0    1    0    0    1    0    1    1/2/1976
  145. 1397*/            /* 0    1    0    1    1    0    1    0    1    0    1    0    12/22/1976
  146. 1398*/            /* 1    0    1    0    1    0    1    1    0    1    0    1    12/11/1977
  147. 1399*/            /* 0    1    0    1    0    1    0    1    0    1    1    0    12/1/1978
  148. 1400*/            /* 1    0    1    0    1    0    0    1    0    1    1    0    11/20/1979
  149. 1401*/            /* 1    1    0    1    0    1    0    0    1    0    1    0    11/8/1980
  150. 1402*/            /* 1    1    1    0    1    0    1    0    0    1    0    1    10/28/1981
  151. 1403*/            /* 0    1    1    1    0    1    0    1    0    0    1    0    10/18/1982
  152. 1404*/            /* 0    1    1    0    1    1    1    0    1    0    0    1    10/7/1983
  153. 1405*/            /* 0    0    1    1    0    1    1    0    1    0    1    0    9/26/1984
  154. 1406*/            /* 1    0    1    0    1    0    1    0    1    1    0    1    9/15/1985
  155. 1407*/            /* 0    1    0    1    0    1    0    1    0    1    0    1    9/5/1986
  156. 1408*/            /* 1    0    1    0    1    0    1    0    0    1    0    1    8/25/1987
  157. 1409*/            /* 1    0    1    1    0    1    0    1    0    0    1    0    8/13/1988
  158. 1410*/            /* 1    0    1    1    1    0    1    0    1    0    0    1    8/2/1989
  159. 1411*/            /* 0    1    0    1    1    0    1    1    0    1    0    0    7/23/1990
  160. 1412*/            /* 1    0    0    1    1    0    1    1    1    0    1    0    7/12/1991
  161. 1413*/            /* 0    1    0    0    1    1    0    1    1    0    1    1    7/1/1992
  162. 1414*/            /* 0    0    1    0    0    1    0    1    1    1    0    1    6/21/1993
  163. 1415*/            /* 0    1    0    1    0    0    1    0    1    1    0    1    6/10/1994
  164. 1416*/            /* 1    0    1    0    1    0    1    0    0    1    0    1    5/30/1995
  165. 1417*/            /* 1    0    1    0    1    1    0    1    0    1    0    0    5/18/1996
  166. 1418*/            /* 1    0    1    0    1    1    1    0    1    0    1    0    5/7/1997
  167. 1419*/            /* 0    1    0    1    0    1    1    0    1    1    0    1    4/27/1998
  168. 1420*/            /* 0    1    0    0    1    0    1    1    1    1    0    1    4/17/1999
  169. 1421*/            /* 0    0    1    0    0    0    1    1    1    1    0    1    4/6/2000
  170. 1422*/            /* 1    0    0    1    0    0    0    1    1    1    0    1    3/26/2001
  171. 1423*/            /* 1    0    1    0    1    0    0    1    0    1    0    1    3/15/2002
  172. 1424*/            /* 1    0    1    1    0    1    0    0    1    0    1    0    3/4/2003
  173. 1425*/            /* 1    0    1    1    0    1    0    1    1    0    1    0    2/21/2004
  174. 1426*/            /* 0    1    0    1    0    1    1    0    1    1    0    1    2/10/2005
  175. 1427*/            /* 0    0    1    0    1    0    1    1    0    1    1    0    1/31/2006
  176. 1428*/            /* 1    0    0    1    0    0    1    1    1    0    1    1    1/20/2007
  177. 1429*/            /* 0    1    0    0    1    0    0    1    1    0    1    1    1/10/2008
  178. 1430*/            /* 0    1    1    0    0    1    0    1    0    1    0    1    12/29/2008
  179. 1431*/            /* 0    1    1    0    1    0    1    0    1    0    0    1    12/18/2009
  180. 1432*/            /* 0    1    1    1    0    1    0    1    0    1    0    0    12/7/2010
  181. 1433*/            /* 1    0    1    1    0    1    1    0    1    0    1    0    11/26/2011
  182. 1434*/            /* 0    1    0    1    0    1    1    0    1    1    0    0    11/15/2012
  183. 1435*/            /* 1    0    1    0    1    0    1    0    1    1    0    1    11/4/2013
  184. 1436*/            /* 0    1    0    1    0    1    0    1    0    1    0    1    10/25/2014
  185. 1437*/            /* 1    0    1    1    0    0    1    0    1    0    0    1    10/14/2015
  186. 1438*/            /* 1    0    1    1    1    0    0    1    0    0    1    0    10/2/2016
  187. 1439*/            /* 1    0    1    1    1    0    1    0    1    0    0    1    9/21/2017
  188. 1440*/            /* 0    1    0    1    1    1    0    1    0    1    0    0    9/11/2018
  189. 1441*/            /* 1    0    1    0    1    1    0    1    1    0    1    0    8/31/2019
  190. 1442*/            /* 0    1    0    1    0    1    0    1    1    0    1    0    8/20/2020
  191. 1443*/            /* 1    0    1    0    1    0    1    0    1    0    1    1    8/9/2021
  192. 1444*/            /* 0    1    0    1    1    0    0    1    0    1    0    1    7/30/2022
  193. 1445*/            /* 0    1    1    1    0    1    0    0    1    0    0    1    7/19/2023
  194. 1446*/            /* 0    1    1    1    0    1    1    0    0    1    0    0    7/7/2024
  195. 1447*/            /* 1    0    1    1    1    0    1    0    1    0    1    0    6/26/2025
  196. 1448*/            /* 0    1    0    1    1    0    1    1    0    1    0    1    6/16/2026
  197. 1449*/            /* 0    0    1    0    1    0    1    1    0    1    1    0    6/6/2027
  198. 1450*/            /* 1    0    1    0    0    1    0    1    0    1    1    0    5/25/2028
  199. 1451*/            /* 0    0    0    0    0    0    0    0    0    0    0    0    5/14/2029
  200. */        new DateMapping(2778, 2026, 6, 16), new DateMapping(1748, 2027, 6, 6), new DateMapping(1701, 2028, 5, 25), new DateMapping(0, 2029, 5, 14)};
  201.        
  202.         public const int UmAlQuraEra = 1;
  203.        
  204.         internal const int DateCycle = 30;
  205.         internal const int DatePartYear = 0;
  206.         internal const int DatePartDayOfYear = 1;
  207.         internal const int DatePartMonth = 2;
  208.         internal const int DatePartDay = 3;
  209.        
  210.         static internal short[] gmonth = {31, 31, 28, 31, 30, 31, 30, 31, 31, 30,
  211.         31, 30, 31, 31};
  212. /* makes it circular m[0]=m[12] & m[13]=m[1] */       
  213.         //internal static Calendar m_defaultInstance;
  214.        
  215.        
  216.         // This is the minimal Gregorian date that we support in the UmAlQuraCalendar.
  217.         static internal DateTime minDate = new DateTime(1900, 4, 30);
  218.         static internal DateTime maxDate = new DateTime((new DateTime(2029, 5, 13, 23, 59, 59, 999)).Ticks + 9999);
  219.        
  220. /*=================================GetDefaultInstance==========================
  221.         **Action: Internal method to provide a default intance of UmAlQuraCalendar.  Used by NLS+ implementation
  222.         **      and other calendars.
  223.         **Returns:
  224.         **Arguments:
  225.         **Exceptions:
  226.         ============================================================================*/       
  227. /*
  228.         internal static Calendar GetDefaultInstance() {
  229.             if (m_defaultInstance == null) {
  230.                 m_defaultInstance = new UmAlQuraCalendar();
  231.             }
  232.             return (m_defaultInstance);
  233.         }
  234.         */       
  235.        
  236.        
  237.        
  238.         public override DateTime MinSupportedDateTime {
  239.             get { return (minDate); }
  240.         }
  241.        
  242.        
  243.         public override DateTime MaxSupportedDateTime {
  244.             get { return (maxDate); }
  245.         }
  246.        
  247.        
  248.         // Return the type of the UmAlQura calendar.
  249.         //
  250.        
  251.        
  252.         public override CalendarAlgorithmType AlgorithmType {
  253.             get { return CalendarAlgorithmType.LunarCalendar; }
  254.         }
  255.        
  256.         // Construct an instance of UmAlQura calendar.
  257.        
  258.         public UmAlQuraCalendar()
  259.         {
  260.         }
  261.        
  262.         internal override int BaseCalendarID {
  263.             get { return (CAL_HIJRI); }
  264.         }
  265.        
  266.         internal override int ID {
  267.             get { return (CAL_UMALQURA); }
  268.         }
  269. /*==========================ConvertHijriToGregorian==========================
  270.         ** Purpose: convert Hdate(year,month,day) to Gdate(year,month,day)                             
  271.         ** Arguments:                                                                                                               
  272.         ** Input/Ouput: Hijrah  date: year:yh, month:mh, day:dh                                                 
  273.         ** Output: Gregorian date: year:yg, month:mg, day:dg , day of week:dayweek                 
  274.         **      and returns flag found:1 not found:0                                                                     
  275.         =========================ConvertHijriToGregorian============================*/       
  276.         void ConvertHijriToGregorian(int HijriYear, int HijriMonth, int HijriDay, ref int yg, ref int mg, ref int dg)
  277.         {
  278.             BCLDebug.Assert((HijriYear >= MinCalendarYear) && (HijriYear <= MaxCalendarYear), "Hijri year is out of range.");
  279.             BCLDebug.Assert(HijriMonth >= 1, "Hijri month is out of range.");
  280.             BCLDebug.Assert(HijriDay >= 1, "Hijri day is out of range.");
  281.             int index;
  282.             int b;
  283.             int nDays = HijriDay - 1;
  284.             DateTime dt;
  285.            
  286.            
  287.             index = HijriYear - MinCalendarYear;
  288.             dt = HijriYearInfo[index].GregorianDate;
  289.            
  290.            
  291.             b = HijriYearInfo[index].HijriMonthsLengthFlags;
  292.            
  293.             for (int m = 1; m < HijriMonth; m++) {
  294.                 nDays = nDays + 29 + (b & 1);
  295.                 /* Add the months lengths before mh */b = b >> 1;
  296.             }
  297.            
  298.             dt = dt.AddDays(nDays);
  299.             yg = dt.Year;
  300.             mg = dt.Month;
  301.             dg = dt.Day;
  302.         }
  303.        
  304. /*=================================GetAbsoluteDateUmAlQura==========================
  305.         **Action: Gets the Absolute date for the given UmAlQura date.  The absolute date means
  306.         **      the number of days from January 1st, 1 A.D.
  307.         **Returns:
  308.         **Arguments:
  309.         **Exceptions:
  310.         ============================================================================*/       
  311.         long GetAbsoluteDateUmAlQura(int year, int month, int day)
  312.         {
  313.             //Caller should check the validaty of year, month and day.
  314.            
  315.             int yg = 0;
  316.             int mg = 0;
  317.             int dg = 0;
  318.             ConvertHijriToGregorian(year, month, day, ref yg, ref mg, ref dg);
  319.             return GregorianCalendar.GetAbsoluteDate(yg, mg, dg);
  320.         }
  321.        
  322.         internal void CheckTicksRange(long ticks)
  323.         {
  324.             if (ticks < minDate.Ticks || ticks > maxDate.Ticks) {
  325.                 throw new ArgumentOutOfRangeException("time", String.Format(CultureInfo.InvariantCulture, Environment.GetResourceString("ArgumentOutOfRange_CalendarRange"), minDate, maxDate));
  326.             }
  327.         }
  328.        
  329.         internal void CheckEraRange(int era)
  330.         {
  331.             if (era != CurrentEra && era != UmAlQuraEra) {
  332.                 throw new ArgumentOutOfRangeException("era", Environment.GetResourceString("ArgumentOutOfRange_InvalidEraValue"));
  333.             }
  334.         }
  335.        
  336.         internal void CheckYearRange(int year, int era)
  337.         {
  338.             CheckEraRange(era);
  339.             if (year < MinCalendarYear || year > MaxCalendarYear) {
  340.                 throw new ArgumentOutOfRangeException("year", String.Format(CultureInfo.CurrentCulture, Environment.GetResourceString("ArgumentOutOfRange_Range"), MinCalendarYear, MaxCalendarYear));
  341.             }
  342.         }
  343.        
  344.         internal void CheckYearMonthRange(int year, int month, int era)
  345.         {
  346.             CheckYearRange(year, era);
  347.             if (month < 1 || month > 12) {
  348.                 throw new ArgumentOutOfRangeException("month", Environment.GetResourceString("ArgumentOutOfRange_Month"));
  349.             }
  350.         }
  351.        
  352. /*========================ConvertGregorianToHijri============================
  353.         ** Purpose: convert DateTime to Hdate(year,month,day)                                                 
  354.         ** Arguments:                                                                                                               
  355.         ** Input: DateTime                                                                                                       
  356.         ** Output: Hijrah  date: year:yh, month:mh, day:dh                                                         
  357.         ============================================================================*/       
  358.         void ConvertGregorianToHijri(DateTime time, ref int HijriYear, ref int HijriMonth, ref int HijriDay)
  359.         {
  360.            
  361.             int index;
  362.             int b;
  363.             int DaysPerThisMonth;
  364.             double nDays;
  365.             TimeSpan ts;
  366.             int yh1 = 0;
  367.             int mh1 = 0;
  368.             int dh1 = 0;
  369.            
  370.             BCLDebug.Assert((time.Ticks >= minDate.Ticks) && (time.Ticks <= maxDate.Ticks), "Gregorian date is out of range.");
  371.            
  372.             // Find the index where we should start our search by quessing the Hijri year that we will be in HijriYearInfo.
  373.             // A Hijri year is 354 or 355 days. Use 355 days so that we will search from a lower index.
  374.            
  375.             index = (int)((time.Ticks - minDate.Ticks) / Calendar.TicksPerDay) / 355;
  376.             do {
  377.             }
  378.             while (time.CompareTo(HijriYearInfo[++index].GregorianDate) > 0);
  379.             //while greater
  380.             if (time.CompareTo(HijriYearInfo[index].GregorianDate) != 0) {
  381.                 index--;
  382.             }
  383.            
  384.             ts = time.Subtract(HijriYearInfo[index].GregorianDate);
  385.             yh1 = index + MinCalendarYear;
  386.            
  387.             mh1 = 1;
  388.             dh1 = 1;
  389.             nDays = ts.TotalDays;
  390.             b = HijriYearInfo[index].HijriMonthsLengthFlags;
  391.             DaysPerThisMonth = 29 + (b & 1);
  392.            
  393.             while (nDays >= DaysPerThisMonth) {
  394.                 nDays -= DaysPerThisMonth;
  395.                 b = b >> 1;
  396.                 DaysPerThisMonth = 29 + (b & 1);
  397.                 mh1++;
  398.             }
  399.             dh1 += (int)nDays;
  400.            
  401.             HijriDay = dh1;
  402.             HijriMonth = mh1;
  403.             HijriYear = yh1;
  404.         }
  405.        
  406. /*=================================GetDatePart==========================
  407.         **Action: Returns a given date part of this <i>DateTime</i>. This method is used
  408.         **      to compute the year, day-of-year, month, or day part.
  409.         **Returns:
  410.         **Arguments:
  411.         **Exceptions:  ArgumentException if part is incorrect.
  412.         **Notes:
  413.         **      First, we get the absolute date (the number of days from January 1st, 1 A.C) for the given ticks.
  414.         **      Use the formula (((AbsoluteDate - 226894) * 33) / (33 * 365 + 8)) + 1, we can a rough value for the UmAlQura year.
  415.         **      In order to get the exact UmAlQura year, we compare the exact absolute date for UmAlQuraYear and (UmAlQuraYear + 1).
  416.         **      From here, we can get the correct UmAlQura year.
  417.         ============================================================================*/       
  418.        
  419.         internal virtual int GetDatePart(DateTime time, int part)
  420.         {
  421.             int UmAlQuraYear = 0;
  422.             // UmAlQura year
  423.             int UmAlQuraMonth = 0;
  424.             // UmAlQura month
  425.             int UmAlQuraDay = 0;
  426.             // UmAlQura day
  427.             long ticks = time.Ticks;
  428.             CheckTicksRange(ticks);
  429.            
  430.             ConvertGregorianToHijri(time, ref UmAlQuraYear, ref UmAlQuraMonth, ref UmAlQuraDay);
  431.            
  432.             if (part == DatePartYear)
  433.                 return (UmAlQuraYear);
  434.            
  435.             if (part == DatePartMonth)
  436.                 return (UmAlQuraMonth);
  437.            
  438.             if (part == DatePartDay)
  439.                 return (UmAlQuraDay);
  440.            
  441.             if (part == DatePartDayOfYear)
  442.                 return (int)(GetAbsoluteDateUmAlQura(UmAlQuraYear, UmAlQuraMonth, UmAlQuraDay) - GetAbsoluteDateUmAlQura(UmAlQuraYear, 1, 1) + 1);
  443.            
  444.             // Incorrect part value.
  445.             throw new InvalidOperationException(Environment.GetResourceString("InvalidOperation_DateTimeParsing"));
  446.         }
  447.        
  448.         // Returns the DateTime resulting from adding the given number of
  449.         // months to the specified DateTime. The result is computed by incrementing
  450.         // (or decrementing) the year and month parts of the specified DateTime by
  451.         // value months, and, if required, adjusting the day part of the
  452.         // resulting date downwards to the last day of the resulting month in the
  453.         // resulting year. The time-of-day part of the result is the same as the
  454.         // time-of-day part of the specified DateTime.
  455.         //
  456.         // In more precise terms, considering the specified DateTime to be of the
  457.         // form y / m / d + t, where y is the
  458.         // year, m is the month, d is the day, and t is the
  459.         // time-of-day, the result is y1 / m1 / d1 + t,
  460.         // where y1 and m1 are computed by adding value months
  461.         // to y and m, and d1 is the largest value less than
  462.         // or equal to d that denotes a valid day in month m1 of year
  463.         // y1.
  464.         //
  465.        
  466.        
  467.         public override DateTime AddMonths(DateTime time, int months)
  468.         {
  469.             if (months < -120000 || months > 120000) {
  470.                 throw new ArgumentOutOfRangeException("months", String.Format(CultureInfo.CurrentCulture, Environment.GetResourceString("ArgumentOutOfRange_Range"), -120000, 120000));
  471.             }
  472.             // Get the date in UmAlQura calendar.
  473.             int y = GetDatePart(time, DatePartYear);
  474.             int m = GetDatePart(time, DatePartMonth);
  475.             int d = GetDatePart(time, DatePartDay);
  476.             int i = m - 1 + months;
  477.            
  478.             if (i >= 0) {
  479.                 m = i % 12 + 1;
  480.                 y = y + i / 12;
  481.             }
  482.             else {
  483.                 m = 12 + (i + 1) % 12;
  484.                 y = y + (i - 11) / 12;
  485.             }
  486.            
  487.             if (d > 29) {
  488.                 int days = GetDaysInMonth(y, m);
  489.                 if (d > days) {
  490.                     d = days;
  491.                 }
  492.             }
  493.             CheckYearRange(y, UmAlQuraEra);
  494.             DateTime dt = new DateTime(GetAbsoluteDateUmAlQura(y, m, d) * TicksPerDay + time.Ticks % TicksPerDay);
  495.             Calendar.CheckAddResult(dt.Ticks, MinSupportedDateTime, MaxSupportedDateTime);
  496.             return (dt);
  497.         }
  498.        
  499.         // Returns the DateTime resulting from adding the given number of
  500.         // years to the specified DateTime. The result is computed by incrementing
  501.         // (or decrementing) the year part of the specified DateTime by value
  502.         // years. If the month and day of the specified DateTime is 2/29, and if the
  503.         // resulting year is not a leap year, the month and day of the resulting
  504.         // DateTime becomes 2/28. Otherwise, the month, day, and time-of-day
  505.         // parts of the result are the same as those of the specified DateTime.
  506.         //
  507.        
  508.        
  509.         public override DateTime AddYears(DateTime time, int years)
  510.         {
  511.             return (AddMonths(time, years * 12));
  512.         }
  513.        
  514.         // Returns the day-of-month part of the specified DateTime. The returned
  515.         // value is an integer between 1 and 31.
  516.         //
  517.        
  518.        
  519.         public override int GetDayOfMonth(DateTime time)
  520.         {
  521.             return (GetDatePart(time, DatePartDay));
  522.         }
  523.        
  524.         // Returns the day-of-week part of the specified DateTime. The returned value
  525.         // is an integer between 0 and 6, where 0 indicates Sunday, 1 indicates
  526.         // Monday, 2 indicates Tuesday, 3 indicates Wednesday, 4 indicates
  527.         // Thursday, 5 indicates Friday, and 6 indicates Saturday.
  528.         //
  529.        
  530.        
  531.         public override DayOfWeek GetDayOfWeek(DateTime time)
  532.         {
  533.             return ((DayOfWeek)((int)(time.Ticks / TicksPerDay + 1) % 7));
  534.         }
  535.        
  536.         // Returns the day-of-year part of the specified DateTime. The returned value
  537.         // is an integer between 1 and 354 or 355.
  538.         //
  539.        
  540.        
  541.         public override int GetDayOfYear(DateTime time)
  542.         {
  543.             return (GetDatePart(time, DatePartDayOfYear));
  544.         }
  545.        
  546. /*
  547.         internal bool CouldBeLeapYear(int year)
  548.         {
  549.             return ((((year * 11) + 14) % 30) < 11);
  550.         }
  551.         */       
  552.        
  553.         // Returns the number of days in the month given by the year and
  554.         // month arguments.
  555.         //
  556.        
  557.        
  558.         public override int GetDaysInMonth(int year, int month, int era)
  559.         {
  560.             CheckYearMonthRange(year, month, era);
  561.            
  562.             if ((HijriYearInfo[year - MinCalendarYear].HijriMonthsLengthFlags & (1 << month - 1)) == 0)
  563.                 return 29;
  564.             else
  565.                 return 30;
  566.         }
  567.        
  568.         internal int RealGetDaysInYear(int year)
  569.         {
  570.             int days = 0;
  571.             int b;
  572.            
  573.             BCLDebug.Assert((year >= MinCalendarYear) && (year <= MaxCalendarYear), "Hijri year is out of range.");
  574.            
  575.             b = HijriYearInfo[year - MinCalendarYear].HijriMonthsLengthFlags;
  576.            
  577.             for (int m = 1; m <= 12; m++) {
  578.                 days = days + 29 + (b & 1);
  579.                 /* Add the months lengths before mh */b = b >> 1;
  580.             }
  581.             BCLDebug.Assert((days == 354) || (days == 355), "Hijri year has to be 354 or 355 days.");
  582.             return days;
  583.         }
  584.        
  585.         // Returns the number of days in the year given by the year argument for the current era.
  586.         //
  587.        
  588.        
  589.         public override int GetDaysInYear(int year, int era)
  590.         {
  591.             CheckYearRange(year, era);
  592.             return (RealGetDaysInYear(year));
  593.         }
  594.        
  595.         // Returns the era for the specified DateTime value.
  596.        
  597.        
  598.         public override int GetEra(DateTime time)
  599.         {
  600.             CheckTicksRange(time.Ticks);
  601.             return (UmAlQuraEra);
  602.         }
  603.        
  604.        
  605.        
  606.         public override int[] Eras {
  607.             get { return (new int[] {UmAlQuraEra}); }
  608.         }
  609.        
  610.         // Returns the month part of the specified DateTime. The returned value is an
  611.         // integer between 1 and 12.
  612.         //
  613.        
  614.        
  615.         public override int GetMonth(DateTime time)
  616.         {
  617.             return (GetDatePart(time, DatePartMonth));
  618.         }
  619.        
  620.         // Returns the number of months in the specified year and era.
  621.        
  622.        
  623.         public override int GetMonthsInYear(int year, int era)
  624.         {
  625.             CheckYearRange(year, era);
  626.             return (12);
  627.         }
  628.        
  629.         // Returns the year part of the specified DateTime. The returned value is an
  630.         // integer between MinCalendarYear and MaxCalendarYear.
  631.         //
  632.        
  633.        
  634.         public override int GetYear(DateTime time)
  635.         {
  636.             return (GetDatePart(time, DatePartYear));
  637.         }
  638.        
  639.         // Checks whether a given day in the specified era is a leap day. This method returns true if
  640.         // the date is a leap day, or false if not.
  641.         //
  642.        
  643.        
  644.         public override bool IsLeapDay(int year, int month, int day, int era)
  645.         {
  646.             if (day >= 1 && day <= 29) {
  647.                 CheckYearMonthRange(year, month, era);
  648.                 return (false);
  649.             }
  650.            
  651.             // The year/month/era value checking is done in GetDaysInMonth().
  652.             int daysInMonth = GetDaysInMonth(year, month, era);
  653.             if (day < 1 || day > daysInMonth) {
  654.                 throw new ArgumentOutOfRangeException("day", String.Format(CultureInfo.CurrentCulture, Environment.GetResourceString("ArgumentOutOfRange_Day"), daysInMonth, month));
  655.             }
  656.             return (false);
  657.         }
  658.        
  659.         // Returns the leap month in a calendar year of the specified era. This method returns 0
  660.         // if this calendar does not have leap month, or this year is not a leap year.
  661.         //
  662.        
  663.        
  664.         public override int GetLeapMonth(int year, int era)
  665.         {
  666.             CheckYearRange(year, era);
  667.             return (0);
  668.         }
  669.        
  670.         // Checks whether a given month in the specified era is a leap month. This method returns true if
  671.         // month is a leap month, or false if not.
  672.         //
  673.        
  674.        
  675.         public override bool IsLeapMonth(int year, int month, int era)
  676.         {
  677.             CheckYearMonthRange(year, month, era);
  678.             return (false);
  679.         }
  680.        
  681.         // Checks whether a given year in the specified era is a leap year. This method returns true if
  682.         // year is a leap year, or false if not.
  683.         //
  684.        
  685.        
  686.         public override bool IsLeapYear(int year, int era)
  687.         {
  688.             CheckYearRange(year, era);
  689.             if (RealGetDaysInYear(year) == 355)
  690.                 return true;
  691.             else
  692.                 return false;
  693.         }
  694.        
  695.         // Returns the date and time converted to a DateTime value. Throws an exception if the n-tuple is invalid.
  696.         //
  697.        
  698.        
  699.         public override DateTime ToDateTime(int year, int month, int day, int hour, int minute, int second, int millisecond, int era)
  700.         {
  701.             if (day >= 1 && day <= 29) {
  702.                 CheckYearMonthRange(year, month, era);
  703.                 goto DayInRang;
  704.             }
  705.            
  706.             // The year/month/era value checking is done in GetDaysInMonth().
  707.             int daysInMonth = GetDaysInMonth(year, month, era);
  708.            
  709.             if (day < 1 || day > daysInMonth) {
  710.                 BCLDebug.Log("year = " + year + ", month = " + month + ", day = " + day);
  711.                 throw new ArgumentOutOfRangeException("day", String.Format(CultureInfo.CurrentCulture, Environment.GetResourceString("ArgumentOutOfRange_Day"), daysInMonth, month));
  712.             }
  713.             DayInRang:
  714.             long lDate = GetAbsoluteDateUmAlQura(year, month, day);
  715.            
  716.             if (lDate >= 0) {
  717.                 return (new DateTime(lDate * GregorianCalendar.TicksPerDay + TimeToTicks(hour, minute, second, millisecond)));
  718.             }
  719.             else {
  720.                 throw new ArgumentOutOfRangeException(null, Environment.GetResourceString("ArgumentOutOfRange_BadYearMonthDay"));
  721.             }
  722.         }
  723.        
  724.         private const int DEFAULT_TWO_DIGIT_YEAR_MAX = 1451;
  725.        
  726.        
  727.        
  728.         public override int TwoDigitYearMax {
  729.             get {
  730.                 if (twoDigitYearMax == -1) {
  731.                     twoDigitYearMax = GetSystemTwoDigitYearSetting(ID, DEFAULT_TWO_DIGIT_YEAR_MAX);
  732.                 }
  733.                 return (twoDigitYearMax);
  734.             }
  735.            
  736.             set {
  737.                 VerifyWritable();
  738.                 if (value != 99 && (value < MinCalendarYear || value > MaxCalendarYear)) {
  739.                     throw new ArgumentOutOfRangeException("value", String.Format(CultureInfo.CurrentCulture, Environment.GetResourceString("ArgumentOutOfRange_Range"), MinCalendarYear, MaxCalendarYear));
  740.                 }
  741.                 // We allow year 99 to be set so that one can make ToFourDigitYearMax a no-op by setting TwoDigitYearMax to 99.
  742.                 twoDigitYearMax = value;
  743.             }
  744.         }
  745.        
  746.        
  747.        
  748.         public override int ToFourDigitYear(int year)
  749.         {
  750.             if (year < 100) {
  751.                 return (base.ToFourDigitYear(year));
  752.             }
  753.            
  754.             if ((year < MinCalendarYear) || (year > MaxCalendarYear)) {
  755.                 throw new ArgumentOutOfRangeException("year", String.Format(CultureInfo.CurrentCulture, Environment.GetResourceString("ArgumentOutOfRange_Range"), MinCalendarYear, MaxCalendarYear));
  756.             }
  757.             return (year);
  758.         }
  759.     }
  760. }

Developer Fusion