如何从日期列表中找到下一个生日日期并正确排序?
如何按生日(忽略年份)排序日期数组并找到下一个生日?
看起来你已经抓住了问题的核心——原排序逻辑错误地被年份干扰,而且只比较了日期的“日”部分,完全没考虑月份,才会出现1992年4月的Sam排在1991年2月的Eva前面的情况。我来帮你把这个问题理清楚,再完善下解决方案:
原代码的问题分析
你最初的排序函数存在两个关键问题:
myArray.sort(function compare(a, b) { const dateA = new Date(a.date); const dateB = new Date(b.date); return dateA.getUTCDate() - dateB.getUTCDate(); });
- 只比较“日”忽略了月份:比如2月26日和4月16日,仅比较“日”的话26>16,但实际我们需要先按月份排序;
- 未排除年份影响:完整的
Date对象包含年份,年份大的日期时间戳更大,会干扰纯生日(月+日)的排序逻辑。
你的Moment.js解决方案解析
你后来写的sortByDateNoYear函数是完全正确的方向,它专门聚焦于月份和日期的比较,彻底忽略年份:
sortByDateNoYear(adate, bdate) { let results; const lhdate = moment(adate.birthdayDate); const rhdate = moment(bdate.birthdayDate); // 优先比较月份 results = lhdate.month() > rhdate.month() ? 1 : lhdate.month() < rhdate.month() ? -1 : 0; // 月份相同时再比较日期 if (results === 0) { results = lhdate.date() > rhdate.date() ? 1 : lhdate.date() < rhdate.date() ? -1 : 0; } return results; } // 调用方式 [array].sort(this.sortByDateNoYear);
这个函数会先按月份从小到大排序,月份相同则按日期排序,排序后Eva(2月26日)会排在最前面,接着是Sam(4月16日),最后是Joe(11月25日),完全符合你忽略年份按生日排序的需求。
补充:原生JavaScript实现(无需Moment.js)
如果你不想依赖第三方库,用原生JS也能实现同样的逻辑:
function sortByBirthday(a, b) { // 解析日期字符串为Date对象 const dateA = new Date(a.date); const dateB = new Date(b.date); // 提取月份和日期 const monthA = dateA.getMonth(); const monthB = dateB.getMonth(); const dayA = dateA.getDate(); const dayB = dateB.getDate(); // 先比月份,再比日期 if (monthA !== monthB) { return monthA - monthB; } else { return dayA - dayB; } } // 调用方式 myArray.sort(sortByBirthday);
逻辑和Moment.js版本完全一致,只是用原生API完成解析和比较。
额外:找到下一个生日
排序完成后,我们可以快速定位当前日期之后的下一个生日:
// 获取当前日期的月份和日期 const today = new Date(); const currentMonth = today.getMonth(); const currentDay = today.getDate(); // 查找今年尚未到来的第一个生日 const nextBirthday = myArray.find(person => { const bdayDate = new Date(person.date); const bdayMonth = bdayDate.getMonth(); const bdayDay = bdayDate.getDate(); return bdayMonth > currentMonth || (bdayMonth === currentMonth && bdayDay >= currentDay); }); // 如果今年所有生日都已过,就取明年第一个生日(数组第一个元素) const finalNextBirthday = nextBirthday || myArray[0]; console.log("下一个生日是:", finalNextBirthday);
内容的提问来源于stack exchange,提问作者Seysay
相关产品推荐
相关产品推荐

