老忘亲友生日,写了个纪念日管家,首页直接看还剩几天
【摘要】 录入亲友生日和纪念日,自动算出"下一个"生日落在哪年、距离今天还有多少天,按临近程度排序展示,临近的标红提醒。
手机里零散记着几个日期,没人提醒的时候根本想不起来翻翻亲人朋友的生日。我就做了个网页小工具:把家里人、朋友的生日和各类纪念日一次性录进去,打开首页就按"还剩几天"排好序,七天内的标红。哪天随手点开看一眼,该买礼物的不会再漏。
一、算"下一个生日"落在哪一年
生日只有月日,每年都有。难点是:如果今年的生日已经过了,那该倒计时的是明年的。先判断今年这一场过没过:
function nextOccurrence(month, day) {
const now = new Date();
let y = now.getFullYear();
const thisYear = new Date(y, month - 1, day);
if (thisYear < new Date(now.getFullYear(), now.getMonth(), now.getDate())) {
y += 1; // 今年这场已过,看明年
}
return new Date(y, month - 1, day);
}
用 month - 1 是因为 JS 的月份从 0 开始,这是最容易写错的地方。比较时拿"今天零点"去比,避免当前时间下午导致边界抖动。
二、剩余天数怎么算
两个日期相减得到毫秒,除以一天的毫秒数再取整:
function daysLeft(target) {
const ms = target - new Date();
return Math.ceil(ms / 86400000);
}
// 录入一条记录
const people = [
{ name: '老妈', month: 5, day: 18, type: '生日' },
{ name: '结婚', month: 10, day: 1, type: '纪念日' },
];
people.forEach(p => p.left = daysLeft(nextOccurrence(p.month, p.day)));
people.sort((a, b) => a.left - b.left); // 最近的开头
Math.ceil 而不是 floor,是因为"差 5 小时也算剩 1 天",符合人话习惯。排完序最近的排最前,打开页面第一眼就是最该操心的那个。
三、存本地并给出临近提醒
记录写进 localStorage,刷新不丢;渲染时给剩余天数小的行加个红色样式:
localStorage.setItem('anniv', JSON.stringify(people));
// 渲染
const cls = p.left <= 7 ? 'urgent' : '';
list.innerHTML = people.map(p =>
`<li class="${cls}">${p.name} · ${p.type}:还剩 ${p.left} 天</li>`
).join('');
临近七天标红,不只是好看,是真能救命——礼物的快递周期基本就在一周左右。
| 字段 | 作用 | 备注 |
|---|---|---|
| name | 展示称呼 | 随意填 |
| month/day | 计算下一个日期 | 月份存 1–12 |
| type | 区分生日/纪念日 | 仅展示用 |
| left | 派生值 | 不入库,渲染时算 |
几个需要注意的地方
- 2 月 29 日生日的,平年
new Date(y,1,29)会回滚成 3 月 1 日,倒计时会偏。这种特殊日期我直接提示用户填 2 月 28 日兜底。 - 比较"今年是否已过"必须用零点日期,直接用
new Date()带时分秒,容易在生日当天凌晨算出负数。 - localStorage 里别存
left这种派生字段,它是会变的,每次打开重算才对,存进去第二天就过期了。 - 排序用
a.left - b.left,负数(已经过了但还没到明年?不会,因已滚明年)不会出现,放心用。
总结
纪念日管家的难点不在计算,而在"下一个生日滚到哪年"这个边界。把年份判断和剩余天数拆成两个小函数,逻辑一下就清楚:前者处理跨年,后者处理展示。再配合 localStorage 持久化和七天标红,它就从一个玩具变成了我真每天会用的东西。
【声明】本内容来自华为云开发者社区博主,不代表华为云及华为云开发者社区的观点和立场。转载时必须标注文章的来源(华为云社区)、文章链接、文章作者等基本信息,否则作者和本社区有权追究责任。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱:
cloudbbs@huaweicloud.com
- 点赞
- 收藏
- 关注作者
评论(0)