islamic.js 6.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249
  1. define("dojox/date/islamic", ["dojo/_base/kernel", "dojo/date", "./islamic/Date"], function(dojo, dd, islamicDate){
  2. dojo.getObject("date.islamic", true, dojox);
  3. dojo.experimental("dojox.date.islamic");
  4. // Utility methods to do arithmetic calculations with islamic.Dates
  5. // added for compat to date
  6. dojox.date.islamic.getDaysInMonth = function(/*islamic.Date*/month){
  7. return month.getDaysInIslamicMonth(month.getMonth(), month.getFullYear());
  8. };
  9. //TODO: define islamic.isLeapYear? Or should it be invalid, since it has different meaning?
  10. dojox.date.islamic.compare = function(/*islamic.Date*/date1, /*islamic.Date*/date2, /*String?*/portion){
  11. // summary:
  12. // Compare two islamic date objects by date, time, or both.
  13. // description:
  14. // Returns 0 if equal, positive if a > b, else negative.
  15. // date1:
  16. // islamic.Date object
  17. // date2:
  18. // islamic.Date object. If not specified, the current islamic.Date is used.
  19. // portion:
  20. // A string indicating the "date" or "time" portion of a Date object.
  21. // Compares both "date" and "time" by default. One of the following:
  22. // "date", "time", "datetime"
  23. if(date1 instanceof islamicDate){
  24. date1 = date1.toGregorian();
  25. }
  26. if(date2 instanceof islamicDate){
  27. date2 = date2.toGregorian();
  28. }
  29. return dd.compare.apply(null, arguments);
  30. };
  31. dojox.date.islamic.add = function(/*dojox.date.islamic.Date*/date, /*String*/interval, /*int*/amount){
  32. // based on and similar to dojo.date.add
  33. // summary:
  34. // Add to a Date in intervals of different size, from milliseconds to years
  35. // date: islamic.Date
  36. // Date object to start with
  37. // interval:
  38. // A string representing the interval. One of the following:
  39. // "year", "month", "day", "hour", "minute", "second",
  40. // "millisecond", "week", "weekday"
  41. // amount:
  42. // How much to add to the date.
  43. var newIslamDate = new islamicDate(date);
  44. switch(interval){
  45. case "day":
  46. newIslamDate.setDate(date.getDate() + amount);
  47. break;
  48. case "weekday":
  49. var day = date.getDay();
  50. if(((day + amount) < 5) && ((day + amount) > 0)){
  51. newIslamDate.setDate(date.getDate() + amount);
  52. }else{
  53. var adddays = 0, /*weekend */
  54. remdays = 0;
  55. if(day == 5){//friday
  56. day = 4;
  57. remdays = (amount > 0) ? -1 : 1;
  58. }else if(day == 6){ //shabat
  59. day = 4;
  60. remdays = (amount > 0) ? -2 : 2;
  61. }
  62. var add = (amount > 0) ? (5 - day - 1) : -day
  63. var amountdif = amount - add;
  64. var div = parseInt(amountdif / 5);
  65. if(amountdif % 5 != 0){
  66. adddays = (amount > 0) ? 2 : -2;
  67. }
  68. adddays = adddays + div * 7 + amountdif % 5 + add;
  69. newIslamDate.setDate(date.getDate() + adddays + remdays);
  70. }
  71. break;
  72. case "year":
  73. newIslamDate.setFullYear(date.getFullYear() + amount);
  74. break;
  75. case "week":
  76. amount *= 7;
  77. newIslamDate.setDate(date.getDate() + amount);
  78. break;
  79. case "month":
  80. var month = date.getMonth();
  81. newIslamDate.setMonth(month + amount);
  82. break;
  83. case "hour":
  84. newIslamDate.setHours(date.getHours() + amount);
  85. break;
  86. case "minute":
  87. newIslamDate._addMinutes(amount);
  88. break;
  89. case "second":
  90. newIslamDate._addSeconds(amount);
  91. break;
  92. case "millisecond":
  93. newIslamDate._addMilliseconds(amount);
  94. break;
  95. }
  96. return newIslamDate; // dojox.date.islamic.Date
  97. };
  98. dojox.date.islamic.difference = function(/*dojox.date.islamic.Date*/date1, /*dojox.date.islamic.Date?*/date2, /*String?*/interval){
  99. // based on and similar to dojo.date.difference
  100. // summary:
  101. // date2 - date1
  102. // date2 is islamic.Date object. If not specified, the current islamic.Date is used.
  103. // interval:
  104. // A string representing the interval. One of the following:
  105. // "year", "month", "day", "hour", "minute", "second",
  106. // "millisecond", "week", "weekday"
  107. // Defaults to "day".
  108. date2 = date2 || new islamicDate();
  109. interval = interval || "day";
  110. var yearDiff = date2.getFullYear() - date1.getFullYear();
  111. var delta = 1; // Integer return value
  112. switch(interval){
  113. case "weekday":
  114. var days = Math.round(dojox.date.islamic.difference(date1, date2, "day"));
  115. var weeks = parseInt(dojox.date.islamic.difference(date1, date2, "week"));
  116. var mod = days % 7;
  117. // Even number of weeks
  118. if(mod == 0){
  119. days = weeks*5;
  120. }else{
  121. // Weeks plus spare change (< 7 days)
  122. var adj = 0;
  123. var aDay = date1.getDay();
  124. var bDay = date2.getDay();
  125. weeks = parseInt(days/7);
  126. mod = days % 7;
  127. // Mark the date advanced by the number of
  128. // round weeks (may be zero)
  129. var dtMark = new islamicDate(date1);
  130. dtMark.setDate(dtMark.getDate()+(weeks*7));
  131. var dayMark = dtMark.getDay();
  132. // Spare change days -- 6 or less
  133. if(days > 0){
  134. switch(true){
  135. // Range starts on Fri
  136. case aDay == 5:
  137. adj = -1;
  138. break;
  139. // Range starts on Sat
  140. case aDay == 6:
  141. adj = 0;
  142. break;
  143. // Range ends on Fri
  144. case bDay == 5:
  145. adj = -1;
  146. break;
  147. // Range ends on Sat
  148. case bDay == 6:
  149. adj = -2;
  150. break;
  151. // Range contains weekend
  152. case (dayMark + mod) > 5:
  153. adj = -2;
  154. }
  155. }else if(days < 0){
  156. switch(true){
  157. // Range starts on Fri
  158. case aDay == 5:
  159. adj = 0;
  160. break;
  161. // Range starts on Sat
  162. case aDay == 6:
  163. adj = 1;
  164. break;
  165. // Range ends on Fri
  166. case bDay == 5:
  167. adj = 2;
  168. break;
  169. // Range ends on Sat
  170. case bDay == 6:
  171. adj = 1;
  172. break;
  173. // Range contains weekend
  174. case (dayMark + mod) < 0:
  175. adj = 2;
  176. }
  177. }
  178. days += adj;
  179. days -= (weeks*2);
  180. }
  181. delta = days;
  182. break;
  183. case "year":
  184. delta = yearDiff;
  185. break;
  186. case "month":
  187. var startdate = (date2.toGregorian() > date1.toGregorian()) ? date2 : date1; // more
  188. var enddate = (date2.toGregorian() > date1.toGregorian()) ? date1 : date2;
  189. var month1 = startdate.getMonth();
  190. var month2 = enddate.getMonth();
  191. if (yearDiff == 0){
  192. delta = startdate.getMonth() - enddate.getMonth() ;
  193. }else{
  194. delta = 12-month2;
  195. delta += month1;
  196. var i = enddate.getFullYear()+1;
  197. var e = startdate.getFullYear();
  198. for (i; i < e; i++){
  199. delta += 12;
  200. }
  201. }
  202. if (date2.toGregorian() < date1.toGregorian()){
  203. delta = -delta;
  204. }
  205. break;
  206. case "week":
  207. // Truncate instead of rounding
  208. // Don't use Math.floor -- value may be negative
  209. delta = parseInt(dojox.date.islamic.difference(date1, date2, "day")/7);
  210. break;
  211. case "day":
  212. delta /= 24;
  213. // fallthrough
  214. case "hour":
  215. delta /= 60;
  216. // fallthrough
  217. case "minute":
  218. delta /= 60;
  219. // fallthrough
  220. case "second":
  221. delta /= 1000;
  222. // fallthrough
  223. case "millisecond":
  224. delta *= date2.toGregorian().getTime()- date1.toGregorian().getTime();
  225. }
  226. // Round for fractional values and DST leaps
  227. return Math.round(delta); // Number (integer)
  228. };
  229. return dojox.date.islamic;
  230. });