dayjs.js 6.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226
  1. import dayjs from 'dayjs';
  2. import weekday from 'dayjs/plugin/weekday';
  3. import localeData from 'dayjs/plugin/localeData';
  4. import weekOfYear from 'dayjs/plugin/weekOfYear';
  5. import weekYear from 'dayjs/plugin/weekYear';
  6. import quarterOfYear from 'dayjs/plugin/quarterOfYear';
  7. import advancedFormat from 'dayjs/plugin/advancedFormat';
  8. import customParseFormat from 'dayjs/plugin/customParseFormat';
  9. import { noteOnce } from '../../vc-util/warning';
  10. dayjs.extend(customParseFormat);
  11. dayjs.extend(advancedFormat);
  12. dayjs.extend(weekday);
  13. dayjs.extend(localeData);
  14. dayjs.extend(weekOfYear);
  15. dayjs.extend(weekYear);
  16. dayjs.extend(quarterOfYear);
  17. dayjs.extend((_o, c) => {
  18. // todo support Wo (ISO week)
  19. const proto = c.prototype;
  20. const oldFormat = proto.format;
  21. proto.format = function f(formatStr) {
  22. const str = (formatStr || '').replace('Wo', 'wo');
  23. return oldFormat.bind(this)(str);
  24. };
  25. });
  26. const localeMap = {
  27. // ar_EG:
  28. // az_AZ:
  29. // bg_BG:
  30. bn_BD: 'bn-bd',
  31. by_BY: 'be',
  32. // ca_ES:
  33. // cs_CZ:
  34. // da_DK:
  35. // de_DE:
  36. // el_GR:
  37. en_GB: 'en-gb',
  38. en_US: 'en',
  39. // es_ES:
  40. // et_EE:
  41. // fa_IR:
  42. // fi_FI:
  43. fr_BE: 'fr',
  44. fr_CA: 'fr-ca',
  45. // fr_FR:
  46. // ga_IE:
  47. // gl_ES:
  48. // he_IL:
  49. // hi_IN:
  50. // hr_HR:
  51. // hu_HU:
  52. hy_AM: 'hy-am',
  53. // id_ID:
  54. // is_IS:
  55. // it_IT:
  56. // ja_JP:
  57. // ka_GE:
  58. // kk_KZ:
  59. // km_KH:
  60. kmr_IQ: 'ku',
  61. // kn_IN:
  62. // ko_KR:
  63. // ku_IQ: // previous ku in antd
  64. // lt_LT:
  65. // lv_LV:
  66. // mk_MK:
  67. // ml_IN:
  68. // mn_MN:
  69. // ms_MY:
  70. // nb_NO:
  71. // ne_NP:
  72. nl_BE: 'nl-be',
  73. // nl_NL:
  74. // pl_PL:
  75. pt_BR: 'pt-br',
  76. // pt_PT:
  77. // ro_RO:
  78. // ru_RU:
  79. // sk_SK:
  80. // sl_SI:
  81. // sr_RS:
  82. // sv_SE:
  83. // ta_IN:
  84. // th_TH:
  85. // tr_TR:
  86. // uk_UA:
  87. // ur_PK:
  88. // vi_VN:
  89. zh_CN: 'zh-cn',
  90. zh_HK: 'zh-hk',
  91. zh_TW: 'zh-tw'
  92. };
  93. const parseLocale = locale => {
  94. const mapLocale = localeMap[locale];
  95. return mapLocale || locale.split('_')[0];
  96. };
  97. const parseNoMatchNotice = () => {
  98. /* istanbul ignore next */
  99. noteOnce(false, 'Not match any format. Please help to fire a issue about this.');
  100. };
  101. const advancedFormatRegex = /\[([^\]]+)]|Q|wo|ww|w|WW|W|zzz|z|gggg|GGGG|k{1,2}|S/g;
  102. function findTargetStr(val, index, segmentation) {
  103. const items = [...new Set(val.split(segmentation))];
  104. let idx = 0;
  105. for (let i = 0; i < items.length; i++) {
  106. const item = items[i];
  107. idx += item.length;
  108. if (idx > index) {
  109. return item;
  110. }
  111. idx += segmentation.length;
  112. }
  113. }
  114. const toDateWithValueFormat = (val, valueFormat) => {
  115. if (!val) return null;
  116. if (dayjs.isDayjs(val)) {
  117. return val;
  118. }
  119. const matchs = valueFormat.matchAll(advancedFormatRegex);
  120. let baseDate = dayjs(val, valueFormat);
  121. if (matchs === null) {
  122. return baseDate;
  123. }
  124. for (const match of matchs) {
  125. const origin = match[0];
  126. const index = match['index'];
  127. if (origin === 'Q') {
  128. const segmentation = val.slice(index - 1, index);
  129. const quarterStr = findTargetStr(val, index, segmentation).match(/\d+/)[0];
  130. baseDate = baseDate.quarter(parseInt(quarterStr));
  131. }
  132. if (origin.toLowerCase() === 'wo') {
  133. const segmentation = val.slice(index - 1, index);
  134. const weekStr = findTargetStr(val, index, segmentation).match(/\d+/)[0];
  135. baseDate = baseDate.week(parseInt(weekStr));
  136. }
  137. if (origin.toLowerCase() === 'ww') {
  138. baseDate = baseDate.week(parseInt(val.slice(index, index + origin.length)));
  139. }
  140. if (origin.toLowerCase() === 'w') {
  141. baseDate = baseDate.week(parseInt(val.slice(index, index + origin.length + 1)));
  142. }
  143. }
  144. return baseDate;
  145. };
  146. const generateConfig = {
  147. // get
  148. getNow: () => dayjs(),
  149. getFixedDate: string => dayjs(string, ['YYYY-M-DD', 'YYYY-MM-DD']),
  150. getEndDate: date => date.endOf('month'),
  151. getWeekDay: date => {
  152. const clone = date.locale('en');
  153. return clone.weekday() + clone.localeData().firstDayOfWeek();
  154. },
  155. getYear: date => date.year(),
  156. getMonth: date => date.month(),
  157. getDate: date => date.date(),
  158. getHour: date => date.hour(),
  159. getMinute: date => date.minute(),
  160. getSecond: date => date.second(),
  161. // set
  162. addYear: (date, diff) => date.add(diff, 'year'),
  163. addMonth: (date, diff) => date.add(diff, 'month'),
  164. addDate: (date, diff) => date.add(diff, 'day'),
  165. setYear: (date, year) => date.year(year),
  166. setMonth: (date, month) => date.month(month),
  167. setDate: (date, num) => date.date(num),
  168. setHour: (date, hour) => date.hour(hour),
  169. setMinute: (date, minute) => date.minute(minute),
  170. setSecond: (date, second) => date.second(second),
  171. // Compare
  172. isAfter: (date1, date2) => date1.isAfter(date2),
  173. isValidate: date => date.isValid(),
  174. locale: {
  175. getWeekFirstDay: locale => dayjs().locale(parseLocale(locale)).localeData().firstDayOfWeek(),
  176. getWeekFirstDate: (locale, date) => date.locale(parseLocale(locale)).weekday(0),
  177. getWeek: (locale, date) => date.locale(parseLocale(locale)).week(),
  178. getShortWeekDays: locale => dayjs().locale(parseLocale(locale)).localeData().weekdaysMin(),
  179. getShortMonths: locale => dayjs().locale(parseLocale(locale)).localeData().monthsShort(),
  180. format: (locale, date, format) => date.locale(parseLocale(locale)).format(format),
  181. parse: (locale, text, formats) => {
  182. const localeStr = parseLocale(locale);
  183. for (let i = 0; i < formats.length; i += 1) {
  184. const format = formats[i];
  185. const formatText = text;
  186. if (format.includes('wo') || format.includes('Wo')) {
  187. // parse Wo
  188. const year = formatText.split('-')[0];
  189. const weekStr = formatText.split('-')[1];
  190. const firstWeek = dayjs(year, 'YYYY').startOf('year').locale(localeStr);
  191. for (let j = 0; j <= 52; j += 1) {
  192. const nextWeek = firstWeek.add(j, 'week');
  193. if (nextWeek.format('Wo') === weekStr) {
  194. return nextWeek;
  195. }
  196. }
  197. parseNoMatchNotice();
  198. return null;
  199. }
  200. const date = dayjs(formatText, format, true).locale(localeStr);
  201. if (date.isValid()) {
  202. return date;
  203. }
  204. }
  205. if (!text) {
  206. parseNoMatchNotice();
  207. }
  208. return null;
  209. }
  210. },
  211. toDate: (value, valueFormat) => {
  212. if (Array.isArray(value)) {
  213. return value.map(val => toDateWithValueFormat(val, valueFormat));
  214. } else {
  215. return toDateWithValueFormat(value, valueFormat);
  216. }
  217. },
  218. toString: (value, valueFormat) => {
  219. if (Array.isArray(value)) {
  220. return value.map(val => dayjs.isDayjs(val) ? val.format(valueFormat) : val);
  221. } else {
  222. return dayjs.isDayjs(value) ? value.format(valueFormat) : value;
  223. }
  224. }
  225. };
  226. export default generateConfig;