Du kan inte välja fler än 25 ämnen Ämnen måste starta med en bokstav eller siffra, kan innehålla bindestreck ('-') och vara max 35 tecken långa.
 
 
 
 

301 rader
6.8 KiB

  1. var MILI = 'milliseconds'
  2. , SECONDS = 'seconds'
  3. , MINUTES = 'minutes'
  4. , HOURS = 'hours'
  5. , DAY = 'day'
  6. , WEEK = 'week'
  7. , MONTH = 'month'
  8. , YEAR = 'year'
  9. , DECADE = 'decade'
  10. , CENTURY = 'century';
  11. var multiplierMilli = {
  12. 'milliseconds': 1,
  13. 'seconds': 1000,
  14. 'minutes': 60 * 1000,
  15. 'hours': 60 * 60 * 1000,
  16. 'day': 24 * 60 * 60 * 1000,
  17. 'week': 7 * 24 * 60 * 60 * 1000
  18. }
  19. var multiplierMonth = {
  20. 'month': 1,
  21. 'year': 12,
  22. 'decade': 10 * 12,
  23. 'century': 100 * 12
  24. }
  25. function daysOf(year) {
  26. return [31, daysInFeb(year), 31, 30, 31, 30, 31, 31, 30, 31, 30, 31]
  27. }
  28. function daysInFeb(year) {
  29. return (
  30. year % 4 === 0
  31. && year % 100 !== 0
  32. ) || year % 400 === 0
  33. ? 29
  34. : 28
  35. }
  36. export function add(d, num, unit) {
  37. d = new Date(d)
  38. switch (unit){
  39. case MILI:
  40. case SECONDS:
  41. case MINUTES:
  42. case HOURS:
  43. case DAY:
  44. case WEEK:
  45. return addMillis(d, num * multiplierMilli[unit])
  46. case MONTH:
  47. case YEAR:
  48. case DECADE:
  49. case CENTURY:
  50. return addMonths(d, num * multiplierMonth[unit])
  51. }
  52. throw new TypeError('Invalid units: "' + unit + '"')
  53. }
  54. function addMillis(d, num) {
  55. var nextDate = new Date(+(d) + num)
  56. return solveDST(d, nextDate)
  57. }
  58. function addMonths(d, num) {
  59. var year = d.getFullYear()
  60. , month = d.getMonth()
  61. , day = d.getDate()
  62. , totalMonths = year * 12 + month + num
  63. , nextYear = Math.trunc(totalMonths / 12)
  64. , nextMonth = totalMonths % 12
  65. , nextDay = Math.min(day, daysOf(nextYear)[nextMonth])
  66. var nextDate = new Date(d)
  67. nextDate.setFullYear(nextYear)
  68. // To avoid a bug when sets the Feb month
  69. // with a date > 28 or date > 29 (leap year)
  70. nextDate.setDate(1)
  71. nextDate.setMonth(nextMonth)
  72. nextDate.setDate(nextDay)
  73. return nextDate
  74. }
  75. function solveDST(currentDate, nextDate) {
  76. var currentOffset = currentDate.getTimezoneOffset()
  77. , nextOffset = nextDate.getTimezoneOffset()
  78. // if is DST, add the difference in minutes
  79. // else the difference is zero
  80. var diffMinutes = (nextOffset - currentOffset)
  81. return new Date(+(nextDate) + diffMinutes * multiplierMilli['minutes'])
  82. }
  83. export function subtract(d, num, unit) {
  84. return add(d, -num, unit)
  85. }
  86. export function startOf(d, unit, firstOfWeek) {
  87. d = new Date(d)
  88. switch (unit) {
  89. case CENTURY:
  90. case DECADE:
  91. case YEAR:
  92. d = month(d, 0);
  93. case MONTH:
  94. d = date(d, 1);
  95. case WEEK:
  96. case DAY:
  97. d = hours(d, 0);
  98. case HOURS:
  99. d = minutes(d, 0);
  100. case MINUTES:
  101. d = seconds(d, 0);
  102. case SECONDS:
  103. d = milliseconds(d, 0);
  104. }
  105. if (unit === DECADE)
  106. d = subtract(d, year(d) % 10, 'year')
  107. if (unit === CENTURY)
  108. d = subtract(d, year(d) % 100, 'year')
  109. if (unit === WEEK)
  110. d = weekday(d, 0, firstOfWeek);
  111. return d
  112. }
  113. export function endOf(d, unit, firstOfWeek){
  114. d = new Date(d)
  115. d = startOf(d, unit, firstOfWeek)
  116. switch (unit) {
  117. case CENTURY:
  118. case DECADE:
  119. case YEAR:
  120. case MONTH:
  121. case WEEK:
  122. d = add(d, 1, unit)
  123. d = subtract(d, 1, DAY)
  124. d.setHours(23, 59, 59, 999)
  125. break;
  126. case DAY:
  127. d.setHours(23, 59, 59, 999)
  128. break;
  129. case HOURS:
  130. case MINUTES:
  131. case SECONDS:
  132. d = add(d, 1, unit)
  133. d = subtract(d, 1, MILI)
  134. }
  135. return d
  136. }
  137. export var eq = createComparer(function(a, b){ return a === b })
  138. export var neq = createComparer(function(a, b){ return a !== b })
  139. export var gt = createComparer(function(a, b){ return a > b })
  140. export var gte = createComparer(function(a, b){ return a >= b })
  141. export var lt = createComparer(function(a, b){ return a < b })
  142. export var lte = createComparer(function(a, b){ return a <= b })
  143. export function min(){
  144. return new Date(Math.min.apply(Math, arguments))
  145. }
  146. export function max(){
  147. return new Date(Math.max.apply(Math, arguments))
  148. }
  149. export function inRange(day, min, max, unit){
  150. unit = unit || 'day'
  151. return (!min || gte(day, min, unit))
  152. && (!max || lte(day, max, unit))
  153. }
  154. export var milliseconds = createAccessor('Milliseconds')
  155. export var seconds = createAccessor('Seconds')
  156. export var minutes = createAccessor('Minutes')
  157. export var hours = createAccessor('Hours')
  158. export var day = createAccessor('Day')
  159. export var date = createAccessor('Date')
  160. export var month = createAccessor('Month')
  161. export var year = createAccessor('FullYear')
  162. export function decade(d, val) {
  163. return val === undefined
  164. ? year(startOf(d, DECADE))
  165. : add(d, val + 10, YEAR);
  166. }
  167. export function century(d, val) {
  168. return val === undefined
  169. ? year(startOf(d, CENTURY))
  170. : add(d, val + 100, YEAR);
  171. }
  172. export function weekday(d, val, firstDay) {
  173. var w = (day(d) + 7 - (firstDay || 0) ) % 7;
  174. return val === undefined
  175. ? w
  176. : add(d, val - w, DAY);
  177. }
  178. export function diff(date1, date2, unit, asFloat) {
  179. var dividend, divisor, result;
  180. switch (unit) {
  181. case MILI:
  182. case SECONDS:
  183. case MINUTES:
  184. case HOURS:
  185. case DAY:
  186. case WEEK:
  187. dividend = date2.getTime() - date1.getTime(); break;
  188. case MONTH:
  189. case YEAR:
  190. case DECADE:
  191. case CENTURY:
  192. dividend = (year(date2) - year(date1)) * 12 + month(date2) - month(date1); break;
  193. default:
  194. throw new TypeError('Invalid units: "' + unit + '"');
  195. }
  196. switch (unit) {
  197. case MILI:
  198. divisor = 1; break;
  199. case SECONDS:
  200. divisor = 1000; break;
  201. case MINUTES:
  202. divisor = 1000 * 60; break;
  203. case HOURS:
  204. divisor = 1000 * 60 * 60; break;
  205. case DAY:
  206. divisor = 1000 * 60 * 60 * 24; break;
  207. case WEEK:
  208. divisor = 1000 * 60 * 60 * 24 * 7; break;
  209. case MONTH:
  210. divisor = 1; break;
  211. case YEAR:
  212. divisor = 12; break;
  213. case DECADE:
  214. divisor = 120; break;
  215. case CENTURY:
  216. divisor = 1200; break;
  217. default:
  218. throw new TypeError('Invalid units: "' + unit + '"');
  219. }
  220. result = dividend / divisor;
  221. return asFloat ? result : Math.round(result);
  222. }
  223. function createAccessor(method){
  224. var hourLength = (function(method) {
  225. switch(method) {
  226. case 'Milliseconds':
  227. return 3600000;
  228. case 'Seconds':
  229. return 3600;
  230. case 'Minutes':
  231. return 60;
  232. case 'Hours':
  233. return 1;
  234. default:
  235. return null;
  236. }
  237. })(method);
  238. return function(d, val){
  239. if (val === undefined)
  240. return d['get' + method]()
  241. var dateOut = new Date(d)
  242. dateOut['set' + method](val)
  243. if(hourLength && dateOut['get'+method]() != val && (method === 'Hours' || val >=hourLength && (dateOut.getHours()-d.getHours()<Math.floor(val/hourLength))) ){
  244. //Skip DST hour, if it occurs
  245. dateOut['set'+method](val+hourLength);
  246. }
  247. return dateOut
  248. }
  249. }
  250. function createComparer(operator) {
  251. return function (a, b, unit) {
  252. return operator(+startOf(a, unit), +startOf(b, unit))
  253. };
  254. }