hijrah-date.js 64 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684168516861687168816891690169116921693169416951696169716981699170017011702170317041705170617071708170917101711171217131714171517161717171817191720172117221723172417251726172717281729173017311732173317341735173617371738173917401741174217431744174517461747174817491750175117521753175417551756175717581759176017611762176317641765176617671768176917701771177217731774177517761777177817791780178117821783178417851786178717881789179017911792179317941795179617971798179918001801180218031804180518061807180818091810181118121813181418151816181718181819182018211822182318241825182618271828182918301831183218331834183518361837183818391840184118421843184418451846184718481849185018511852185318541855185618571858185918601861186218631864186518661867186818691870187118721873
  1. (function (global, factory) {typeof exports === 'object' && typeof module !== 'undefined' ? module.exports = factory() :typeof define === 'function' && define.amd ? define(factory) :global.HijrahDate = factory()}(this, function(){ 'use strict';var slice = [].slice,
  2. splice = [].splice,
  3. push = [].push,
  4. getPrototypeOf = Object.getPrototypeOf;
  5. var lowercase = function(string) {return isString(string) ? string.toLowerCase() : string;};
  6. var uppercase = function(string) {return isString(string) ? string.toUpperCase() : string;};
  7. function toInt(value){
  8. return parseInt(value, 10);
  9. }
  10. function isUndefined(value) {return typeof value === 'undefined';}
  11. function isDefined(value) {return typeof value !== 'undefined';}
  12. function isString(value) {return typeof value === 'string';}
  13. function isNumber(value) {return typeof value === 'number';}
  14. function isDate(value) {
  15. return Object.prototype.toString.call(value) === '[object Date]';
  16. }
  17. function isValidDate(value) {
  18. return isDate(value) && !isNaN(value.getTime());
  19. }
  20. var isArray = Array.isArray;
  21. function isFunction(value) {return typeof value === 'function';}
  22. function concat(array1, array2, index) {
  23. return array1.concat(slice.call(array2, index));
  24. }
  25. function forEach(obj, iterator, context) {
  26. var key, length;
  27. if (obj) {
  28. if (isFunction(obj)) {
  29. for (key in obj) {
  30. if (key !== 'prototype' && key !== 'length' && key !== 'name' && obj.hasOwnProperty(key)) {
  31. iterator.call(context, obj[key], key, obj);
  32. }
  33. }
  34. } else if (isArray(obj) || isArrayLike(obj)) {
  35. var isPrimitive = typeof obj !== 'object';
  36. for (key = 0, length = obj.length; key < length; key++) {
  37. if (isPrimitive || key in obj) {
  38. iterator.call(context, obj[key], key, obj);
  39. }
  40. }
  41. } else if (obj.forEach && obj.forEach !== forEach) {
  42. obj.forEach(iterator, context, obj);
  43. } else if (isBlankObject(obj)) {
  44. // createMap() fast path --- Safe to avoid hasOwnProperty check because prototype chain is empty
  45. for (key in obj) {
  46. iterator.call(context, obj[key], key, obj);
  47. }
  48. } else if (typeof obj.hasOwnProperty === 'function') {
  49. // Slow path for objects inheriting Object.prototype, hasOwnProperty check needed
  50. for (key in obj) {
  51. if (obj.hasOwnProperty(key)) {
  52. iterator.call(context, obj[key], key, obj);
  53. }
  54. }
  55. } else {
  56. // Slow path for objects which do not have a method `hasOwnProperty`
  57. for (key in obj) {
  58. if (hasOwnProperty.call(obj, key)) {
  59. iterator.call(context, obj[key], key, obj);
  60. }
  61. }
  62. }
  63. }
  64. return obj;
  65. }
  66. function floorDiv(x, y){
  67. var r = toInt(x / y);
  68. if ((x ^ y) < 0 && (r * y != x)) {
  69. r--;
  70. }
  71. return r;
  72. }
  73. function floorMod(x, y){
  74. return x - floorDiv(x, y) * y;
  75. }
  76. function addExact(x, y) {
  77. var r = x + y;
  78. if (((x ^ r) & (y ^ r)) < 0) {
  79. throw "integer overflow";
  80. }
  81. return r;
  82. }
  83. function arrayBinarySearch(a, key) {
  84. var low = 0;
  85. var high = a.length - 1;
  86. while (low <= high) {
  87. var mid = (low + high) >>> 1;
  88. var midVal = a[mid];
  89. if (midVal < key){
  90. low = mid + 1;
  91. } else if (midVal > key){
  92. high = mid - 1;
  93. } else {
  94. return mid;
  95. }
  96. }
  97. return -(low + 1); // key not found.
  98. }
  99. var LocaleProvider = (function(){
  100. var locales = {};
  101. return {
  102. register: function(localId, localeData){
  103. locales[localId] = localeData;
  104. },
  105. getLocale: function(localId){
  106. return locales[localId];
  107. }
  108. };
  109. })();
  110. /*
  111. Original work Copyright (c) 2010-2016 Google, Inc. http://angularjs.org
  112. Modified work Copyright (c) 2016 Mouaffak A. Sarhan
  113. Permission is hereby granted, free of charge, to any person obtaining a copy
  114. of this software and associated documentation files (the "Software"), to deal
  115. in the Software without restriction, including without limitation the rights
  116. to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
  117. copies of the Software, and to permit persons to whom the Software is
  118. furnished to do so, subject to the following conditions:
  119. The above copyright notice and this permission notice shall be included in
  120. all copies or substantial portions of the Software.
  121. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  122. IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  123. FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
  124. AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
  125. LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
  126. OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
  127. THE SOFTWARE.
  128. */
  129. 'use strict';
  130. (function(){
  131. var PLURAL_CATEGORY = {ZERO: "zero", ONE: "one", TWO: "two", FEW: "few", MANY: "many", OTHER: "other"};
  132. var locale = {
  133. "DATETIME_FORMATS": {
  134. "AMPMS": [
  135. "\u0635",
  136. "\u0645"
  137. ],
  138. "DAY": [
  139. "\u0627\u0644\u0623\u062d\u062f",
  140. "\u0627\u0644\u0627\u062b\u0646\u064a\u0646",
  141. "\u0627\u0644\u062b\u0644\u0627\u062b\u0627\u0621",
  142. "\u0627\u0644\u0623\u0631\u0628\u0639\u0627\u0621",
  143. "\u0627\u0644\u062e\u0645\u064a\u0633",
  144. "\u0627\u0644\u062c\u0645\u0639\u0629",
  145. "\u0627\u0644\u0633\u0628\u062a"
  146. ],
  147. "ERANAMES": [
  148. "\u0647\u062C\u0631\u064A"
  149. ],
  150. "ERAS": [
  151. "\u0647\u0640"
  152. ],
  153. "FIRSTDAYOFWEEK": 5,
  154. "MONTH": [
  155. "\u0645\u062D\u0631\u0645",
  156. "\u0635\u0641\u0631",
  157. "\u0631\u0628\u064A\u0639 \u0627\u0644\u0623\u0648\u0644",
  158. "\u0631\u0628\u064A\u0639 \u0627\u0644\u062B\u0627\u0646\u064A",
  159. "\u062C\u0645\u0627\u062F\u0649 \u0627\u0644\u0623\u0648\u0644\u0649",
  160. "\u062C\u0645\u0627\u062F\u0649 \u0627\u0644\u0622\u062E\u0631\u0629",
  161. "\u0631\u062C\u0628",
  162. "\u0634\u0639\u0628\u0627\u0646",
  163. "\u0631\u0645\u0636\u0627\u0646",
  164. "\u0634\u0648\u0627\u0644",
  165. "\u0630\u0648 \u0627\u0644\u0642\u0639\u062F\u0629",
  166. "\u0630\u0648 \u0627\u0644\u062D\u062C\u0629"
  167. ],
  168. "SHORTDAY": [
  169. "\u0627\u0644\u0623\u062d\u062f",
  170. "\u0627\u0644\u0627\u062b\u0646\u064a\u0646",
  171. "\u0627\u0644\u062b\u0644\u0627\u062b\u0627\u0621",
  172. "\u0627\u0644\u0623\u0631\u0628\u0639\u0627\u0621",
  173. "\u0627\u0644\u062e\u0645\u064a\u0633",
  174. "\u0627\u0644\u062c\u0645\u0639\u0629",
  175. "\u0627\u0644\u0633\u0628\u062a"
  176. ],
  177. "SHORTMONTH": [
  178. "\u0645\u062D\u0631\u0645",
  179. "\u0635\u0641\u0631",
  180. "\u0631\u0628\u064A\u0639 1",
  181. "\u0631\u0628\u064A\u0639 2",
  182. "\u062C\u0645\u0627\u062F\u0649 1",
  183. "\u062C\u0645\u0627\u062F\u0649 2",
  184. "\u0631\u062C\u0628",
  185. "\u0634\u0639\u0628\u0627\u0646",
  186. "\u0631\u0645\u0636\u0627\u0646",
  187. "\u0634\u0648\u0627\u0644",
  188. "\u0630\u0648 \u0627\u0644\u0642\u0639\u062F\u0629",
  189. "\u0630\u0648 \u0627\u0644\u062D\u062C\u0629"
  190. ],
  191. "STANDALONEMONTH": [
  192. "\u0645\u062D\u0631\u0645",
  193. "\u0635\u0641\u0631",
  194. "\u0631\u0628\u064A\u0639 \u0627\u0644\u0623\u0648\u0644",
  195. "\u0631\u0628\u064A\u0639 \u0627\u0644\u062B\u0627\u0646\u064A",
  196. "\u062C\u0645\u0627\u062F\u0649 \u0627\u0644\u0623\u0648\u0644\u0649",
  197. "\u062C\u0645\u0627\u062F\u0649 \u0627\u0644\u0622\u062E\u0631\u0629",
  198. "\u0631\u062C\u0628",
  199. "\u0634\u0639\u0628\u0627\u0646",
  200. "\u0631\u0645\u0636\u0627\u0646",
  201. "\u0634\u0648\u0627\u0644",
  202. "\u0630\u0648 \u0627\u0644\u0642\u0639\u062F\u0629",
  203. "\u0630\u0648 \u0627\u0644\u062D\u062C\u0629"
  204. ],
  205. "WEEKENDRANGE": [
  206. 4,
  207. 5
  208. ],
  209. "fullDate": "EEEE\u060c d MMMM\u060c y",
  210. "longDate": "d MMMM\u060c y",
  211. "medium": "dd\u200f/MM\u200f/y h:mm:ss a",
  212. "mediumDate": "dd\u200f/MM\u200f/y",
  213. "mediumTime": "h:mm:ss a",
  214. "short": "d\u200f/M\u200f/y h:mm a",
  215. "shortDate": "d\u200f/M\u200f/y",
  216. "shortTime": "h:mm a"
  217. },
  218. "NUMBER_FORMATS": {
  219. "CURRENCY_SYM": "\u00a3",
  220. "DECIMAL_SEP": "\u066b",
  221. "GROUP_SEP": "\u066c",
  222. "PATTERNS": [
  223. {
  224. "gSize": 3,
  225. "lgSize": 3,
  226. "maxFrac": 3,
  227. "minFrac": 0,
  228. "minInt": 1,
  229. "negPre": "-",
  230. "negSuf": "",
  231. "posPre": "",
  232. "posSuf": ""
  233. },
  234. {
  235. "gSize": 3,
  236. "lgSize": 3,
  237. "maxFrac": 2,
  238. "minFrac": 2,
  239. "minInt": 1,
  240. "negPre": "-\u00a4\u00a0",
  241. "negSuf": "",
  242. "posPre": "\u00a4\u00a0",
  243. "posSuf": ""
  244. }
  245. ]
  246. },
  247. "id": "ar",
  248. "localeID": "ar",
  249. "pluralCat": function(n, opt_precision) { if (n == 0) { return PLURAL_CATEGORY.ZERO; } if (n == 1) { return PLURAL_CATEGORY.ONE; } if (n == 2) { return PLURAL_CATEGORY.TWO; } if (n % 100 >= 3 && n % 100 <= 10) { return PLURAL_CATEGORY.FEW; } if (n % 100 >= 11 && n % 100 <= 99) { return PLURAL_CATEGORY.MANY; } return PLURAL_CATEGORY.OTHER;}
  250. };
  251. LocaleProvider.register('ar', locale);
  252. })();
  253. /*
  254. Original work Copyright (c) 2010-2016 Google, Inc. http://angularjs.org
  255. Modified work Copyright (c) 2016 Mouaffak A. Sarhan
  256. Permission is hereby granted, free of charge, to any person obtaining a copy
  257. of this software and associated documentation files (the "Software"), to deal
  258. in the Software without restriction, including without limitation the rights
  259. to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
  260. copies of the Software, and to permit persons to whom the Software is
  261. furnished to do so, subject to the following conditions:
  262. The above copyright notice and this permission notice shall be included in
  263. all copies or substantial portions of the Software.
  264. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  265. IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  266. FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
  267. AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
  268. LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
  269. OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
  270. THE SOFTWARE.
  271. */
  272. 'use strict';
  273. (function(){
  274. var PLURAL_CATEGORY = {ZERO: "zero", ONE: "one", TWO: "two", FEW: "few", MANY: "many", OTHER: "other"};
  275. function getDecimals(n) {
  276. n = n + '';
  277. var i = n.indexOf('.');
  278. return (i == -1) ? 0 : n.length - i - 1;
  279. }
  280. function getVF(n, opt_precision) {
  281. var v = opt_precision;
  282. if (undefined === v) {
  283. v = Math.min(getDecimals(n), 3);
  284. }
  285. var base = Math.pow(10, v);
  286. var f = ((n * base) | 0) % base;
  287. return {v: v, f: f};
  288. }
  289. var locale = {
  290. "DATETIME_FORMATS": {
  291. "AMPMS": [
  292. "AM",
  293. "PM"
  294. ],
  295. "DAY": [
  296. "Sunday",
  297. "Monday",
  298. "Tuesday",
  299. "Wednesday",
  300. "Thursday",
  301. "Friday",
  302. "Saturday"
  303. ],
  304. "ERANAMES": [
  305. "Anno Hegirae"
  306. ],
  307. "ERAS": [
  308. "AH"
  309. ],
  310. "FIRSTDAYOFWEEK": 6,
  311. "MONTH": [
  312. "Muharram",
  313. "Safar",
  314. "Rabiʻ I",
  315. "Rabiʻ II",
  316. "Jumada I",
  317. "Jumada II",
  318. "Rajab",
  319. "Shaʻban",
  320. "Ramadan",
  321. "Shawwal",
  322. "Dhuʻl-Qiʻdah",
  323. "Dhuʻl-Hijjah"
  324. ],
  325. "SHORTDAY": [
  326. "Sun",
  327. "Mon",
  328. "Tue",
  329. "Wed",
  330. "Thu",
  331. "Fri",
  332. "Sat"
  333. ],
  334. "SHORTMONTH": [
  335. "Muh",
  336. "Saf",
  337. "Rab I",
  338. "Rab II",
  339. "Jum I",
  340. "Jum II",
  341. "Raj",
  342. "Sha",
  343. "Ram",
  344. "Shaw",
  345. "Dhuʻl-Q",
  346. "Dhuʻl-H"
  347. ],
  348. "STANDALONEMONTH": [
  349. "Muharram",
  350. "Safar",
  351. "Rabiʻ I",
  352. "Rabiʻ II",
  353. "Jumada I",
  354. "Jumada II",
  355. "Rajab",
  356. "Shaʻban",
  357. "Ramadan",
  358. "Shawwal",
  359. "Dhuʻl-Qiʻdah",
  360. "Dhuʻl-Hijjah"
  361. ],
  362. "WEEKENDRANGE": [
  363. 5,
  364. 6
  365. ],
  366. "fullDate": "EEEE, MMMM d, y",
  367. "longDate": "MMMM d, y",
  368. "medium": "MMM d, y h:mm:ss a",
  369. "mediumDate": "MMM d, y",
  370. "mediumTime": "h:mm:ss a",
  371. "short": "M/d/yy h:mm a",
  372. "shortDate": "M/d/yy",
  373. "shortTime": "h:mm a"
  374. },
  375. "NUMBER_FORMATS": {
  376. "CURRENCY_SYM": "$",
  377. "DECIMAL_SEP": ".",
  378. "GROUP_SEP": ",",
  379. "PATTERNS": [
  380. {
  381. "gSize": 3,
  382. "lgSize": 3,
  383. "maxFrac": 3,
  384. "minFrac": 0,
  385. "minInt": 1,
  386. "negPre": "-",
  387. "negSuf": "",
  388. "posPre": "",
  389. "posSuf": ""
  390. },
  391. {
  392. "gSize": 3,
  393. "lgSize": 3,
  394. "maxFrac": 2,
  395. "minFrac": 2,
  396. "minInt": 1,
  397. "negPre": "-\u00a4",
  398. "negSuf": "",
  399. "posPre": "\u00a4",
  400. "posSuf": ""
  401. }
  402. ]
  403. },
  404. "id": "en",
  405. "localeID": "en",
  406. "pluralCat": function(n, opt_precision) { var i = n | 0; var vf = getVF(n, opt_precision); if (i == 1 && vf.v == 0) { return PLURAL_CATEGORY.ONE; } return PLURAL_CATEGORY.OTHER;}
  407. };
  408. LocaleProvider.register('en', locale);
  409. })();
  410. /*
  411. Original work Copyright (c) 2010-2016 Google, Inc. http://angularjs.org
  412. Modified work Copyright (c) 2016 Mouaffak A. Sarhan
  413. Permission is hereby granted, free of charge, to any person obtaining a copy
  414. of this software and associated documentation files (the "Software"), to deal
  415. in the Software without restriction, including without limitation the rights
  416. to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
  417. copies of the Software, and to permit persons to whom the Software is
  418. furnished to do so, subject to the following conditions:
  419. The above copyright notice and this permission notice shall be included in
  420. all copies or substantial portions of the Software.
  421. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  422. IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  423. FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
  424. AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
  425. LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
  426. OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
  427. THE SOFTWARE.
  428. */
  429. var HijrahDateFormatter = (function(){
  430. 'use strict';
  431. var MAX_DIGITS = 22;
  432. var DECIMAL_SEP = '.';
  433. var ZERO_CHAR = '0';
  434. var ALL_COLONS = /:/g;
  435. function timezoneToOffset(timezone, fallback) {
  436. // IE/Edge do not "understand" colon (`:`) in timezone
  437. timezone = timezone.replace(ALL_COLONS, '');
  438. var requestedTimezoneOffset = Date.parse('Jan 01, 1970 00:00:00 ' + timezone) / 60000;
  439. return isNaN(requestedTimezoneOffset) ? fallback : requestedTimezoneOffset;
  440. }
  441. function addDateMinutes(date, minutes) {
  442. date = new Date(date.getTime());
  443. date.setMinutes(date.getMinutes() + minutes);
  444. return date;
  445. }
  446. function convertTimezoneToLocal(date, timezone, reverse) {
  447. reverse = reverse ? -1 : 1;
  448. var dateTimezoneOffset = date.getTimezoneOffset();
  449. var timezoneOffset = timezoneToOffset(timezone, dateTimezoneOffset);
  450. return addDateMinutes(date, reverse * (timezoneOffset - dateTimezoneOffset));
  451. }
  452. /**
  453. * Parse a number (as a string) into three components that can be used
  454. * for formatting the number.
  455. *
  456. * (Significant bits of this parse algorithm came from https://github.com/MikeMcl/big.js/)
  457. *
  458. * @param {string} numStr The number to parse
  459. * @return {object} An object describing this number, containing the following keys:
  460. * - d : an array of digits containing leading zeros as necessary
  461. * - i : the number of the digits in `d` that are to the left of the decimal point
  462. * - e : the exponent for numbers that would need more than `MAX_DIGITS` digits in `d`
  463. *
  464. */
  465. function parse(numStr) {
  466. var exponent = 0, digits, numberOfIntegerDigits;
  467. var i, j, zeros;
  468. // Decimal point?
  469. if ((numberOfIntegerDigits = numStr.indexOf(DECIMAL_SEP)) > -1) {
  470. numStr = numStr.replace(DECIMAL_SEP, '');
  471. }
  472. // Exponential form?
  473. if ((i = numStr.search(/e/i)) > 0) {
  474. // Work out the exponent.
  475. if (numberOfIntegerDigits < 0) numberOfIntegerDigits = i;
  476. numberOfIntegerDigits += +numStr.slice(i + 1);
  477. numStr = numStr.substring(0, i);
  478. } else if (numberOfIntegerDigits < 0) {
  479. // There was no decimal point or exponent so it is an integer.
  480. numberOfIntegerDigits = numStr.length;
  481. }
  482. // Count the number of leading zeros.
  483. for (i = 0; numStr.charAt(i) === ZERO_CHAR; i++) { /* empty */ }
  484. if (i === (zeros = numStr.length)) {
  485. // The digits are all zero.
  486. digits = [0];
  487. numberOfIntegerDigits = 1;
  488. } else {
  489. // Count the number of trailing zeros
  490. zeros--;
  491. while (numStr.charAt(zeros) === ZERO_CHAR) zeros--;
  492. // Trailing zeros are insignificant so ignore them
  493. numberOfIntegerDigits -= i;
  494. digits = [];
  495. // Convert string to array of digits without leading/trailing zeros.
  496. for (j = 0; i <= zeros; i++, j++) {
  497. digits[j] = +numStr.charAt(i);
  498. }
  499. }
  500. // If the number overflows the maximum allowed digits then use an exponent.
  501. if (numberOfIntegerDigits > MAX_DIGITS) {
  502. digits = digits.splice(0, MAX_DIGITS - 1);
  503. exponent = numberOfIntegerDigits - 1;
  504. numberOfIntegerDigits = 1;
  505. }
  506. return { d: digits, e: exponent, i: numberOfIntegerDigits };
  507. }
  508. /**
  509. * Round the parsed number to the specified number of decimal places
  510. * This function changed the parsedNumber in-place
  511. */
  512. function roundNumber(parsedNumber, fractionSize, minFrac, maxFrac) {
  513. var digits = parsedNumber.d;
  514. var fractionLen = digits.length - parsedNumber.i;
  515. // determine fractionSize if it is not specified; `+fractionSize` converts it to a number
  516. fractionSize = (isUndefined(fractionSize)) ? Math.min(Math.max(minFrac, fractionLen), maxFrac) : +fractionSize;
  517. // The index of the digit to where rounding is to occur
  518. var roundAt = fractionSize + parsedNumber.i;
  519. var digit = digits[roundAt];
  520. if (roundAt > 0) {
  521. // Drop fractional digits beyond `roundAt`
  522. digits.splice(Math.max(parsedNumber.i, roundAt));
  523. // Set non-fractional digits beyond `roundAt` to 0
  524. for (var j = roundAt; j < digits.length; j++) {
  525. digits[j] = 0;
  526. }
  527. } else {
  528. // We rounded to zero so reset the parsedNumber
  529. fractionLen = Math.max(0, fractionLen);
  530. parsedNumber.i = 1;
  531. digits.length = Math.max(1, roundAt = fractionSize + 1);
  532. digits[0] = 0;
  533. for (var i = 1; i < roundAt; i++) digits[i] = 0;
  534. }
  535. if (digit >= 5) {
  536. if (roundAt - 1 < 0) {
  537. for (var k = 0; k > roundAt; k--) {
  538. digits.unshift(0);
  539. parsedNumber.i++;
  540. }
  541. digits.unshift(1);
  542. parsedNumber.i++;
  543. } else {
  544. digits[roundAt - 1]++;
  545. }
  546. }
  547. // Pad out with zeros to get the required fraction length
  548. for (; fractionLen < Math.max(0, fractionSize); fractionLen++) digits.push(0);
  549. // Do any carrying, e.g. a digit was rounded up to 10
  550. var carry = digits.reduceRight(function(carry, d, i, digits) {
  551. d = d + carry;
  552. digits[i] = d % 10;
  553. return Math.floor(d / 10);
  554. }, 0);
  555. if (carry) {
  556. digits.unshift(carry);
  557. parsedNumber.i++;
  558. }
  559. }
  560. /**
  561. * Format a number into a string
  562. * @param {number} number The number to format
  563. * @param {{
  564. * minFrac, // the minimum number of digits required in the fraction part of the number
  565. * maxFrac, // the maximum number of digits required in the fraction part of the number
  566. * gSize, // number of digits in each group of separated digits
  567. * lgSize, // number of digits in the last group of digits before the decimal separator
  568. * negPre, // the string to go in front of a negative number (e.g. `-` or `(`))
  569. * posPre, // the string to go in front of a positive number
  570. * negSuf, // the string to go after a negative number (e.g. `)`)
  571. * posSuf // the string to go after a positive number
  572. * }} pattern
  573. * @param {string} groupSep The string to separate groups of number (e.g. `,`)
  574. * @param {string} decimalSep The string to act as the decimal separator (e.g. `.`)
  575. * @param {[type]} fractionSize The size of the fractional part of the number
  576. * @return {string} The number formatted as a string
  577. */
  578. function formatNumber(number, pattern, groupSep, decimalSep, fractionSize) {
  579. if (!(isString(number) || isNumber(number)) || isNaN(number)) return '';
  580. var isInfinity = !isFinite(number);
  581. var isZero = false;
  582. var numStr = Math.abs(number) + '',
  583. formattedText = '',
  584. parsedNumber;
  585. if (isInfinity) {
  586. formattedText = '\u221e';
  587. } else {
  588. parsedNumber = parse(numStr);
  589. roundNumber(parsedNumber, fractionSize, pattern.minFrac, pattern.maxFrac);
  590. var digits = parsedNumber.d;
  591. var integerLen = parsedNumber.i;
  592. var exponent = parsedNumber.e;
  593. var decimals = [];
  594. isZero = digits.reduce(function(isZero, d) { return isZero && !d; }, true);
  595. // pad zeros for small numbers
  596. while (integerLen < 0) {
  597. digits.unshift(0);
  598. integerLen++;
  599. }
  600. // extract decimals digits
  601. if (integerLen > 0) {
  602. decimals = digits.splice(integerLen, digits.length);
  603. } else {
  604. decimals = digits;
  605. digits = [0];
  606. }
  607. // format the integer digits with grouping separators
  608. var groups = [];
  609. if (digits.length >= pattern.lgSize) {
  610. groups.unshift(digits.splice(-pattern.lgSize, digits.length).join(''));
  611. }
  612. while (digits.length > pattern.gSize) {
  613. groups.unshift(digits.splice(-pattern.gSize, digits.length).join(''));
  614. }
  615. if (digits.length) {
  616. groups.unshift(digits.join(''));
  617. }
  618. formattedText = groups.join(groupSep);
  619. // append the decimal digits
  620. if (decimals.length) {
  621. formattedText += decimalSep + decimals.join('');
  622. }
  623. if (exponent) {
  624. formattedText += 'e+' + exponent;
  625. }
  626. }
  627. if (number < 0 && !isZero) {
  628. return pattern.negPre + formattedText + pattern.negSuf;
  629. } else {
  630. return pattern.posPre + formattedText + pattern.posSuf;
  631. }
  632. }
  633. function padNumber(num, digits, trim, negWrap) {
  634. var neg = '';
  635. if (num < 0 || (negWrap && num <= 0)) {
  636. if (negWrap) {
  637. num = -num + 1;
  638. } else {
  639. num = -num;
  640. neg = '-';
  641. }
  642. }
  643. num = '' + num;
  644. while (num.length < digits) num = ZERO_CHAR + num;
  645. if (trim) {
  646. num = num.substr(num.length - digits);
  647. }
  648. return neg + num;
  649. }
  650. function dateGetter(name, size, offset, trim, negWrap) {
  651. offset = offset || 0;
  652. return function(date) {
  653. var value = date['get' + name]();
  654. if (offset > 0 || value > -offset) {
  655. value += offset;
  656. }
  657. if (value === 0 && offset === -12) value = 12;
  658. return padNumber(value, size, trim, negWrap);
  659. };
  660. }
  661. function dateStrGetter(name, shortForm, standAlone) {
  662. return function(date, formats) {
  663. var value = date['get' + name]();
  664. var propPrefix = (standAlone ? 'STANDALONE' : '') + (shortForm ? 'SHORT' : '');
  665. var get = uppercase(propPrefix + name);
  666. return formats[get][value];
  667. };
  668. }
  669. function timeZoneGetter(date, formats, offset) {
  670. var zone = -1 * offset;
  671. var paddedZone = (zone >= 0) ? '+' : '';
  672. paddedZone += padNumber(Math[zone > 0 ? 'floor' : 'ceil'](zone / 60), 2) +
  673. padNumber(Math.abs(zone % 60), 2);
  674. return paddedZone;
  675. }
  676. function getFirstThursdayOfYear(year) {
  677. // 0 = index of January
  678. var dayOfWeekOnFirst = (new Date(year, 0, 1)).getDay();
  679. // 4 = index of Thursday (+1 to account for 1st = 5)
  680. // 11 = index of *next* Thursday (+1 account for 1st = 12)
  681. return new Date(year, 0, ((dayOfWeekOnFirst <= 4) ? 5 : 12) - dayOfWeekOnFirst);
  682. }
  683. function getThursdayThisWeek(datetime) {
  684. return new Date(datetime.getFullYear(), datetime.getMonth(),
  685. // 4 = index of Thursday
  686. datetime.getDate() + (4 - datetime.getDay()));
  687. }
  688. function weekGetter(size) {
  689. return function(hijrahDate) {
  690. var result = toInt(((hijrahDate.getDayOfYear() - 1) / 7)) + 1;
  691. /*
  692. var firstThurs = getFirstThursdayOfYear(date.getFullYear()),
  693. thisThurs = getThursdayThisWeek(date);
  694. var diff = +thisThurs - +firstThurs,
  695. result = 1 + Math.round(diff / 6.048e8); // 6.048e8 ms per week
  696. */
  697. return padNumber(result, size);
  698. };
  699. }
  700. function ampmGetter(date, formats) {
  701. return date.getHours() < 12 ? formats.AMPMS[0] : formats.AMPMS[1];
  702. }
  703. function eraGetter(date, formats) {
  704. return formats.ERAS[0];
  705. }
  706. function longEraGetter(date, formats) {
  707. return formats.ERANAMES[0];
  708. }
  709. var DATE_FORMATS = {
  710. yyyy: dateGetter('FullYear', 4, 0, false, true),
  711. yy: dateGetter('FullYear', 2, 0, true, true),
  712. y: dateGetter('FullYear', 1, 0, false, true),
  713. MMMM: dateStrGetter('Month'),
  714. MMM: dateStrGetter('Month', true),
  715. MM: dateGetter('Month', 2, 1),
  716. M: dateGetter('Month', 1, 1),
  717. LLLL: dateStrGetter('Month', false, true),
  718. dd: dateGetter('Date', 2),
  719. d: dateGetter('Date', 1),
  720. HH: dateGetter('Hours', 2),
  721. H: dateGetter('Hours', 1),
  722. hh: dateGetter('Hours', 2, -12),
  723. h: dateGetter('Hours', 1, -12),
  724. mm: dateGetter('Minutes', 2),
  725. m: dateGetter('Minutes', 1),
  726. ss: dateGetter('Seconds', 2),
  727. s: dateGetter('Seconds', 1),
  728. // while ISO 8601 requires fractions to be prefixed with `.` or `,`
  729. // we can be just safely rely on using `sss` since we currently don't support single or two digit fractions
  730. sss: dateGetter('Milliseconds', 3),
  731. EEEE: dateStrGetter('Day'),
  732. EEE: dateStrGetter('Day', true),
  733. a: ampmGetter,
  734. Z: timeZoneGetter,
  735. ww: weekGetter(2),
  736. w: weekGetter(1),
  737. G: eraGetter,
  738. GG: eraGetter,
  739. GGG: eraGetter,
  740. GGGG: longEraGetter
  741. };
  742. var DATE_FORMATS_SPLIT = /((?:[^yMLdHhmsaZEwG']+)|(?:'(?:[^']|'')*')|(?:E+|y+|M+|L+|d+|H+|h+|m+|s+|a|Z|G+|w+))(.*)/,
  743. NUMBER_STRING = /^\-?\d+$/;
  744. /**
  745. * @ngdoc filter
  746. * @name date
  747. * @kind function
  748. *
  749. * @description
  750. * Formats `date` to a string based on the requested `format`.
  751. *
  752. * `format` string can be composed of the following elements:
  753. *
  754. * * `'yyyy'`: 4 digit representation of year (e.g. AD 1 => 0001, AD 2010 => 2010)
  755. * * `'yy'`: 2 digit representation of year, padded (00-99). (e.g. AD 2001 => 01, AD 2010 => 10)
  756. * * `'y'`: 1 digit representation of year, e.g. (AD 1 => 1, AD 199 => 199)
  757. * * `'MMMM'`: Month in year (January-December)
  758. * * `'MMM'`: Month in year (Jan-Dec)
  759. * * `'MM'`: Month in year, padded (01-12)
  760. * * `'M'`: Month in year (1-12)
  761. * * `'LLLL'`: Stand-alone month in year (January-December)
  762. * * `'dd'`: Day in month, padded (01-31)
  763. * * `'d'`: Day in month (1-31)
  764. * * `'EEEE'`: Day in Week,(Sunday-Saturday)
  765. * * `'EEE'`: Day in Week, (Sun-Sat)
  766. * * `'HH'`: Hour in day, padded (00-23)
  767. * * `'H'`: Hour in day (0-23)
  768. * * `'hh'`: Hour in AM/PM, padded (01-12)
  769. * * `'h'`: Hour in AM/PM, (1-12)
  770. * * `'mm'`: Minute in hour, padded (00-59)
  771. * * `'m'`: Minute in hour (0-59)
  772. * * `'ss'`: Second in minute, padded (00-59)
  773. * * `'s'`: Second in minute (0-59)
  774. * * `'sss'`: Millisecond in second, padded (000-999)
  775. * * `'a'`: AM/PM marker
  776. * * `'Z'`: 4 digit (+sign) representation of the timezone offset (-1200-+1200)
  777. * * `'ww'`: Week of year, padded (00-53). Week 01 is the week with the first Thursday of the year
  778. * * `'w'`: Week of year (0-53). Week 1 is the week with the first Thursday of the year
  779. * * `'G'`, `'GG'`, `'GGG'`: The abbreviated form of the era string (e.g. 'AD')
  780. * * `'GGGG'`: The long form of the era string (e.g. 'Anno Domini')
  781. *
  782. * `format` string can also be one of the following predefined
  783. * {@link guide/i18n localizable formats}:
  784. *
  785. * * `'medium'`: equivalent to `'MMM d, y h:mm:ss a'` for en_US locale
  786. * (e.g. Sep 3, 2010 12:05:08 PM)
  787. * * `'short'`: equivalent to `'M/d/yy h:mm a'` for en_US locale (e.g. 9/3/10 12:05 PM)
  788. * * `'fullDate'`: equivalent to `'EEEE, MMMM d, y'` for en_US locale
  789. * (e.g. Friday, September 3, 2010)
  790. * * `'longDate'`: equivalent to `'MMMM d, y'` for en_US locale (e.g. September 3, 2010)
  791. * * `'mediumDate'`: equivalent to `'MMM d, y'` for en_US locale (e.g. Sep 3, 2010)
  792. * * `'shortDate'`: equivalent to `'M/d/yy'` for en_US locale (e.g. 9/3/10)
  793. * * `'mediumTime'`: equivalent to `'h:mm:ss a'` for en_US locale (e.g. 12:05:08 PM)
  794. * * `'shortTime'`: equivalent to `'h:mm a'` for en_US locale (e.g. 12:05 PM)
  795. *
  796. * `format` string can contain literal values. These need to be escaped by surrounding with single quotes (e.g.
  797. * `"h 'in the morning'"`). In order to output a single quote, escape it - i.e., two single quotes in a sequence
  798. * (e.g. `"h 'o''clock'"`).
  799. *
  800. * @param {(Date|number|string)} date Date to format either as Date object, milliseconds (string or
  801. * number) or various ISO 8601 datetime string formats (e.g. yyyy-MM-ddTHH:mm:ss.sssZ and its
  802. * shorter versions like yyyy-MM-ddTHH:mmZ, yyyy-MM-dd or yyyyMMddTHHmmssZ). If no timezone is
  803. * specified in the string input, the time is considered to be in the local timezone.
  804. * @param {string=} format Formatting rules (see Description). If not specified,
  805. * `mediumDate` is used.
  806. * @param {string=} timezone Timezone to be used for formatting. It understands UTC/GMT and the
  807. * continental US time zone abbreviations, but for general use, use a time zone offset, for
  808. * example, `'+0430'` (4 hours, 30 minutes east of the Greenwich meridian)
  809. * If not specified, the timezone of the browser will be used.
  810. * @returns {string} Formatted string or the input if input is not recognized as date/millis.
  811. *
  812. * @example
  813. <example name="filter-date">
  814. <file name="index.html">
  815. <span ng-non-bindable>{{1288323623006 | date:'medium'}}</span>:
  816. <span>{{1288323623006 | date:'medium'}}</span><br>
  817. <span ng-non-bindable>{{1288323623006 | date:'yyyy-MM-dd HH:mm:ss Z'}}</span>:
  818. <span>{{1288323623006 | date:'yyyy-MM-dd HH:mm:ss Z'}}</span><br>
  819. <span ng-non-bindable>{{1288323623006 | date:'MM/dd/yyyy @ h:mma'}}</span>:
  820. <span>{{'1288323623006' | date:'MM/dd/yyyy @ h:mma'}}</span><br>
  821. <span ng-non-bindable>{{1288323623006 | date:"MM/dd/yyyy 'at' h:mma"}}</span>:
  822. <span>{{'1288323623006' | date:"MM/dd/yyyy 'at' h:mma"}}</span><br>
  823. </file>
  824. <file name="protractor.js" type="protractor">
  825. it('should format date', function() {
  826. expect(element(by.binding("1288323623006 | date:'medium'")).getText()).
  827. toMatch(/Oct 2\d, 2010 \d{1,2}:\d{2}:\d{2} (AM|PM)/);
  828. expect(element(by.binding("1288323623006 | date:'yyyy-MM-dd HH:mm:ss Z'")).getText()).
  829. toMatch(/2010\-10\-2\d \d{2}:\d{2}:\d{2} (\-|\+)?\d{4}/);
  830. expect(element(by.binding("'1288323623006' | date:'MM/dd/yyyy @ h:mma'")).getText()).
  831. toMatch(/10\/2\d\/2010 @ \d{1,2}:\d{2}(AM|PM)/);
  832. expect(element(by.binding("'1288323623006' | date:\"MM/dd/yyyy 'at' h:mma\"")).getText()).
  833. toMatch(/10\/2\d\/2010 at \d{1,2}:\d{2}(AM|PM)/);
  834. });
  835. </file>
  836. </example>
  837. */
  838. //dateFilter.$inject = ['$locale'];
  839. function dateFilter($locale) {
  840. var R_ISO8601_STR = /^(\d{4})-?(\d\d)-?(\d\d)(?:T(\d\d)(?::?(\d\d)(?::?(\d\d)(?:\.(\d+))?)?)?(Z|([+-])(\d\d):?(\d\d))?)?$/;
  841. // 1 2 3 4 5 6 7 8 9 10 11
  842. function jsonStringToDate(string) {
  843. var match;
  844. if ((match = string.match(R_ISO8601_STR))) {
  845. var date = new HijrahDate(new Date(0)),
  846. tzHour = 0,
  847. tzMin = 0,
  848. dateSetter = match[8] ? date.setUTCFullYear : date.setFullYear,
  849. timeSetter = match[8] ? date.setUTCHours : date.setHours;
  850. if (match[9]) {
  851. tzHour = toInt(match[9] + match[10]);
  852. tzMin = toInt(match[9] + match[11]);
  853. }
  854. dateSetter.call(date, toInt(match[1]), toInt(match[2]) - 1, toInt(match[3]));
  855. var h = toInt(match[4] || 0) - tzHour;
  856. var m = toInt(match[5] || 0) - tzMin;
  857. var s = toInt(match[6] || 0);
  858. var ms = Math.round(parseFloat('0.' + (match[7] || 0)) * 1000);
  859. timeSetter.call(date, h, m, s, ms);
  860. return date;
  861. }
  862. return string;
  863. }
  864. return function(hijrahDate, format, timezone) {
  865. var text = '',
  866. parts = [],
  867. fn, match;
  868. format = format || 'mediumDate';
  869. format = $locale.DATETIME_FORMATS[format] || format;
  870. if (isString(hijrahDate)) {
  871. hijrahDate = NUMBER_STRING.test(hijrahDate) ? toInt(hijrahDate) : jsonStringToDate(hijrahDate);
  872. }
  873. if (isNumber(hijrahDate)) {
  874. hijrahDate = new HijrahDate(hijrahDate);
  875. }
  876. if (!HijrahDate.isHijrahDate(hijrahDate) || !isFinite(hijrahDate.getTime())) {
  877. return hijrahDate;
  878. }
  879. while (format) {
  880. match = DATE_FORMATS_SPLIT.exec(format);
  881. if (match) {
  882. parts = concat(parts, match, 1);
  883. format = parts.pop();
  884. } else {
  885. parts.push(format);
  886. format = null;
  887. }
  888. }
  889. var date = hijrahDate.toGregorian();
  890. var dateTimezoneOffset = date.getTimezoneOffset();
  891. if (timezone) {
  892. dateTimezoneOffset = timezoneToOffset(timezone, dateTimezoneOffset);
  893. date = convertTimezoneToLocal(date, timezone, true);
  894. hijrahDate = new HijrahDate(date);
  895. }
  896. forEach(parts, function(value) {
  897. fn = DATE_FORMATS[value];
  898. text += fn ? fn(hijrahDate, $locale.DATETIME_FORMATS, dateTimezoneOffset)
  899. : value === '\'\'' ? '\'' : value.replace(/(^'|'$)/g, '').replace(/''/g, '\'');
  900. });
  901. return text;
  902. };
  903. }
  904. return {
  905. formatter: function(localeId){
  906. return dateFilter(LocaleProvider.getLocale(localeId));
  907. }
  908. };
  909. })();
  910. 'use strict';
  911. var HijrahDate = (function(){
  912. HijrahDate.isValid = isValid;
  913. HijrahDate.isHijrahDate = isHijrahDate;
  914. HijrahDate.prototype.getTime = getTime;
  915. HijrahDate.prototype.setFullYear = setFullYear;
  916. HijrahDate.prototype.getFullYear = getFullYear;
  917. HijrahDate.prototype.setMonth = setMonth;
  918. HijrahDate.prototype.getMonth = getMonth;
  919. HijrahDate.prototype.setDate = setDate;
  920. HijrahDate.prototype.getDate = getDate;
  921. HijrahDate.prototype.setHours = setHours;
  922. HijrahDate.prototype.getHours = getHours;
  923. HijrahDate.prototype.setMinutes = setMinutes;
  924. HijrahDate.prototype.getMinutes = getMinutes;
  925. HijrahDate.prototype.setSeconds = setSeconds;
  926. HijrahDate.prototype.getSeconds = getSeconds;
  927. HijrahDate.prototype.getMilliseconds = getMilliseconds;
  928. HijrahDate.prototype.getDayOfYear = getDayOfYear;
  929. HijrahDate.prototype.getWeekOfYear = getWeekOfYear;
  930. HijrahDate.prototype.getDay = getDay;
  931. HijrahDate.prototype.getTimezoneOffset = getTimezoneOffset;
  932. HijrahDate.prototype.getMonthLength = getMonthLength;
  933. HijrahDate.prototype.getYearLength = getYearLength;
  934. HijrahDate.prototype.isLeapYear = isLeapYear;
  935. HijrahDate.prototype.toEpochDay = toEpochDay;
  936. HijrahDate.prototype.setUTCFullYear = setUTCFullYear;
  937. HijrahDate.prototype.getUTCFullYear = getUTCFullYear;
  938. HijrahDate.prototype.setUTCHours = setUTCHours;
  939. HijrahDate.prototype.getUTCHours = getUTCHours;
  940. HijrahDate.prototype.plusYears = plusYears;
  941. HijrahDate.prototype.plusMonths = plusMonths;
  942. HijrahDate.prototype.plusWeeks = plusWeeks;
  943. HijrahDate.prototype.plusDays = plusDays;
  944. HijrahDate.prototype.minusYears = minusYears;
  945. HijrahDate.prototype.minusMonths = minusMonths;
  946. HijrahDate.prototype.minusWeeks = minusWeeks;
  947. HijrahDate.prototype.minusDays = minusDays;
  948. HijrahDate.prototype.toGregorian = toGregorian;
  949. HijrahDate.prototype.toString = toString;
  950. HijrahDate.prototype.format = format;
  951. var DAYS_PER_CYCLE = 146097;
  952. var DAYS_0000_TO_1970 = (DAYS_PER_CYCLE * 5) - (30 * 365 + 7);
  953. var hijrahEpochMonthStartDays,
  954. minEpochDay,
  955. maxEpochDay,
  956. hijrahStartEpochMonth,
  957. minMonthLength,
  958. maxMonthLength,
  959. minYearLength,
  960. maxYearLength;
  961. init();
  962. function HijrahDate(year, monthOfYear, dayOfMonth, hours, minutes, seconds, milliseconds){
  963. this._year = Number.NaN;
  964. this._monthOfYear = Number.NaN;
  965. this._dayOfMonth = Number.NaN;
  966. var y, m, d, g;
  967. if(arguments.length === 0){
  968. g = new Date();
  969. var dateInfo = getHijrahDateInfo(epochDayFromGregorain(g));
  970. y = dateInfo[0];
  971. m = dateInfo[1];
  972. d = dateInfo[2];
  973. } else if(arguments.length === 1){
  974. if(HijrahDate.isHijrahDate(arguments[0])){
  975. var hd = arguments[0];
  976. g = hd.toGregorian();
  977. y = hd._year;
  978. m = hd._monthOfYear;
  979. d = hd._dayOfMonth;
  980. } else {
  981. g = new Date(arguments[0]);
  982. var dateInfo = getHijrahDateInfo(epochDayFromGregorain(g));
  983. y = dateInfo[0];
  984. m = dateInfo[1];
  985. d = dateInfo[2];
  986. }
  987. } else {
  988. // Computing the Gregorian day and checks the valid ranges
  989. g = gregorianFromEpochDay(getEpochDay(year, monthOfYear + 1, dayOfMonth || 1));
  990. g.setHours(hours || 0, minutes || 0, seconds || 0, milliseconds || 0);
  991. var dateInfo = getHijrahDateInfo(epochDayFromGregorain(g));
  992. y = dateInfo[0];
  993. m = dateInfo[1];
  994. d = dateInfo[2];
  995. }
  996. this._year = y;
  997. this._monthOfYear = m;
  998. this._dayOfMonth = d;
  999. this._gregorianDate = g;
  1000. }
  1001. function setFromHijrahDate(dest, src){
  1002. dest._year = src._year;
  1003. dest._monthOfYear = src._monthOfYear;
  1004. dest._dayOfMonth = src._dayOfMonth;
  1005. dest._gregorianDate.setFullYear(src._gregorianDate.getFullYear(), src._gregorianDate.getMonth(), src._gregorianDate.getDate());
  1006. }
  1007. function ofEpochDay(epochDay){
  1008. var dateInfo = getHijrahDateInfo(toInt(epochDay));
  1009. return new HijrahDate(dateInfo[0], dateInfo[1] - 1, dateInfo[2]);
  1010. }
  1011. function isValid(year, monthOfYear, dayOfMonth){
  1012. /* this will throws an exception if values not valid */
  1013. getEpochDay(year, monthOfYear + 1, dayOfMonth);
  1014. return true;
  1015. }
  1016. function isHijrahDate(value) {
  1017. return ((Object.prototype.toString.call(value) === '[object Object]') && (value instanceof HijrahDate));
  1018. }
  1019. function getTime(){
  1020. return this._gregorianDate.getTime();
  1021. }
  1022. function setFullYear(year, month, day){
  1023. var m = isNumber(month) ? (month + 1) : this._monthOfYear;
  1024. var d = day || this._dayOfMonth;
  1025. var hijrahDate = resolvePreviousValid(year, m, d);
  1026. setFromHijrahDate(this, hijrahDate);
  1027. }
  1028. function getFullYear(){
  1029. return this._year;
  1030. }
  1031. function setUTCFullYear(year, month, day){
  1032. return this.setFullYear(year, month, day);
  1033. }
  1034. function getUTCFullYear(){
  1035. return this.getFullYear();
  1036. }
  1037. function setMonth(month, day){
  1038. var hijrahDate = resolvePreviousValid(this.getFullYear(), month + 1, day || this._dayOfMonth);
  1039. setFromHijrahDate(this, hijrahDate);
  1040. }
  1041. function getMonth(){
  1042. return this._monthOfYear - 1;
  1043. }
  1044. function setDate(dayOfMonth){
  1045. if(dayOfMonth === this.getDate()){
  1046. return;
  1047. }
  1048. if(dayOfMonth === 0){
  1049. return this.minusDays(this.getDate());
  1050. } else if(dayOfMonth < 0){
  1051. return this.minusDays(this.getDate() + Math.abs(dayOfMonth));
  1052. } else {
  1053. return this.plusDays(dayOfMonth - this.getMonthLength());
  1054. }
  1055. }
  1056. function getDate(){
  1057. return this._dayOfMonth;
  1058. }
  1059. function setHours(hours, minutes, seconds, milliseconds){
  1060. var res = this._gregorianDate.setHours(hours, minutes, seconds, milliseconds);
  1061. var hijrahDate = new HijrahDate(res);
  1062. setFromHijrahDate(this, hijrahDate);
  1063. return res;
  1064. }
  1065. function getHours(){
  1066. return this._gregorianDate.getHours();
  1067. }
  1068. function setUTCHours(hours, minutes, seconds, milliseconds){
  1069. return this._gregorianDate.setUTCHours(hours, minutes, seconds, milliseconds);
  1070. }
  1071. function getUTCHours(){
  1072. return this._gregorianDate.getUTCHours();
  1073. }
  1074. function setMinutes(minutes, seconds, milliseconds){
  1075. return this._gregorianDate.setMinutes(minutes, seconds, milliseconds);
  1076. }
  1077. function getMinutes(){
  1078. return this._gregorianDate.getMinutes();
  1079. }
  1080. function setSeconds(seconds, milliseconds){
  1081. return this._gregorianDate.setSeconds(seconds, milliseconds);
  1082. }
  1083. function getSeconds(){
  1084. return this._gregorianDate.getSeconds();
  1085. }
  1086. function getMilliseconds(){
  1087. return this._gregorianDate.getMilliseconds();
  1088. }
  1089. function getMonthLength() {
  1090. return _getMonthLength(this._year, this._monthOfYear);
  1091. }
  1092. function getYearLength() {
  1093. return _getYearLength(this._year);
  1094. }
  1095. function toEpochDay() {
  1096. return getEpochDay(this._year, this._monthOfYear, this._dayOfMonth);
  1097. }
  1098. function getDayOfYear() {
  1099. return _getDayOfYear(this._year, this._monthOfYear) + this._dayOfMonth;
  1100. }
  1101. function getWeekOfYear() {
  1102. return toInt(((this.getDayOfYear() - 1) / 7)) + 1;
  1103. }
  1104. function getDay() {
  1105. return this._gregorianDate.getDay();
  1106. }
  1107. function getTimezoneOffset() {
  1108. return this._gregorianDate.getTimezoneOffset();
  1109. }
  1110. function isLeapYear() {
  1111. var year = this._year;
  1112. var epochMonth = yearToEpochMonth(toInt(year));
  1113. if (epochMonth < 0 || epochMonth > maxEpochDay) {
  1114. throw "Hijrah date out of range";
  1115. }
  1116. var len = _getYearLength(toInt(year));
  1117. return (len > 354);
  1118. }
  1119. function plusYears(years) {
  1120. if (years == 0) {
  1121. return this;
  1122. }
  1123. var newYear = this._year + years;
  1124. var hijrahDate = resolvePreviousValid(newYear, this._monthOfYear, this._dayOfMonth);
  1125. setFromHijrahDate(this, hijrahDate);
  1126. return this;
  1127. }
  1128. function plusMonths(monthsToAdd) {
  1129. if (monthsToAdd === 0) {
  1130. return this;
  1131. }
  1132. var monthCount = this._year * 12 + (this._monthOfYear - 1);
  1133. var calcMonths = monthCount + monthsToAdd; // safe overflow
  1134. var newYear = checkValidYear(floorDiv(calcMonths, 12));
  1135. var newMonth = toInt(floorMod(calcMonths, 12) + 1);
  1136. var hijrahDate = resolvePreviousValid(newYear, newMonth, this._dayOfMonth);
  1137. setFromHijrahDate(this, hijrahDate);
  1138. return this;
  1139. }
  1140. function plusWeeks(weeksToAdd) {
  1141. return this.plusDays(weeksToAdd * 7);
  1142. }
  1143. function plusDays(days) {
  1144. var hijrahDate = ofEpochDay(this.toEpochDay() + days);
  1145. setFromHijrahDate(this, hijrahDate);
  1146. return this;
  1147. }
  1148. function minusYears(yearsToSubtract) {
  1149. return this.plusYears(-yearsToSubtract);
  1150. }
  1151. function minusMonths(monthsToSubtract) {
  1152. return this.plusMonths(-monthsToSubtract);
  1153. }
  1154. function minusWeeks(weeksToSubtract) {
  1155. return this.plusWeeks(-weeksToSubtract);
  1156. }
  1157. function minusDays(daysToSubtract) {
  1158. return this.plusDays(-daysToSubtract);
  1159. }
  1160. function toGregorian(){
  1161. return new Date(this._gregorianDate);
  1162. }
  1163. function format(format, localeId){
  1164. if(arguments.length === 0){
  1165. return HijrahDateFormatter.formatter('en')(this);
  1166. }
  1167. if(arguments.length === 1){
  1168. return HijrahDateFormatter.formatter('en')(this, format);
  1169. }
  1170. return HijrahDateFormatter.formatter(localeId)(this, format);
  1171. }
  1172. function toString(){
  1173. if(isNaN(this.getTime())){
  1174. return 'Invalid Hijrah Date';
  1175. }
  1176. return this.format('medium');
  1177. }
  1178. function resolvePreviousValid(year, month, day) {
  1179. var monthDays = _getMonthLength(year, month);
  1180. if (day > monthDays) {
  1181. day = monthDays;
  1182. }
  1183. return new HijrahDate(year, month-1, day);
  1184. }
  1185. function checkValidYear(hijrahYear) {
  1186. if (hijrahYear < getMinimumYear() || hijrahYear > getMaximumYear()) {
  1187. throw "Invalid Hijrah year: " + hijrahYear;
  1188. }
  1189. return toInt(hijrahYear);
  1190. }
  1191. function checkValidDayOfYear(dayOfYear) {
  1192. if (dayOfYear < 1 || dayOfYear > getMaximumDayOfYear()) {
  1193. throw "Invalid Hijrah day of year: " + dayOfYear;
  1194. }
  1195. }
  1196. function checkValidMonth(month) {
  1197. if (month < 1 || month > 12) {
  1198. throw "Invalid Hijrah month: " + month;
  1199. }
  1200. }
  1201. function getHijrahDateInfo(epochDay) {
  1202. if (epochDay < minEpochDay || epochDay >= maxEpochDay) {
  1203. throw "Hijrah date out of range";
  1204. }
  1205. var epochMonth = epochDayToEpochMonth(epochDay);
  1206. var year = epochMonthToYear(epochMonth);
  1207. var month = epochMonthToMonth(epochMonth);
  1208. var day1 = epochMonthToEpochDay(epochMonth);
  1209. var date = epochDay - day1; // epochDay - dayOfEpoch(year, month);
  1210. var dateInfo = new Array(3);
  1211. dateInfo[0] = year;
  1212. dateInfo[1] = month + 1; // change to 1-based.
  1213. dateInfo[2] = date + 1; // change to 1-based.
  1214. return dateInfo;
  1215. }
  1216. function getEpochDay(hijrahYear, monthOfYear, dayOfMonth) {
  1217. checkValidMonth(monthOfYear);
  1218. var epochMonth = yearToEpochMonth(hijrahYear) + (monthOfYear - 1);
  1219. if (epochMonth < 0 || epochMonth >= hijrahEpochMonthStartDays.length) {
  1220. throw "Invalid Hijrah date, year: " +
  1221. hijrahYear + ", month: " + monthOfYear;
  1222. }
  1223. if (dayOfMonth < 1 || dayOfMonth > _getMonthLength(hijrahYear, monthOfYear)) {
  1224. throw "Invalid Hijrah day of month: " + dayOfMonth;
  1225. }
  1226. return epochMonthToEpochDay(epochMonth) + (dayOfMonth - 1);
  1227. }
  1228. function _getDayOfYear(hijrahYear, month) {
  1229. return yearMonthToDayOfYear(hijrahYear, (month - 1));
  1230. }
  1231. function _getMonthLength(hijrahYear, monthOfYear) {
  1232. var epochMonth = yearToEpochMonth(hijrahYear) + (monthOfYear - 1);
  1233. if (epochMonth < 0 || epochMonth >= hijrahEpochMonthStartDays.length) {
  1234. throw "Invalid Hijrah date, year: " +
  1235. hijrahYear + ", month: " + monthOfYear;
  1236. }
  1237. return epochMonthLength(epochMonth);
  1238. }
  1239. function _getYearLength(hijrahYear) {
  1240. return yearMonthToDayOfYear(hijrahYear, 12);
  1241. }
  1242. function getMinimumYear() {
  1243. return epochMonthToYear(0);
  1244. }
  1245. function getMaximumYear() {
  1246. return epochMonthToYear(hijrahEpochMonthStartDays.length - 1) - 1;
  1247. }
  1248. function getMaximumMonthLength() {
  1249. return maxMonthLength;
  1250. }
  1251. function getMinimumMonthLength() {
  1252. return minMonthLength;
  1253. }
  1254. function getMaximumDayOfYear() {
  1255. return maxYearLength;
  1256. }
  1257. function getSmallestMaximumDayOfYear() {
  1258. return minYearLength;
  1259. }
  1260. function epochDayToEpochMonth(epochDay) {
  1261. var ndx = arrayBinarySearch(hijrahEpochMonthStartDays, epochDay);
  1262. if (ndx < 0) {
  1263. ndx = -ndx - 2;
  1264. }
  1265. return ndx;
  1266. }
  1267. function epochMonthToYear(epochMonth) {
  1268. return toInt((epochMonth + hijrahStartEpochMonth) / 12);
  1269. }
  1270. function yearToEpochMonth(year) {
  1271. return (year * 12) - hijrahStartEpochMonth;
  1272. }
  1273. function epochMonthToMonth(epochMonth) {
  1274. return (epochMonth + hijrahStartEpochMonth) % 12;
  1275. }
  1276. function epochMonthToEpochDay(epochMonth) {
  1277. return hijrahEpochMonthStartDays[epochMonth];
  1278. }
  1279. function yearMonthToDayOfYear(hijrahYear, month) {
  1280. var epochMonthFirst = yearToEpochMonth(hijrahYear);
  1281. return epochMonthToEpochDay(epochMonthFirst + month)
  1282. - epochMonthToEpochDay(epochMonthFirst);
  1283. }
  1284. function epochMonthLength(epochMonth) {
  1285. return hijrahEpochMonthStartDays[epochMonth + 1]
  1286. - hijrahEpochMonthStartDays[epochMonth];
  1287. }
  1288. function createEpochMonths(epochDay, minYear, maxYear, years) {
  1289. var numMonths = (maxYear - minYear + 1) * 12 + 1;
  1290. var epochMonth = 0;
  1291. var epochMonths = new Array(numMonths);
  1292. minMonthLength = Number.MIN_VALUE;
  1293. maxMonthLength = Number.MAX_VALUE;
  1294. for (var year = minYear; year <= maxYear; year++) {
  1295. var months = years[year];// must not be gaps
  1296. for (var month = 0; month < 12; month++) {
  1297. var length = months[month];
  1298. epochMonths[epochMonth++] = epochDay;
  1299. if (length < 29 || length > 32) {
  1300. throw "Invalid month length in year: " + minYear;
  1301. }
  1302. epochDay += length;
  1303. minMonthLength = Math.min(minMonthLength, length);
  1304. maxMonthLength = Math.max(maxMonthLength, length);
  1305. }
  1306. }
  1307. epochMonths[epochMonth++] = epochDay;
  1308. if (epochMonth != epochMonths.length) {
  1309. throw "Did not fill epochMonths exactly: ndx = " + epochMonth + " should be " + epochMonths.length;
  1310. }
  1311. return epochMonths;
  1312. }
  1313. function isGregorianLeapYear(year) {
  1314. return ((year & 3) == 0) && ((year % 100) != 0 || (year % 400) == 0);
  1315. }
  1316. function epochDayFromGregorain(date) {
  1317. var y = date.getFullYear();
  1318. var m = date.getMonth()+1;
  1319. var total = 0;
  1320. total += 365 * y;
  1321. if (y >= 0) {
  1322. total += toInt((y + 3) / 4) - toInt((y + 99) / 100) + toInt((y + 399) / 400);
  1323. } else {
  1324. total -= toInt(y / -4 - y / -100 + y / -400);
  1325. }
  1326. total += toInt(((367 * m - 362) / 12));
  1327. total += date.getDate() - 1;
  1328. if (m > 2) {
  1329. total--;
  1330. if (isGregorianLeapYear(date.getFullYear()) == false) {
  1331. total--;
  1332. }
  1333. }
  1334. return total - DAYS_0000_TO_1970;
  1335. }
  1336. function gregorianFromEpochDay(epochDay) {
  1337. var zeroDay = epochDay + DAYS_0000_TO_1970;
  1338. // find the march-based year
  1339. zeroDay -= 60; // adjust to 0000-03-01 so leap day is at end of four year cycle
  1340. var adjust = 0;
  1341. if (zeroDay < 0) {
  1342. // adjust negative years to positive for calculation
  1343. var adjustCycles = toInt((zeroDay + 1) / DAYS_PER_CYCLE - 1);
  1344. adjust = adjustCycles * 400;
  1345. zeroDay += -adjustCycles * DAYS_PER_CYCLE;
  1346. }
  1347. var yearEst = toInt((400 * zeroDay + 591) / DAYS_PER_CYCLE);
  1348. var doyEst = zeroDay - (365 * yearEst + toInt(yearEst / 4) - toInt(yearEst / 100) + toInt(yearEst / 400));
  1349. if (doyEst < 0) {
  1350. // fix estimate
  1351. yearEst--;
  1352. doyEst = zeroDay - toInt((365 * yearEst + yearEst / 4 - yearEst / 100 + yearEst / 400));
  1353. }
  1354. yearEst += adjust; // reset any negative year
  1355. var marchDoy0 = toInt(doyEst);
  1356. // convert march-based values back to january-based
  1357. var marchMonth0 = toInt((marchDoy0 * 5 + 2) / 153);
  1358. var month = (marchMonth0 + 2) % 12 + 1;
  1359. var dom = marchDoy0 - toInt((marchMonth0 * 306 + 5) / 10) + 1;
  1360. yearEst += toInt(marchMonth0 / 10);
  1361. return new Date(yearEst, month - 1, dom);
  1362. }
  1363. function init(){
  1364. var years = [];
  1365. years['1300']=[30,29,30,29,30,29,30,29,30,29,30,29];
  1366. years['1301']=[30,30,29,30,29,30,29,30,29,30,29,29];
  1367. years['1302']=[30,30,30,29,30,30,29,29,30,29,29,30];
  1368. years['1303']=[29,30,30,29,30,30,29,30,29,30,29,29];
  1369. years['1304']=[29,30,30,29,30,30,30,29,30,29,30,29];
  1370. years['1305']=[29,29,30,30,29,30,30,29,30,30,29,29];
  1371. years['1306']=[30,29,30,29,30,29,30,29,30,30,29,30];
  1372. years['1307']=[29,30,29,30,29,30,29,30,29,30,29,30];
  1373. years['1308']=[29,30,30,29,30,29,30,29,30,29,29,30];
  1374. years['1309']=[29,30,30,30,30,29,29,30,29,29,30,29];
  1375. years['1310']=[30,29,30,30,30,29,30,29,30,29,29,30];
  1376. years['1311']=[29,30,29,30,30,30,29,30,29,30,29,29];
  1377. years['1312']=[30,29,30,29,30,30,29,30,30,29,30,29];
  1378. years['1313']=[29,30,29,30,29,30,29,30,30,30,29,29];
  1379. years['1314']=[30,30,29,30,29,29,30,29,30,30,29,30];
  1380. years['1315']=[29,30,30,29,30,29,29,30,29,30,29,30];
  1381. years['1316']=[29,30,30,30,29,30,29,29,30,29,30,29];
  1382. years['1317']=[30,29,30,30,29,30,29,30,29,30,29,29];
  1383. years['1318']=[30,29,30,30,29,30,30,29,30,29,30,29];
  1384. years['1319']=[29,30,29,30,30,29,30,29,30,30,29,30];
  1385. years['1320']=[29,30,29,29,30,29,30,29,30,30,30,29];
  1386. years['1321']=[30,29,30,29,29,30,29,29,30,30,30,30];
  1387. years['1322']=[29,30,29,30,29,29,29,30,29,30,30,30];
  1388. years['1323']=[29,30,30,29,30,29,29,29,30,29,30,30];
  1389. years['1324']=[29,30,30,29,30,29,30,29,29,30,29,30];
  1390. years['1325']=[30,29,30,29,30,30,29,30,29,30,29,30];
  1391. years['1326']=[29,29,30,29,30,30,29,30,29,30,30,29];
  1392. years['1327']=[30,29,29,30,29,30,29,30,30,29,30,30];
  1393. years['1328']=[29,30,29,29,30,29,29,30,30,30,29,30];
  1394. years['1329']=[30,29,30,29,29,30,29,29,30,30,29,30];
  1395. years['1330']=[30,30,29,30,29,29,30,29,29,30,30,29];
  1396. years['1331']=[30,30,29,30,30,29,29,30,29,30,29,30];
  1397. years['1332']=[29,30,29,30,30,29,30,29,30,30,29,29];
  1398. years['1333']=[30,29,29,30,30,29,30,30,29,30,30,29];
  1399. years['1334']=[29,29,30,29,30,29,30,30,30,29,30,29];
  1400. years['1335']=[30,29,30,29,29,30,29,30,30,29,30,30];
  1401. years['1336']=[29,30,29,30,29,29,30,29,30,29,30,30];
  1402. years['1337']=[30,29,30,29,30,29,29,30,29,30,29,30];
  1403. years['1338']=[29,30,30,29,30,30,29,29,30,29,30,29];
  1404. years['1339']=[30,29,30,29,30,30,30,29,30,29,29,30];
  1405. years['1340']=[29,29,30,29,30,30,30,30,29,30,29,29];
  1406. years['1341']=[30,29,29,30,29,30,30,30,29,30,30,29];
  1407. years['1342']=[29,29,30,29,30,29,30,30,29,30,30,29];
  1408. years['1343']=[30,29,29,30,29,30,29,30,29,30,30,29];
  1409. years['1344']=[30,29,30,29,30,30,29,29,30,29,30,29];
  1410. years['1345']=[30,29,30,30,30,29,30,29,29,30,29,29];
  1411. years['1346']=[30,29,30,30,30,30,29,30,29,29,30,29];
  1412. years['1347']=[29,30,29,30,30,30,29,30,30,29,29,30];
  1413. years['1348']=[29,29,30,29,30,30,29,30,30,30,29,29];
  1414. years['1349']=[30,29,29,30,29,30,30,29,30,30,29,30];
  1415. years['1350']=[29,30,29,30,29,30,29,29,30,30,29,30];
  1416. years['1351']=[30,29,30,29,30,29,30,29,29,30,29,30];
  1417. years['1352']=[30,29,30,30,29,30,29,30,29,29,30,29];
  1418. years['1353']=[30,29,30,30,30,29,30,29,29,30,29,30];
  1419. years['1354']=[29,30,29,30,30,29,30,30,29,30,29,29];
  1420. years['1355']=[30,29,29,30,30,29,30,30,29,30,30,29];
  1421. years['1356']=[29,30,29,30,29,30,29,30,29,30,30,30];
  1422. years['1357']=[29,29,30,29,30,29,29,30,29,30,30,30];
  1423. years['1358']=[29,30,29,30,29,30,29,29,30,29,30,30];
  1424. years['1359']=[29,30,30,29,30,29,30,29,29,29,30,30];
  1425. years['1360']=[29,30,30,30,29,30,29,30,29,29,30,29];
  1426. years['1361']=[30,29,30,30,29,30,30,29,29,30,29,30];
  1427. years['1362']=[29,30,29,30,29,30,30,29,30,29,30,29];
  1428. years['1363']=[30,29,30,29,30,29,30,29,30,29,30,30];
  1429. years['1364']=[29,30,29,30,29,29,30,29,30,29,30,30];
  1430. years['1365']=[30,30,29,29,30,29,29,30,29,30,29,30];
  1431. years['1366']=[30,30,29,30,29,30,29,29,30,29,30,29];
  1432. years['1367']=[30,30,29,30,30,29,30,29,29,30,29,30];
  1433. years['1368']=[29,30,29,30,30,30,29,29,30,29,30,29];
  1434. years['1369']=[30,29,30,29,30,30,29,30,29,30,30,29];
  1435. years['1370']=[30,29,29,30,29,30,29,30,29,30,30,30];
  1436. years['1371']=[29,30,29,29,30,29,30,29,30,29,30,30];
  1437. years['1372']=[30,29,29,30,29,30,29,29,30,29,30,30];
  1438. years['1373']=[30,29,30,29,30,29,30,29,29,30,29,30];
  1439. years['1374']=[30,29,30,30,29,30,29,30,29,29,30,29];
  1440. years['1375']=[30,29,30,30,29,30,30,29,30,29,30,29];
  1441. years['1376']=[29,30,29,30,29,30,30,30,29,30,29,30];
  1442. years['1377']=[29,29,30,29,29,30,30,30,29,30,30,29];
  1443. years['1378']=[30,29,29,29,30,29,30,30,29,30,30,30];
  1444. years['1379']=[29,30,29,29,29,30,29,30,30,29,30,30];
  1445. years['1380']=[29,30,29,30,29,30,29,30,29,30,29,30];
  1446. years['1381']=[29,30,29,30,30,29,30,29,30,29,29,30];
  1447. years['1382']=[29,30,29,30,30,29,30,30,29,30,29,29];
  1448. years['1383']=[30,29,29,30,30,30,29,30,30,29,30,29];
  1449. years['1384']=[29,30,29,29,30,30,29,30,30,30,29,30];
  1450. years['1385']=[29,29,30,29,29,30,30,29,30,30,30,29];
  1451. years['1386']=[30,29,29,30,29,29,30,30,29,30,30,29];
  1452. years['1387']=[30,29,30,29,30,29,30,29,30,29,30,29];
  1453. years['1388']=[30,30,29,30,29,30,29,30,29,30,29,29];
  1454. years['1389']=[30,30,29,30,30,29,30,30,29,29,30,29];
  1455. years['1390']=[29,30,29,30,30,30,29,30,29,30,29,30];
  1456. years['1391']=[29,29,30,29,30,30,29,30,30,29,30,29];
  1457. years['1392']=[30,29,29,30,29,30,29,30,30,29,30,30];
  1458. years['1393']=[29,30,29,29,30,29,30,29,30,29,30,30];
  1459. years['1394']=[30,29,30,29,29,30,29,30,29,30,29,30];
  1460. years['1395']=[30,29,30,30,29,30,29,29,30,29,29,30];
  1461. years['1396']=[30,29,30,30,29,30,30,29,29,30,29,29];
  1462. years['1397']=[30,29,30,30,29,30,30,30,29,29,29,30];
  1463. years['1398']=[29,30,29,30,30,29,30,30,29,30,29,29];
  1464. years['1399']=[30,29,30,29,30,29,30,30,29,30,29,30];
  1465. years['1400']=[30,29,30,29,29,30,29,30,29,30,29,30];
  1466. years['1401']=[30,30,29,30,29,29,30,29,29,30,29,30];
  1467. years['1402']=[30,30,30,29,30,29,29,30,29,29,30,29];
  1468. years['1403']=[30,30,30,29,30,30,29,29,30,29,29,30];
  1469. years['1404']=[29,30,30,29,30,30,29,30,29,30,29,29];
  1470. years['1405']=[30,29,30,29,30,30,30,29,30,29,29,30];
  1471. years['1406']=[30,29,29,30,29,30,30,29,30,29,30,30];
  1472. years['1407']=[29,30,29,29,30,29,30,29,30,29,30,30];
  1473. years['1408']=[30,29,30,29,30,29,29,30,29,29,30,30];
  1474. years['1409']=[30,30,29,30,29,30,29,29,30,29,29,30];
  1475. years['1410']=[30,30,29,30,30,29,30,29,29,30,29,29];
  1476. years['1411']=[30,30,29,30,30,29,30,30,29,29,30,29];
  1477. years['1412']=[30,29,30,29,30,29,30,30,30,29,29,30];
  1478. years['1413']=[29,30,29,29,30,29,30,30,30,29,30,29];
  1479. years['1414']=[30,29,30,29,29,30,29,30,30,29,30,30];
  1480. years['1415']=[29,30,29,30,29,29,30,29,30,29,30,30];
  1481. years['1416']=[30,29,30,29,30,29,29,30,29,30,29,30];
  1482. years['1417']=[30,29,30,30,29,29,30,29,30,29,30,29];
  1483. years['1418']=[30,29,30,30,29,30,29,30,29,30,29,30];
  1484. years['1419']=[29,30,29,30,29,30,29,30,30,30,29,29];
  1485. years['1420']=[29,30,29,29,30,29,30,30,30,30,29,30];
  1486. years['1421']=[29,29,30,29,29,29,30,30,30,30,29,30];
  1487. years['1422']=[30,29,29,30,29,29,29,30,30,30,29,30];
  1488. years['1423']=[30,29,30,29,30,29,29,30,29,30,29,30];
  1489. years['1424']=[30,29,30,30,29,30,29,29,30,29,30,29];
  1490. years['1425']=[30,29,30,30,29,30,29,30,30,29,30,29];
  1491. years['1426']=[29,30,29,30,29,30,30,29,30,30,29,30];
  1492. years['1427']=[29,29,30,29,30,29,30,30,29,30,30,29];
  1493. years['1428']=[30,29,29,30,29,29,30,30,30,29,30,30];
  1494. years['1429']=[29,30,29,29,30,29,29,30,30,29,30,30];
  1495. years['1430']=[29,30,30,29,29,30,29,30,29,30,29,30];
  1496. years['1431']=[29,30,30,29,30,29,30,29,30,29,29,30];
  1497. years['1432']=[29,30,30,30,29,30,29,30,29,30,29,29];
  1498. years['1433']=[30,29,30,30,29,30,30,29,30,29,30,29];
  1499. years['1434']=[29,30,29,30,29,30,30,29,30,30,29,29];
  1500. years['1435']=[30,29,30,29,30,29,30,29,30,30,29,30];
  1501. years['1436']=[29,30,29,30,29,30,29,30,29,30,29,30];
  1502. years['1437']=[30,29,30,30,29,29,30,29,30,29,29,30];
  1503. years['1438']=[30,29,30,30,30,29,29,30,29,29,30,29];
  1504. years['1439']=[30,29,30,30,30,29,30,29,30,29,29,30];
  1505. years['1440']=[29,30,29,30,30,30,29,30,29,30,29,29];
  1506. years['1441']=[30,29,30,29,30,30,29,30,30,29,30,29];
  1507. years['1442']=[29,30,29,30,29,30,29,30,30,29,30,29];
  1508. years['1443']=[30,29,30,29,30,29,30,29,30,29,30,30];
  1509. years['1444']=[29,30,29,30,30,29,29,30,29,30,29,30];
  1510. years['1445']=[29,30,30,30,29,30,29,29,30,29,29,30];
  1511. years['1446']=[29,30,30,30,29,30,30,29,29,30,29,29];
  1512. years['1447']=[30,29,30,30,30,29,30,29,30,29,30,29];
  1513. years['1448']=[29,30,29,30,30,29,30,30,29,30,29,30];
  1514. years['1449']=[29,29,30,29,30,29,30,30,29,30,30,29];
  1515. years['1450']=[30,29,30,29,29,30,29,30,29,30,30,29];
  1516. years['1451']=[30,30,30,29,29,30,29,29,30,30,29,30];
  1517. years['1452']=[30,29,30,30,29,29,30,29,29,30,29,30];
  1518. years['1453']=[30,29,30,30,29,30,29,30,29,29,30,29];
  1519. years['1454']=[30,29,30,30,29,30,30,29,30,29,30,29];
  1520. years['1455']=[29,30,29,30,30,29,30,29,30,30,29,30];
  1521. years['1456']=[29,29,30,29,30,29,30,29,30,30,30,29];
  1522. years['1457']=[30,29,29,30,29,29,30,29,30,30,30,30];
  1523. years['1458']=[29,30,29,29,30,29,29,30,29,30,30,30];
  1524. years['1459']=[29,30,30,29,29,30,29,29,30,29,30,30];
  1525. years['1460']=[29,30,30,29,30,29,30,29,29,30,29,30];
  1526. years['1461']=[29,30,30,29,30,29,30,29,30,30,29,29];
  1527. years['1462']=[30,29,30,29,30,30,29,30,29,30,30,29];
  1528. years['1463']=[29,30,29,30,29,30,29,30,30,30,29,30];
  1529. years['1464']=[29,30,29,29,30,29,29,30,30,30,29,30];
  1530. years['1465']=[30,29,30,29,29,30,29,29,30,30,29,30];
  1531. years['1466']=[30,30,29,30,29,29,29,30,29,30,30,29];
  1532. years['1467']=[30,30,29,30,30,29,29,30,29,30,29,30];
  1533. years['1468']=[29,30,29,30,30,29,30,29,30,29,30,29];
  1534. years['1469']=[29,30,29,30,30,29,30,30,29,30,29,30];
  1535. years['1470']=[29,29,30,29,30,30,29,30,30,29,30,29];
  1536. years['1471']=[30,29,29,30,29,30,29,30,30,29,30,30];
  1537. years['1472']=[29,30,29,29,30,29,30,29,30,30,29,30];
  1538. years['1473']=[29,30,29,30,30,29,29,30,29,30,29,30];
  1539. years['1474']=[29,30,30,29,30,30,29,29,30,29,30,29];
  1540. years['1475']=[29,30,30,29,30,30,30,29,29,30,29,29];
  1541. years['1476']=[30,29,30,29,30,30,30,29,30,29,30,29];
  1542. years['1477']=[29,30,29,29,30,30,30,30,29,30,29,30];
  1543. years['1478']=[29,29,30,29,30,29,30,30,29,30,30,29];
  1544. years['1479']=[30,29,29,30,29,30,29,30,29,30,30,29];
  1545. years['1480']=[30,29,30,29,30,29,30,29,30,29,30,29];
  1546. years['1481']=[30,29,30,30,29,30,29,30,29,30,29,29];
  1547. years['1482']=[30,29,30,30,30,30,29,30,29,29,30,29];
  1548. years['1483']=[29,30,29,30,30,30,29,30,30,29,29,30];
  1549. years['1484']=[29,29,30,29,30,30,30,29,30,29,30,29];
  1550. years['1485']=[30,29,29,30,29,30,30,29,30,30,29,30];
  1551. years['1486']=[29,30,29,29,30,29,30,29,30,30,29,30];
  1552. years['1487']=[30,29,30,29,30,29,29,30,29,30,29,30];
  1553. years['1488']=[30,29,30,30,29,30,29,29,30,29,30,29];
  1554. years['1489']=[30,29,30,30,30,29,30,29,29,30,29,30];
  1555. years['1490']=[29,30,29,30,30,29,30,30,29,29,30,29];
  1556. years['1491']=[30,29,29,30,30,29,30,30,29,30,29,30];
  1557. years['1492']=[29,30,29,29,30,30,29,30,29,30,30,29];
  1558. years['1493']=[30,29,30,29,30,29,29,30,29,30,30,30];
  1559. years['1494']=[29,30,29,30,29,30,29,29,29,30,30,30];
  1560. years['1495']=[29,30,30,29,30,29,29,30,29,29,30,30];
  1561. years['1496']=[29,30,30,30,29,30,29,29,30,29,29,30];
  1562. years['1497']=[30,29,30,30,29,30,29,30,29,30,29,30];
  1563. years['1498']=[29,30,29,30,29,30,30,29,30,29,30,29];
  1564. years['1499']=[30,29,30,29,29,30,30,29,30,29,30,30];
  1565. years['1500']=[29,30,29,30,29,29,30,29,30,29,30,30];
  1566. years['1501']=[30,29,30,29,30,29,29,29,30,29,30,30];
  1567. years['1502']=[30,30,29,30,29,30,29,29,29,30,30,29];
  1568. years['1503']=[30,30,29,30,30,29,30,29,29,29,30,30];
  1569. years['1504']=[29,30,29,30,30,30,29,29,30,29,30,29];
  1570. years['1505']=[30,29,30,29,30,30,29,30,29,30,30,29];
  1571. years['1506']=[29,30,29,29,30,30,29,30,30,29,30,30];
  1572. years['1507']=[29,29,30,29,29,30,30,29,30,29,30,30];
  1573. years['1508']=[30,29,29,30,29,30,29,29,30,29,30,30];
  1574. years['1509']=[30,29,30,29,30,29,30,29,29,30,29,30];
  1575. years['1510']=[30,29,30,30,29,30,29,30,29,29,30,29];
  1576. years['1511']=[30,29,30,30,29,30,30,29,30,29,29,30];
  1577. years['1512']=[29,30,29,30,29,30,30,30,29,30,29,30];
  1578. years['1513']=[29,29,29,30,29,30,30,30,29,30,30,29];
  1579. years['1514']=[30,29,29,29,30,29,30,30,29,30,30,30];
  1580. years['1515']=[29,29,30,29,29,30,29,30,30,29,30,30];
  1581. years['1516']=[29,30,29,30,29,29,30,29,30,29,30,30];
  1582. years['1517']=[29,30,29,30,29,30,30,29,29,30,29,30];
  1583. years['1518']=[29,30,29,30,30,29,30,30,29,30,29,29];
  1584. years['1519']=[30,29,29,30,30,30,29,30,30,29,30,29];
  1585. years['1520']=[29,30,29,29,30,30,30,29,30,30,29,30];
  1586. years['1521']=[29,29,29,30,29,30,30,29,30,30,29,30];
  1587. years['1522']=[30,29,29,29,30,29,30,30,29,30,30,29];
  1588. years['1523']=[30,29,30,29,30,29,30,29,29,30,30,29];
  1589. years['1524']=[30,30,29,30,29,30,29,30,29,29,30,29];
  1590. years['1525']=[30,30,29,30,30,29,30,29,30,29,29,30];
  1591. years['1526']=[29,30,29,30,30,30,29,30,29,30,29,29];
  1592. years['1527']=[30,29,30,29,30,30,29,30,30,29,30,29];
  1593. years['1528']=[30,29,29,30,29,30,29,30,30,29,30,30];
  1594. years['1529']=[29,30,29,29,30,29,30,29,30,29,30,30];
  1595. years['1530']=[29,30,30,29,29,30,29,30,29,29,30,30];
  1596. years['1531']=[29,30,30,30,29,29,30,29,30,29,29,30];
  1597. years['1532']=[29,30,30,30,29,30,30,29,29,29,30,29];
  1598. years['1533']=[30,29,30,30,30,29,30,29,30,29,29,30];
  1599. years['1534']=[29,30,29,30,30,29,30,30,29,29,30,29];
  1600. years['1535']=[30,29,30,29,30,29,30,30,29,30,29,30];
  1601. years['1536']=[29,30,29,30,29,30,29,30,29,30,29,30];
  1602. years['1537']=[30,29,30,30,29,29,30,29,29,30,29,30];
  1603. years['1538']=[30,30,29,30,30,29,29,30,29,29,30,29];
  1604. years['1539']=[30,30,30,29,30,30,29,29,30,29,29,30];
  1605. years['1540']=[29,30,30,29,30,30,29,30,29,29,30,29];
  1606. years['1541']=[30,29,30,29,30,30,30,29,30,29,29,30];
  1607. years['1542']=[29,30,29,30,29,30,30,29,30,29,30,30];
  1608. years['1543']=[29,30,29,29,30,29,30,29,30,29,30,30];
  1609. years['1544']=[30,29,30,29,29,30,29,30,29,30,29,30];
  1610. years['1545']=[30,30,29,30,29,29,30,29,30,29,29,30];
  1611. years['1546']=[30,30,29,30,29,30,29,30,29,30,29,29];
  1612. years['1547']=[30,30,29,30,30,29,30,29,30,29,30,29];
  1613. years['1548']=[30,29,29,30,30,29,30,30,29,30,29,30];
  1614. years['1549']=[29,30,29,29,30,29,30,30,30,29,30,29];
  1615. years['1550']=[30,29,30,29,29,29,30,30,30,29,30,30];
  1616. years['1551']=[29,30,29,29,30,29,29,30,30,29,30,30];
  1617. years['1552']=[30,29,30,29,29,30,29,29,30,30,29,30];
  1618. years['1553']=[30,29,30,29,30,29,30,29,30,29,30,29];
  1619. years['1554']=[30,29,30,29,30,30,29,30,29,30,29,30];
  1620. years['1555']=[29,29,30,29,30,30,29,30,30,29,30,29];
  1621. years['1556']=[30,29,29,30,29,30,29,30,30,30,29,30];
  1622. years['1557']=[29,30,29,29,29,30,29,30,30,30,30,29];
  1623. years['1558']=[30,29,30,29,29,29,30,29,30,30,30,29];
  1624. years['1559']=[30,30,29,29,30,29,29,30,30,29,30,29];
  1625. years['1560']=[30,30,29,30,29,30,29,30,29,30,29,30];
  1626. years['1561']=[29,30,30,29,30,29,30,30,29,29,30,29];
  1627. years['1562']=[29,30,30,29,30,29,30,30,30,29,29,30];
  1628. years['1563']=[29,30,29,29,30,29,30,30,30,29,30,29];
  1629. years['1564']=[30,29,30,29,29,30,29,30,30,30,29,30];
  1630. years['1565']=[29,30,29,30,29,29,30,29,30,30,29,30];
  1631. years['1566']=[30,29,30,29,30,29,29,30,29,30,29,30];
  1632. years['1567']=[30,29,30,30,29,30,29,30,29,29,30,29];
  1633. years['1568']=[30,29,30,30,30,29,30,29,30,29,29,29];
  1634. years['1569']=[30,29,30,30,30,29,30,30,29,30,29,29];
  1635. years['1570']=[29,30,29,30,30,29,30,30,30,29,29,30];
  1636. years['1571']=[29,29,30,29,30,30,29,30,30,29,30,29];
  1637. years['1572']=[30,29,29,30,29,30,29,30,30,29,30,29];
  1638. years['1573']=[30,29,30,30,29,30,29,29,30,29,30,29];
  1639. years['1574']=[30,30,29,30,30,29,30,29,29,30,29,29];
  1640. years['1575']=[30,30,30,29,30,30,29,30,29,29,29,30];
  1641. years['1576']=[29,30,30,29,30,30,30,29,30,29,29,29];
  1642. years['1577']=[30,29,30,30,29,30,30,29,30,29,30,29];
  1643. years['1578']=[29,30,29,30,29,30,30,29,30,30,29,30];
  1644. years['1579']=[29,30,29,30,29,29,30,30,29,30,29,30];
  1645. years['1580']=[29,30,30,29,30,29,29,30,29,30,29,30];
  1646. years['1581']=[30,30,29,30,29,30,29,29,30,29,30,29];
  1647. years['1582']=[30,30,29,30,30,29,30,29,30,29,29,29];
  1648. years['1583']=[30,30,29,30,30,30,29,30,29,30,29,29];
  1649. years['1584']=[29,30,30,29,30,30,29,30,30,29,30,29];
  1650. years['1585']=[29,30,29,30,29,30,29,30,30,29,30,30];
  1651. years['1586']=[29,29,30,29,30,29,29,30,30,30,29,30];
  1652. years['1587']=[29,30,30,29,29,29,30,29,30,29,30,30];
  1653. years['1588']=[30,29,30,30,29,29,29,30,29,30,29,30];
  1654. years['1589']=[30,29,30,30,29,30,29,29,30,29,30,29];
  1655. years['1590']=[30,29,30,30,30,29,29,30,29,30,29,30];
  1656. years['1591']=[29,30,29,30,30,29,30,29,30,29,30,29];
  1657. years['1592']=[30,29,30,29,30,29,30,29,30,30,30,29];
  1658. years['1593']=[30,29,29,30,29,29,30,29,30,30,30,29];
  1659. years['1594']=[30,30,29,29,30,29,29,29,30,30,30,30];
  1660. years['1595']=[29,30,29,30,29,29,30,29,29,30,30,30];
  1661. years['1596']=[29,30,30,29,30,29,29,30,29,30,29,30];
  1662. years['1597']=[29,30,30,29,30,29,30,29,30,29,30,29];
  1663. years['1598']=[30,29,30,29,30,30,29,30,29,30,30,29];
  1664. years['1599']=[29,30,29,30,29,30,29,30,30,30,29,30];
  1665. years['1600']=[29,29,30,29,30,29,29,30,30,30,29,30];
  1666. var minYear = 1300;
  1667. var maxYear = 1600;
  1668. var isoStart = epochDayFromGregorain(new Date(1882, 11-1, 12));
  1669. hijrahStartEpochMonth = minYear * 12;
  1670. minEpochDay = isoStart;
  1671. hijrahEpochMonthStartDays = createEpochMonths(minEpochDay, minYear, maxYear, years);
  1672. maxEpochDay = hijrahEpochMonthStartDays[hijrahEpochMonthStartDays.length - 1];
  1673. minYearLength = 0, maxYearLength = 0;
  1674. for (var year = minYear; year < maxYear; year++) {
  1675. var length = _getYearLength(year);
  1676. minYearLength = Math.min(minYearLength, length);
  1677. maxYearLength = Math.max(maxYearLength, length);
  1678. }
  1679. }
  1680. return HijrahDate;
  1681. })();
  1682. ; return HijrahDate;}));