c1ae537c8dbb9809d2261f1ef4dd3ee84047ba83271584d4f4a1cbb7a1005f68720d8dcf7b060151af4105d8fc53cea0dc8254b941a54342d912874120dedd 8.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282
  1. import fecha from 'element-ui/src/utils/date';
  2. import { t } from 'element-ui/src/locale';
  3. const weeks = ['sun', 'mon', 'tue', 'wed', 'thu', 'fri', 'sat'];
  4. const months = ['jan', 'feb', 'mar', 'apr', 'may', 'jun', 'jul', 'aug', 'sep', 'oct', 'nov', 'dec'];
  5. const newArray = function(start, end) {
  6. let result = [];
  7. for (let i = start; i <= end; i++) {
  8. result.push(i);
  9. }
  10. return result;
  11. };
  12. export const getI18nSettings = () => {
  13. return {
  14. dayNamesShort: weeks.map(week => t(`el.datepicker.weeks.${ week }`)),
  15. dayNames: weeks.map(week => t(`el.datepicker.weeks.${ week }`)),
  16. monthNamesShort: months.map(month => t(`el.datepicker.months.${ month }`)),
  17. monthNames: months.map((month, index) => t(`el.datepicker.month${ index + 1 }`)),
  18. amPm: ['am', 'pm']
  19. };
  20. };
  21. export const toDate = function(date) {
  22. return isDate(date) ? new Date(date) : null;
  23. };
  24. export const isDate = function(date) {
  25. if (date === null || date === undefined) return false;
  26. if (isNaN(new Date(date).getTime())) return false;
  27. if (Array.isArray(date)) return false; // deal with `new Date([ new Date() ]) -> new Date()`
  28. return true;
  29. };
  30. export const isDateObject = function(val) {
  31. return val instanceof Date;
  32. };
  33. export const formatDate = function(date, format) {
  34. date = toDate(date);
  35. if (!date) return '';
  36. return fecha.format(date, format || 'yyyy-MM-dd', getI18nSettings());
  37. };
  38. export const parseDate = function(string, format) {
  39. return fecha.parse(string, format || 'yyyy-MM-dd', getI18nSettings());
  40. };
  41. export const getDayCountOfMonth = function(year, month) {
  42. if (isNaN(+month)) return 31;
  43. return new Date(year, +month + 1, 0).getDate();
  44. };
  45. export const getDayCountOfYear = function(year) {
  46. const isLeapYear = year % 400 === 0 || (year % 100 !== 0 && year % 4 === 0);
  47. return isLeapYear ? 366 : 365;
  48. };
  49. export const getFirstDayOfMonth = function(date) {
  50. const temp = new Date(date.getTime());
  51. temp.setDate(1);
  52. return temp.getDay();
  53. };
  54. // see: https://stackoverflow.com/questions/3674539/incrementing-a-date-in-javascript
  55. // {prev, next} Date should work for Daylight Saving Time
  56. // Adding 24 * 60 * 60 * 1000 does not work in the above scenario
  57. export const prevDate = function(date, amount = 1) {
  58. return new Date(date.getFullYear(), date.getMonth(), date.getDate() - amount);
  59. };
  60. export const nextDate = function(date, amount = 1) {
  61. return new Date(date.getFullYear(), date.getMonth(), date.getDate() + amount);
  62. };
  63. export const getStartDateOfMonth = function(year, month) {
  64. const result = new Date(year, month, 1);
  65. const day = result.getDay();
  66. if (day === 0) {
  67. return prevDate(result, 7);
  68. } else {
  69. return prevDate(result, day);
  70. }
  71. };
  72. export const getWeekNumber = function(src) {
  73. if (!isDate(src)) return null;
  74. const date = new Date(src.getTime());
  75. date.setHours(0, 0, 0, 0);
  76. // Thursday in current week decides the year.
  77. date.setDate(date.getDate() + 3 - (date.getDay() + 6) % 7);
  78. // January 4 is always in week 1.
  79. const week1 = new Date(date.getFullYear(), 0, 4);
  80. // Adjust to Thursday in week 1 and count number of weeks from date to week 1.
  81. // Rounding should be fine for Daylight Saving Time. Its shift should never be more than 12 hours.
  82. return 1 + Math.round(((date.getTime() - week1.getTime()) / 86400000 - 3 + (week1.getDay() + 6) % 7) / 7);
  83. };
  84. export const getRangeHours = function(ranges) {
  85. const hours = [];
  86. let disabledHours = [];
  87. (ranges || []).forEach(range => {
  88. const value = range.map(date => date.getHours());
  89. disabledHours = disabledHours.concat(newArray(value[0], value[1]));
  90. });
  91. if (disabledHours.length) {
  92. for (let i = 0; i < 24; i++) {
  93. hours[i] = disabledHours.indexOf(i) === -1;
  94. }
  95. } else {
  96. for (let i = 0; i < 24; i++) {
  97. hours[i] = false;
  98. }
  99. }
  100. return hours;
  101. };
  102. export const getPrevMonthLastDays = (date, amount) => {
  103. if (amount <= 0) return [];
  104. const temp = new Date(date.getTime());
  105. temp.setDate(0);
  106. const lastDay = temp.getDate();
  107. return range(amount).map((_, index) => lastDay - (amount - index - 1));
  108. };
  109. export const getMonthDays = (date) => {
  110. const temp = new Date(date.getFullYear(), date.getMonth() + 1, 0);
  111. const days = temp.getDate();
  112. return range(days).map((_, index) => index + 1);
  113. };
  114. function setRangeData(arr, start, end, value) {
  115. for (let i = start; i < end; i++) {
  116. arr[i] = value;
  117. }
  118. }
  119. export const getRangeMinutes = function(ranges, hour) {
  120. const minutes = new Array(60);
  121. if (ranges.length > 0) {
  122. ranges.forEach(range => {
  123. const start = range[0];
  124. const end = range[1];
  125. const startHour = start.getHours();
  126. const startMinute = start.getMinutes();
  127. const endHour = end.getHours();
  128. const endMinute = end.getMinutes();
  129. if (startHour === hour && endHour !== hour) {
  130. setRangeData(minutes, startMinute, 60, true);
  131. } else if (startHour === hour && endHour === hour) {
  132. setRangeData(minutes, startMinute, endMinute + 1, true);
  133. } else if (startHour !== hour && endHour === hour) {
  134. setRangeData(minutes, 0, endMinute + 1, true);
  135. } else if (startHour < hour && endHour > hour) {
  136. setRangeData(minutes, 0, 60, true);
  137. }
  138. });
  139. } else {
  140. setRangeData(minutes, 0, 60, true);
  141. }
  142. return minutes;
  143. };
  144. export const range = function(n) {
  145. // see https://stackoverflow.com/questions/3746725/create-a-javascript-array-containing-1-n
  146. return Array.apply(null, {length: n}).map((_, n) => n);
  147. };
  148. export const modifyDate = function(date, y, m, d) {
  149. return new Date(y, m, d, date.getHours(), date.getMinutes(), date.getSeconds(), date.getMilliseconds());
  150. };
  151. export const modifyTime = function(date, h, m, s) {
  152. return new Date(date.getFullYear(), date.getMonth(), date.getDate(), h, m, s, date.getMilliseconds());
  153. };
  154. export const modifyWithTimeString = (date, time) => {
  155. if (date == null || !time) {
  156. return date;
  157. }
  158. time = parseDate(time, 'HH:mm:ss');
  159. return modifyTime(date, time.getHours(), time.getMinutes(), time.getSeconds());
  160. };
  161. export const clearTime = function(date) {
  162. return new Date(date.getFullYear(), date.getMonth(), date.getDate());
  163. };
  164. export const clearMilliseconds = function(date) {
  165. return new Date(date.getFullYear(), date.getMonth(), date.getDate(), date.getHours(), date.getMinutes(), date.getSeconds(), 0);
  166. };
  167. export const limitTimeRange = function(date, ranges, format = 'HH:mm:ss') {
  168. // TODO: refactory a more elegant solution
  169. if (ranges.length === 0) return date;
  170. const normalizeDate = date => fecha.parse(fecha.format(date, format), format);
  171. const ndate = normalizeDate(date);
  172. const nranges = ranges.map(range => range.map(normalizeDate));
  173. if (nranges.some(nrange => ndate >= nrange[0] && ndate <= nrange[1])) return date;
  174. let minDate = nranges[0][0];
  175. let maxDate = nranges[0][0];
  176. nranges.forEach(nrange => {
  177. minDate = new Date(Math.min(nrange[0], minDate));
  178. maxDate = new Date(Math.max(nrange[1], minDate));
  179. });
  180. const ret = ndate < minDate ? minDate : maxDate;
  181. // preserve Year/Month/Date
  182. return modifyDate(
  183. ret,
  184. date.getFullYear(),
  185. date.getMonth(),
  186. date.getDate()
  187. );
  188. };
  189. export const timeWithinRange = function(date, selectableRange, format) {
  190. const limitedDate = limitTimeRange(date, selectableRange, format);
  191. return limitedDate.getTime() === date.getTime();
  192. };
  193. export const changeYearMonthAndClampDate = function(date, year, month) {
  194. // clamp date to the number of days in `year`, `month`
  195. // eg: (2010-1-31, 2010, 2) => 2010-2-28
  196. const monthDate = Math.min(date.getDate(), getDayCountOfMonth(year, month));
  197. return modifyDate(date, year, month, monthDate);
  198. };
  199. export const prevMonth = function(date) {
  200. const year = date.getFullYear();
  201. const month = date.getMonth();
  202. return month === 0
  203. ? changeYearMonthAndClampDate(date, year - 1, 11)
  204. : changeYearMonthAndClampDate(date, year, month - 1);
  205. };
  206. export const nextMonth = function(date) {
  207. const year = date.getFullYear();
  208. const month = date.getMonth();
  209. return month === 11
  210. ? changeYearMonthAndClampDate(date, year + 1, 0)
  211. : changeYearMonthAndClampDate(date, year, month + 1);
  212. };
  213. export const prevYear = function(date, amount = 1) {
  214. const year = date.getFullYear();
  215. const month = date.getMonth();
  216. return changeYearMonthAndClampDate(date, year - amount, month);
  217. };
  218. export const nextYear = function(date, amount = 1) {
  219. const year = date.getFullYear();
  220. const month = date.getMonth();
  221. return changeYearMonthAndClampDate(date, year + amount, month);
  222. };
  223. export const extractDateFormat = function(format) {
  224. return format
  225. .replace(/\W?m{1,2}|\W?ZZ/g, '')
  226. .replace(/\W?h{1,2}|\W?s{1,3}|\W?a/gi, '')
  227. .trim();
  228. };
  229. export const extractTimeFormat = function(format) {
  230. return format
  231. .replace(/\W?D{1,2}|\W?Do|\W?d{1,4}|\W?M{1,4}|\W?y{2,4}/g, '')
  232. .trim();
  233. };
  234. export const validateRangeInOneMonth = function(start, end) {
  235. return (start.getMonth() === end.getMonth()) && (start.getFullYear() === end.getFullYear());
  236. };