Installation and use of leave-days-Calculator
The installation
$ npm install leave-days-calculator
Copy the code
The introduction of
import leaveDaysCalculator form 'leave-days-calculator'
Copy the code
use
const start = 'the 2020-06-22 in the morning'
const end = 'the 2020-06-24 in the afternoon
let leaveDays = leaveDaysCalculator(start, end) / / 3
Copy the code
The time format can only be YYYY-MM-DD am/PM
If you like it and can help you start it, github.
Demand background
Since I made the small program field punching requirement, I continued to develop the approval process for leave. When DEALING with the leave form, there was a display of the duration of leave. When the user selects the start time and end time of the leave, it can automatically calculate the duration of the leave, which sounds routine. But, ha, ha, ha, all leave product requirements in accordance with the along while, please, such as:
Leave starts on the morning of June 1 and ends on the morning of June 2. It is not as simple as the end time minus the start time. Morning to morning this situation, a long time. 😂 😂 😂
So the question is, how to accurately calculate the duration of leave?
The solution
Finally, the first scheme was adopted
Solution a:
Based on current leave and non-current leave,
For the day off:
- From the morning of the day to the morning of the day, the duration of leave is 0.5d;
- From the morning of the day to the afternoon of the day, the duration of leave is 1.0d;
- Start time of the day afternoon – end time of the day morning, error warning processing;
- Start time of the day afternoon – end time of the day afternoon, leave time 0.5d;
If it is calculated on the next day: End time – Start time = gap
- End time am, start time am, Gap + 0.5
- End time am, start time PM, Gap + 1
- End time afternoon, start time morning, gap + 0
- End time afternoon, start time afternoon, gap + 0.5
The core of this program is the need to accurately calculate the gap, can use third-party tools to deal with. From the point of calculation, the workload is relatively small.
My master may really look down, I wrote a push of redundant code, write a version for me, after fine-tuning the scheme a code is as follows:
const getLeaveDays = (start, end) = > {
const [times, tags] = start.split(' ')
const [timet, tagt] = end.split(' ')
const startStr = +new Date(... times.split(The '-'))
const endStr = +new Date(... timet.split(The '-'))
const timeDiff1 = tagt === tags ? 0.5 : {'morning': 'error'.'afternoon': 1 }[tagt] / / in the day
const timeDiff2 = tagt === tags ? 0.5 : {'morning': 0.'afternoon': 1 }[tagt] / / the next day
if(startStr > endStr) {
return 'error'
}
else if(timet === times) {
return timeDiff1
}
else {
return (endStr - startStr) / (60 * 60 * 24 * 1000) + timeDiff2
}
}
Copy the code
Scheme 2:
Pure manual calculation, according to the same day on the afternoon, next day on the afternoon, every other month on the afternoon, every other year on the afternoon of manual calculation of leave. The development time of this scheme is relatively long, and I choose the scheme when the development cycle is relatively rich, because I still want to know the specific calculation. Find something to do for yourself, add some fun to the boring coding.
Manually implement a leave duration calculator
The format based on the start time and end time is YYYY-MM-DD am/PM.
Figure 1: Flow chart
There are four calculation rules:
- The duration of leave on the same day of the same month in the same year shall be calculated
- The duration of leave on other days in the same month of the same year shall be calculated
- The duration of leave in a year other than the same month shall be calculated
- The duration of leave not in the same year shall be calculated
Some basic utility functions are required, such as:
- Is it a leap year
- The number of days in each month of a year
- To 0 function
- Add 0 function
Business common approach:
- Start time, year month day
- End time, month is
- Calculation method of the number of days off on the same day
- Calculation method of the number of days of leave in the next day
- The total number of days in the beginning month, the calculation method of the number of days for leave in the beginning month (a function only used in a month or a year)
- Calculation method for days of leave in the end month (a function only used in a month or year)
- Intermediate month day accumulator
- The number of days of leave in the beginning year: the number of days remaining in the beginning month + the number of days remaining in the beginning month
- Number of days of leave in the end year: number of days in the end month + number of days in the month before the end month
- Day accumulator for intermediate years
The following is the time for leave calculator source, for reference only.
/** * @Authors youxiaoxiao ([email protected]) * @Date: 2020-06-1 * @Last Modified by: Leave duration calculator :(calculate leave duration by (start time + end time) */
/** * is a leap year * @param {*} year */
function isLeapYear (year) {
return year % 100! = =0 && year % 4= = =0 || year % 400= = =0
}
/** * Obtain the number of days in a month * @param {*} year * @param {*} month */
function getMaxDay (year, month) {
year = parseFloat(year)
month = parseFloat(month)
if (month === 2) {
return isLeapYear(year) ? 29 : 28
}
return [4.6.9.11].indexOf(month) >= 0 ? 30 : 31
}
/ / to zero
function trimZero (val) {
val = String(val)
val = val ? parseFloat(val.replace(/^0+/g.' ')) : ' '
val = val || 0
val = val + ' '
return val
}
/** * leave on the same day */
function sameDayLeave(startNoon, endNoon) {
let leaveDays = 0
if (startNoon === endNoon) {
leaveDays = 0.5
}
else if (startNoon === 'morning' && endNoon === 'afternoon') {
leaveDays = 1
}
else if (startNoon === 'afternoon' && endNoon === 'morning') {
console.log('You have chosen the wrong time')}return leaveDays
}
/** ** leave the next day */
function nextDayLeave(startDay, endDay, startNoon, endNoon) {
let leaveDays = 0
if (startNoon === 'morning' && endNoon === 'morning') {
leaveDays = endDay - startDay + 0.5
}
else if (startNoon === 'morning' && endNoon === 'afternoon') {
leaveDays = endDay - startDay + 1
}
else if (startNoon === 'afternoon' && endNoon === 'morning') {
leaveDays = endDay - startDay
}
else if (startNoon === 'afternoon' && endNoon === 'afternoon') {
leaveDays = endDay - startDay + 0.5
}
return leaveDays
}
/ * * * start off days across the month, the month will not use the function of * /
function startMonthLeaveDays (startMonthAllDays, startDay, startNoon) {
let startMonthLeave = 0
if (startNoon === 'morning') {
startMonthLeave = Number(startMonthAllDays) - Number(startDay) + 1
} else if (startNoon === 'afternoon') {
startMonthLeave = Number(startMonthAllDays) - Number(startDay) + 0.5
}
return Number(startMonthLeave)
}
/ * * * for leave days across the month end of month, will not use the function of * /
function endMonthLeaveDays(endDay, endNoon) {
let endLeaveDays = 0
if (endNoon === 'morning') {
endLeaveDays = endDay - 0.5
} else if (endNoon === 'afternoon') {
endLeaveDays = endDay
}
return Number(endLeaveDays)
}
* @param {*} start [supported: yyyY-MM-DD n] * @param {*} end [supported: YYYY-MM-DD n] */ Calculates the leave duration by the start time and end time
export default (start, end) => {
if(! start || ! end)return 0
const startArr = start.split(' ') // Start time
const endArr = end.split(' ') // End time
const startDate = startArr[0] // Start date
const endDate = endArr[0] // End date
const startDateArr = startDate.split(The '-') // Start date is aggregated
const endDateArr = endDate.split(The '-') // The end date is grouped
const startYear = startDateArr[0] // Start date: year
const startMonth = startDateArr[1] // Start date: month
const startDay = startDateArr[2] // Start date: day
const startNoon = startArr[1] // Start time in the early afternoon
const endYear = endDateArr[0] // End date: year
const endMonth = endDateArr[1] // End date: Month
const endDay = endDateArr[2] // End date: date
const endNoon = endArr[1] // End time in the early afternoon
// Total number of days in the starting month
const startMonthAllDays = getMaxDay(startYear, startMonth)
/** * The number of days of leave in the middle month is calculated */
function centerMonthsLeave() {
// Add the number of days in the middle month
let leaveDays = 0
let monthArr = [] // Month array
for(let i = Number(trimZero(startMonth)); i <= Number(trimZero(endMonth)); i++) {
monthArr.push(i)
}
let everyMonthDays = 0
if (monthArr.length > 2) {
monthArr.pop()
monthArr.shift()
monthArr.forEach(month= > {
everyMonthDays = Number(everyMonthDays) + Number(getMaxDay(startYear, month))
})
}
return (Number(leaveDays) + Number(everyMonthDays)).toFixed(1)}/** * Start month and end month leave days leave in adjacent months, or leave across months */
function startEndMonthNext() {
// Calculate the days of leave in the beginning month
let startLeaveDays = startMonthLeaveDays(startMonthAllDays, startDay, startNoon)
// End the month of leave days calculation
let endLeaveDays = endMonthLeaveDays(endDay, endNoon)
// Days add up
return Number(startLeaveDays) + Number(endLeaveDays) || 0
}
/** * The number of days of leave in the beginning year */
function startYearLeaveDays () {
// Start month count
let startMonthDays = startMonthLeaveDays(startMonthAllDays, startDay, startNoon)
// Days of remaining months
let otherMonthDays = 0
for(let i = Number(trimZero(startMonth)) + 1; i <= 12; i++) {
otherMonthDays = Number(otherMonthDays) + Number(getMaxDay(startYear, i))
}
return Number(startMonthDays) + Number(otherMonthDays) || 0
}
/** * The number of days of leave at the end of the year */
function endYearLeaveDays() {
let endYearDays = 0
// End the month count
let endLeaveDays = endMonthLeaveDays(endDay, endNoon)
// Add up the previous months
for(let i = 1; i < trimZero(endMonth); i++) {
endYearDays = Number(endYearDays) + Number(getMaxDay(endYear, i))
}
return Number(endYearDays) + Number(endLeaveDays)
}
/** ** New Year, the middle year of the holiday calculated */
function centerYearsLeaveDays () {
let centerYear = 0
if(endYear - startYear > 1) {
let centerYears = []
for(let startYear; startYear < endYear; startYear++) {
centerYears.push(startYear)
}
centerYears.pop()
centerYears.shift()
centerYears.forEach(year= > {
for(let month = 1; month <=12; month++) {
centerYear = centerYear + getMaxDay(year, month)
}
})
}
return centerYear
}
// Days of absence
let leaveAllDays = 0
// Whether the same year
if (startYear === endYear) {
// Is it the same month
if (startMonth === endMonth) {
// The same day
if (startDay === endDay) {
leaveAllDays = sameDayLeave(startNoon, endNoon)
// Take leave on alternate days in the same year and month
} else if (startDay < endDay) {
leaveAllDays = nextDayLeave(startDay, endDay, startNoon, endNoon)
} else {
console.log('The end time is on the wrong day')}The same year is not the same month
} else if (startMonth < endMonth) {
// In the case of two consecutive months, the sum of the remaining days in the beginning month and the days of leave in the end month
let startEndMonthLeaveDays = startEndMonthNext()
// The number of days of leave in the middle month
let centerMonthsDays = centerMonthsLeave()
// Total days of leave
leaveAllDays = Number(startEndMonthLeaveDays) + Number(centerMonthsDays)
} else {
console.log('Ending in the wrong month')}// Not the same year
} else if (startYear < endYear) {
// The number of days of leave in the beginning year is calculated as the number of days remaining in the beginning month + the number of days remaining in the beginning month
let startYearDays = startYearLeaveDays()
// Number of days of leave at the end of the year: number of days in the end month + number of days in the month before the end month
let endYearDays = endYearLeaveDays()
// The number of days in the middle year
let centerYear = centerYearsLeaveDays()
// Total number of days off
leaveAllDays = Number(startYearDays) + Number(endYearDays) + Number(centerYear)
} else {
console.log('Ended in the wrong year')}// console.log(leaveAllDays)s
return leaveAllDays
}
Copy the code
A leave time calculator on the development of the end, in fact, plan 1 more trouble, plan 2 to achieve, there are many points can be optimized. The final packaged leave duration calculator NPM package is leave-days-calculator.
If you have other solutions or optimization implementation, feel free to leave a comment below.