分析
首先,日期段重合主要有2种场景:
- 日期段 包含 日期段2;
- 日期段2 包含 日期段1。
以上的话翻译一下就是,
如果 日期段2 的开始日在 日期段1 的开始日之后,则可能出现 日期段1 包含 日期段2;
如果 日期段2 的开始日在 日期段1 的开始日之前,则可能出现 日期段2 包含 日期段1。
那么我们假设 日期段1 的开始日、结束日分别为A、B,日期段2 的开始日、结束日分别为X、Y,以 日期段1 为基准,先列出 日期段1 开始日 <= 日期段2 开始日的情况。
日期段1 开始日 = 日期段2 开始日:
1. 日期段2 开始日 = 日期段1 开始日
A------B
XY
X--Y
X------Y
X----------Y
日期段1 开始日 < 日期段2 开始日:
2. 日期段1 开始日 < 日期段2 开始日 < 日期段1 结束日
A------B
XY
X--Y
X----Y
X-------Y
3. 日期段2 开始日 = 日期段1 结束日
A------B
XY
X---Y
3. 日期段2 开始日 > 日期段1 结束日
A------B
XY
X---Y
接下来仍然以 日期段1 为基准,列出 日期段1 开始日 > 日期段2 的情况。
(也可以改为以 日期段2 为基准,将上面分析里的A、B和X、Y交换位置即可)
日期段1 开始日 > 日期段2 开始日:
4. 日期段2 结束日 < 日期段1 开始日
X---Y
A------B
5. 日期段2 结束日 = 日期段1 开始日
X-----Y
A------B
6. 日期段1 开始日 > 日期段2 结束日 > 日期段1 结束日
X--------Y
A------B
7. 日期段2 结束日 = 日期段1 结束日
X------------Y
A------B
8. 日期段2 结束日 > 日期段1 结束日
X---------------Y
A------B
结论
通过观察上面的分析,发现只有2个场景的段日期不重合:
- 第3种:日期段1 开始日 < 日期段2 开始日,且 日期段2 开始日 > 日期段1 结束日
- 第4种:日期段1 开始日 > 日期段2 开始日,且 日期段2 结束日 < 日期段1 开始日
那么,在这2个场景外的其他情况都判断为重复。
代码
function isDuplicateDatePeriod(currPeriod = [], otherPeriod = []) {
const [currStartDay, currEndDay] = currPeriod;
const [otherStartDay, otherEndDay] = otherPeriod;
if (!currStartDay || !currEndDay || !otherStartDay || !otherEndDay) {
// 日期不完整,认为不重复
return false;
}
const currStartTime = new Date(currStartDay).getTime();
const currEndTime = new Date(currEndDay).getTime();
const otherStartTime = new Date(otherStartDay).getTime();
const otherEndTime = new Date(otherEndDay).getTime();
if (otherStartTime > currStartTime) {
// 其他日期段开始日期大于当前日期段开始日日期,那么其他日期段开始日期小于等于当前日期段结束日则为重复
return otherStartTime <= currEndTime;
} else if (otherStartTime < currStartTime) {
// 其他日期段开始日期小于当前开始日期,那么其他日期段结束日期大于等于当前日期段开始日期则为重复
return otherEndTime >= currStartTime;
} else {
// 其他日期段开始日期=当前日期段开始日期,一定重复
return true
}
}