zxz-util.js 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525
  1. class Calendar {
  2. constructor({
  3. selected,
  4. startDate,
  5. endDate,
  6. range,
  7. isMonday
  8. } = {}) {
  9. // 当前日期
  10. this.date = this.getDateObj(new Date()) // 当前初入日期
  11. // 打点信息
  12. this.selected = selected || [];
  13. // 起始时间
  14. this.startDate = startDate
  15. // 终止时间
  16. this.endDate = endDate
  17. // 是否范围选择
  18. this.range = range
  19. // 是否周一开始
  20. this.isMonday = isMonday
  21. // 多选状态
  22. this.cleanMultipleStatus()
  23. // 每周日期
  24. this.weeks = {}
  25. this.lastHover = false
  26. }
  27. /**
  28. * 设置日期
  29. * @param {Object} date
  30. */
  31. setDate(date) {
  32. const selectDate = this.getDateObj(date)
  33. this.getWeeks(selectDate.fullDate)
  34. }
  35. /**
  36. * 清理多选状态
  37. */
  38. cleanMultipleStatus() {
  39. this.multipleStatus = {
  40. before: '',
  41. after: '',
  42. data: []
  43. }
  44. }
  45. setStartDate(startDate) {
  46. this.startDate = startDate
  47. }
  48. setEndDate(endDate) {
  49. this.endDate = endDate
  50. }
  51. getPreMonthObj(date) {
  52. date = fixIosDateFormat(date)
  53. date = new Date(date)
  54. const oldMonth = date.getMonth()
  55. date.setMonth(oldMonth - 1)
  56. const newMonth = date.getMonth()
  57. if (oldMonth !== 0 && newMonth - oldMonth === 0) {
  58. date.setMonth(newMonth - 1)
  59. }
  60. return this.getDateObj(date)
  61. }
  62. getNextMonthObj(date) {
  63. date = fixIosDateFormat(date)
  64. date = new Date(date)
  65. const oldMonth = date.getMonth()
  66. date.setMonth(oldMonth + 1)
  67. const newMonth = date.getMonth()
  68. if (newMonth - oldMonth > 1) {
  69. date.setMonth(newMonth - 1)
  70. }
  71. return this.getDateObj(date)
  72. }
  73. /**
  74. * 获取指定格式Date对象
  75. */
  76. getDateObj(date) {
  77. date = fixIosDateFormat(date)
  78. date = new Date(date)
  79. return {
  80. fullDate: getDate(date),
  81. year: date.getFullYear(),
  82. month: addZero(date.getMonth() + 1),
  83. date: addZero(date.getDate()),
  84. day: date.getDay()
  85. }
  86. }
  87. /**
  88. * 获取上一个月日期集合
  89. */
  90. getPreMonthDays(amount, dateObj) {
  91. const result = []
  92. for (let i = amount - 1; i >= 0; i--) {
  93. const month = dateObj.month - 1
  94. result.push({
  95. date: new Date(dateObj.year, month, -i).getDate(),
  96. month,
  97. disable: true
  98. })
  99. }
  100. return result
  101. }
  102. /**
  103. * 获取本月日期集合
  104. */
  105. getCurrentMonthDays(amount, dateObj) {
  106. const result = []
  107. const fullDate = this.date.fullDate
  108. for (let i = 1; i <= amount; i++) {
  109. const currentDate = `${dateObj.year}-${dateObj.month}-${addZero(i)}`
  110. const isToday = fullDate === currentDate
  111. // 获取打点信息
  112. const info = this.selected && this.selected.find((item) => {
  113. if (this.dateEqual(currentDate, item.date)) {
  114. return item
  115. }
  116. })
  117. // 日期禁用
  118. let disableBefore = true
  119. let disableAfter = true
  120. if (this.startDate) {
  121. disableBefore = dateCompare(this.startDate, currentDate)
  122. }
  123. if (this.endDate) {
  124. disableAfter = dateCompare(currentDate, this.endDate)
  125. }
  126. let multiples = this.multipleStatus.data
  127. let multiplesStatus = -1
  128. if (this.range && multiples) {
  129. multiplesStatus = multiples.findIndex((item) => {
  130. return this.dateEqual(item, currentDate)
  131. })
  132. }
  133. const checked = multiplesStatus !== -1
  134. result.push({
  135. fullDate: currentDate,
  136. year: dateObj.year,
  137. date: i,
  138. multiple: this.range ? checked : false,
  139. beforeMultiple: this.isLogicBefore(currentDate, this.multipleStatus.before, this
  140. .multipleStatus.after),
  141. afterMultiple: this.isLogicAfter(currentDate, this.multipleStatus.before, this
  142. .multipleStatus.after),
  143. month: dateObj.month,
  144. disable: (this.startDate && !dateCompare(this.startDate, currentDate)) || (this.endDate && !
  145. dateCompare(currentDate, this.endDate)),
  146. isToday,
  147. userChecked: false,
  148. extraInfo: info
  149. })
  150. }
  151. return result
  152. }
  153. /**
  154. * 获取下一个月日期集合
  155. */
  156. _getNextMonthDays(amount, dateObj) {
  157. const result = []
  158. const month = dateObj.month + 1
  159. for (let i = 1; i <= amount; i++) {
  160. result.push({
  161. date: i,
  162. month,
  163. disable: true
  164. })
  165. }
  166. return result
  167. }
  168. /**
  169. * 获取当前日期详情
  170. * @param {Object} date
  171. */
  172. getInfo(date) {
  173. if (!date) {
  174. date = new Date()
  175. }
  176. return this.calendar.find(item => item.fullDate === this.getDateObj(date).fullDate)
  177. }
  178. /**
  179. * 比较时间是否相等
  180. */
  181. dateEqual(before, after) {
  182. before = new Date(fixIosDateFormat(before))
  183. after = new Date(fixIosDateFormat(after))
  184. return before.valueOf() === after.valueOf()
  185. }
  186. /**
  187. * 比较真实起始日期
  188. */
  189. isLogicBefore(currentDate, before, after) {
  190. let logicBefore = before
  191. if (before && after) {
  192. logicBefore = dateCompare(before, after) ? before : after
  193. }
  194. return this.dateEqual(logicBefore, currentDate)
  195. }
  196. isLogicAfter(currentDate, before, after) {
  197. let logicAfter = after
  198. if (before && after) {
  199. logicAfter = dateCompare(before, after) ? after : before
  200. }
  201. return this.dateEqual(logicAfter, currentDate)
  202. }
  203. /**
  204. * 获取日期范围内所有日期
  205. * @param {Object} begin
  206. * @param {Object} end
  207. */
  208. geDateAll(begin, end) {
  209. var arr = []
  210. var ab = begin.split('-')
  211. var ae = end.split('-')
  212. var db = new Date()
  213. db.setFullYear(ab[0], ab[1] - 1, ab[2])
  214. var de = new Date()
  215. de.setFullYear(ae[0], ae[1] - 1, ae[2])
  216. var unixDb = db.getTime() - 24 * 60 * 60 * 1000
  217. var unixDe = de.getTime() - 24 * 60 * 60 * 1000
  218. for (var k = unixDb; k <= unixDe;) {
  219. k = k + 24 * 60 * 60 * 1000
  220. arr.push(this.getDateObj(new Date(parseInt(k))).fullDate)
  221. }
  222. return arr
  223. }
  224. /**
  225. * 获取多选状态
  226. */
  227. setMultiple(fullDate) {
  228. if (!this.range) return
  229. let {
  230. before,
  231. after
  232. } = this.multipleStatus
  233. if (before && after) {
  234. if (!this.lastHover) {
  235. this.lastHover = true
  236. return
  237. }
  238. this.multipleStatus.before = fullDate
  239. this.multipleStatus.after = ''
  240. this.multipleStatus.data = []
  241. this.multipleStatus.fulldate = ''
  242. this.lastHover = false
  243. } else {
  244. if (!before) {
  245. this.multipleStatus.before = fullDate
  246. this.lastHover = false
  247. } else {
  248. this.multipleStatus.after = fullDate
  249. if (dateCompare(this.multipleStatus.before, this.multipleStatus.after)) {
  250. this.multipleStatus.data = this.geDateAll(this.multipleStatus.before, this.multipleStatus
  251. .after);
  252. } else {
  253. this.multipleStatus.data = this.geDateAll(this.multipleStatus.after, this.multipleStatus
  254. .before);
  255. }
  256. this.lastHover = true
  257. }
  258. }
  259. this.getWeeks(fullDate)
  260. }
  261. /**
  262. * 鼠标 hover 更新多选状态
  263. */
  264. setHoverMultiple(fullDate) {
  265. if (!this.range || this.lastHover) return
  266. const {
  267. before
  268. } = this.multipleStatus
  269. if (!before) {
  270. this.multipleStatus.before = fullDate
  271. } else {
  272. this.multipleStatus.after = fullDate
  273. if (dateCompare(this.multipleStatus.before, this.multipleStatus.after)) {
  274. this.multipleStatus.data = this.geDateAll(this.multipleStatus.before, this.multipleStatus.after);
  275. } else {
  276. this.multipleStatus.data = this.geDateAll(this.multipleStatus.after, this.multipleStatus.before);
  277. }
  278. }
  279. this.getWeeks(fullDate)
  280. }
  281. /**
  282. * 更新默认值多选状态
  283. */
  284. setDefaultMultiple(before, after) {
  285. this.multipleStatus.before = before
  286. this.multipleStatus.after = after
  287. if (before && after) {
  288. if (dateCompare(before, after)) {
  289. this.multipleStatus.data = this.geDateAll(before, after);
  290. this.getWeeks(after)
  291. } else {
  292. this.multipleStatus.data = this.geDateAll(after, before);
  293. this.getWeeks(before)
  294. }
  295. }
  296. }
  297. /**
  298. * 获取每周数据
  299. * @param {Object} dateData
  300. */
  301. getWeeks(dateData) {
  302. const {
  303. year,
  304. month,
  305. } = this.getDateObj(dateData)
  306. let num = 1
  307. if (this.isMonday) {
  308. num = 0
  309. }
  310. const preMonthDayAmount = new Date(year, month - 1, num).getDay()
  311. const preMonthDays = this.getPreMonthDays(preMonthDayAmount, this.getDateObj(dateData))
  312. const currentMonthDayAmount = new Date(year, month, 0).getDate()
  313. const currentMonthDays = this.getCurrentMonthDays(currentMonthDayAmount, this.getDateObj(dateData))
  314. const nextMonthDayAmount = 42 - preMonthDayAmount - currentMonthDayAmount
  315. const nextMonthDays = this._getNextMonthDays(nextMonthDayAmount, this.getDateObj(dateData))
  316. const calendarDays = [...preMonthDays, ...currentMonthDays, ...nextMonthDays]
  317. const weeks = new Array(6)
  318. for (let i = 0; i < calendarDays.length; i++) {
  319. const index = Math.floor(i / 7)
  320. if (!weeks[index]) {
  321. weeks[index] = new Array(7)
  322. }
  323. weeks[index][i % 7] = calendarDays[i]
  324. }
  325. this.calendar = calendarDays
  326. this.weeks = weeks
  327. }
  328. }
  329. function getDateTime(date, hideSecond) {
  330. return `${getDate(date)} ${getTime(date, hideSecond)}`
  331. }
  332. function getDate(date) {
  333. date = fixIosDateFormat(date)
  334. date = new Date(date)
  335. const year = date.getFullYear()
  336. const month = date.getMonth() + 1
  337. const day = date.getDate()
  338. return `${year}-${addZero(month)}-${addZero(day)}`
  339. }
  340. function getTime(date, hideSecond) {
  341. date = fixIosDateFormat(date)
  342. date = new Date(date)
  343. const hour = date.getHours()
  344. const minute = date.getMinutes()
  345. const second = date.getSeconds()
  346. return hideSecond ? `${addZero(hour)}:${addZero(minute)}` : `${addZero(hour)}:${addZero(minute)}:${addZero(second)}`
  347. }
  348. function addZero(num) {
  349. if (num < 10) {
  350. num = `0${num}`
  351. }
  352. return num
  353. }
  354. function getDefaultSecond(hideSecond) {
  355. return hideSecond ? '00:00' : '00:00:00'
  356. }
  357. function dateCompare(startDate, endDate) {
  358. startDate = new Date(fixIosDateFormat(startDate))
  359. endDate = new Date(fixIosDateFormat(endDate))
  360. return startDate <= endDate
  361. }
  362. function checkDate(date) {
  363. const dateReg = /((19|20)\d{2})(-|\/)\d{1,2}(-|\/)\d{1,2}/g
  364. return date.match(dateReg)
  365. }
  366. const dateTimeReg = /^\d{4}-(0?[1-9]|1[012])-(0?[1-9]|[12][0-9]|3[01])( [0-5]?[0-9]:[0-5]?[0-9]:[0-5]?[0-9])?$/
  367. function fixIosDateFormat(value) {
  368. if (typeof value === 'string' && dateTimeReg.test(value)) {
  369. value = value.replace(/-/g, '/')
  370. }
  371. return value
  372. }
  373. // 页面初始时获取当前是本年第几周
  374. function getYearWeek(a, b, c) {
  375. //a为年 b为月 c为日
  376. /*
  377. date1是当前日期
  378. date2是当年第一天
  379. d是当前日期是今年第多少天
  380. 用d + 当前年的第一天的周差距的和在除以7就是本年第几周
  381. */
  382. var date1 = new Date(a, parseInt(b) - 1, c),
  383. date2 = new Date(a, 0, 1),
  384. d = Math.round((date1.valueOf() - date2.valueOf()) / 86400000);
  385. return Math.ceil((d + (date2.getDay() + 1 - 1)) / 7);
  386. }
  387. // 第n年的第n周,获取开始和结束时间 (星期一为一周的开始)
  388. function week_date(weekstr) {
  389. let year = weekstr.split("-")[0];
  390. let week = weekstr.split("-")[1];
  391. const date = new Date(year, 0, 1);
  392. const dayOfWeek = date.getDay();
  393. const difference = 1 - dayOfWeek;
  394. const firstWeekStart = new Date(year, 0, 1 + difference + (week - 1) * 7);
  395. const firstWeekEnd = new Date(year, 0, 1 + difference + (week - 1) * 7 + 6);
  396. console.log([
  397. convertDateFormat(firstWeekStart.toLocaleDateString()),
  398. convertDateFormat(firstWeekEnd.toLocaleDateString())
  399. ]);
  400. function convertDateFormat(dateString) {
  401. const parts = dateString.split('/');
  402. const year = parts[0];
  403. const month = parseInt(parts[1], 10).toString().padStart(2, '0');
  404. const day = parseInt(parts[2], 10).toString().padStart(2, '0');
  405. return `${year}-${month}-${day}`;
  406. }
  407. return [
  408. convertDateFormat(firstWeekStart.toLocaleDateString()),
  409. convertDateFormat(firstWeekEnd.toLocaleDateString())
  410. ];
  411. // 此年1号是星期几
  412. // console.log('调用时传的',year,weekNo);
  413. let oneday = new Date(year + "-01-01").getDay(); //0-6
  414. // console.log(oneday);
  415. // 方便计算,当为星期天时为7
  416. if (oneday == 0) {
  417. oneday = 7;
  418. }
  419. let one_fistday;
  420. let one_lastday;
  421. // 如果1号刚好是星期一
  422. if (oneday == 1) {
  423. one_fistday = year + "-01-01";
  424. one_lastday = year + "-01-07";
  425. } else {
  426. let jj = 8 - oneday;
  427. one_fistday =
  428. year -
  429. 1 +
  430. "-12-" +
  431. (31 - oneday + 2 > 9 ? 31 - oneday + 2 : "0" + (31 - oneday + 2));
  432. one_lastday = year + "-01-" + (jj > 9 ? jj : "0" + jj);
  433. }
  434. let fistday;
  435. let lastday;
  436. // 如果刚好是第一周
  437. if (weekNo == 1) {
  438. // 在原文档进行了修改
  439. fistday = addDate(one_fistday, 7);
  440. lastday = addDate(one_lastday, 7);
  441. } else {
  442. // 在原文档进行了修改
  443. fistday = addDate(one_lastday, (weekNo - 1) * 7 + 1);
  444. lastday = addDate(one_lastday, weekNo * 7);
  445. }
  446. return [fistday, lastday];
  447. }
  448. //日期加减法 date参数为计算开始的日期,days为需要加的天数
  449. //格式:addDate('2017-1-11',20)
  450. function addDate(date, days) {
  451. var d = new Date(date);
  452. d.setDate(d.getDate() + days);
  453. var m = d.getMonth() + 1;
  454. return (
  455. d.getFullYear() +
  456. "-" +
  457. (m > 9 ? m : "0" + m) +
  458. "-" +
  459. (d.getDate() > 9 ? d.getDate() : "0" + d.getDate())
  460. );
  461. }
  462. export {
  463. Calendar,
  464. getDateTime,
  465. getDate,
  466. getTime,
  467. addZero,
  468. getDefaultSecond,
  469. dateCompare,
  470. checkDate,
  471. fixIosDateFormat,
  472. getYearWeek,
  473. week_date
  474. }