background

The project needs a countdown function, which can calculate the time difference from today according to the selected date. There are a variety of countdown templates, roughly divided into year, month, day, hour, minute, second and individual days. At the beginning, I also found several methods on the Internet, but either they did not match the requirements of the project, or the calculation results were not accurate, so I wrote one myself and shared it with you in this article.

implementation

Calculation conditions

The calculation of the difference between year and month is the comparison date. For example, the difference between February 1 0 minute 0 second and March 1 0 minute 0 second is one month, regardless of whether the year is a leap year or a non-leap year, regardless of how many days February actually has. Less than 1 month (calculated minute and second) is considered as 0 months. Same thing with years.

The two methods

Reference the moment.js library implementation

Moment.js is a common JS library for time processing, and diff and Subtract methods are used to greatly simplify the task. This can be seen in comparison to the native method.

@param endTime {String,Date} - countdown endTime * @param maxUnit {String} - [maxUnit = "year"] maximum unit * @param startTime {String,Date} - countdown startTime, */ function countDownTime(endTime, maxUnit = "year", startTime) { let aUnitArr = ["year", "month", "day", "hour", "minute", "second"] let iMaxIndex = aUnitArr.indexOf(maxUnit); let end = moment(endTime); let start = moment(startTime); Let result = {} if (start-end > 0) {throw new Error(" start time cannot be later than end time ") aUnitArr.filter((item, index) => index >= iMaxIndex) result[maxUnit] = end.diff(start, maxUnit); if (aUnitArr.length > 1) { aUnitArr.reduce((previous, End = end. Subtract (result[previous], previous); result[current] = end.diff(start, current); return current }); } return result };Copy the code

Native JS implementation

function countDownTime2(endTime, maxUnit = "year", startTime) { let end = new Date(endTime); let start = startTime ? new Date(startTime) : new Date(); If (start-end > 0) {throw new Error(" start time cannot be later than end time ")} let aUnitArr = [{value: "second", interval: 60, secNum: }, {value: "minute", interval: 60, secNum: 60}, {value: "hour", interval: 24, secNum: 60 * 60 }, { value: "day", secNum: 60 * 60 * 24 }, { value: "month", interval: 12 }, { value: "year", }, ] let endList = getTimeList(end); let startList = getTimeList(start); const iMaxIndex = aUnitArr.findIndex(item => maxUnit === item.value); // Filter when the maximum unit is day, minute and second. If (iMaxIndex > -1 && iMaxIndex < 4) {aUnitArr = aunitarr. filter((item, index) => index <= iMaxIndex); } let result = {}; aUnitArr.forEach((item, index) => { if (index === iMaxIndex && iMaxIndex < 4) { result[item.value] = Math.floor((end - start) / item.secNum / 1000); return } if (endList[index] - startList[index] >= 0) { result[item.value] = endList[index] - startList[index]; } else { endList[index + 1]--; result[item.value] = item.value === "day" ? countDiffDays(start, startList[index], endList[index]) : endList[index] + item.interval - startList[index]; If (maxUnit === "month") {result.month += result.year * 12 delete result.year} return result; if (maxUnit === "month") {result.month += result.year * 12 delete result.year} return result; } function getTimeList(t) { return [t.getSeconds(), t.getMinutes(), t.getHours(), t.getDate(), t.getMonth() + 1, t.getFullYear()]; } // Calculate the date difference. Function countDiffDays(time, startDay, endDay) {let curDate = new Date(time); let curMonth = curDate.getMonth(); */ curdate.setDate (1) curdate.setMonth (curMonth + 1); */ Curdate.setMonth (curMonth + 1); curDate.setDate(0); // Set the date to the last day of the previous month let restDays = curdate.getDate () -startDay; return restDays + endDay; };Copy the code

conclusion

Native JS is more troublesome to write, and there is no good idea to optimize temporarily. If you find any mistakes or better ideas, please point out.