ARTICLE DETAIL

资讯详情

深耕网站建设与运营推广的一线实战洞察。

用 JavaScript Date 自动校正计算月份最后一天:getLastDayOfMonth 实战详解

用 JavaScript Date 自动校正计算月份最后一天:getLastDayOfMonth 实战详解 文档/教程前端【免费下载链接】en.javascript.infoModern JavaScript Tutorial项目地址https://gitcode.com/gh_mirrors/en/en.javascript.info点击查看免费下载在 JavaScript 中计算某年某月的最后一天是日期处理的高频需求——它天然涉及闰年二月是 28 天还是 29 天、大小月等复杂规则。本指南以 Modern JavaScript Tutorial本仓库中 Date 章节 的经典任务 Last day of month? 为主线讲解如何借助Date对象的自动校正autocorrection机制用一行构造调用优雅地求解并结合本仓库配套源码与单元测试验证其正确性。读完本文你将掌握下一月第 0 天这一经典技巧并能将其推广到任意日期偏移场景。任务要求返回指定年月的最后一天原任务定义如下见 task.md标记 importance: 5属于重点习题编写一个函数getLastDayOfMonth(year, month)返回该月的最后一天。它可能是 30 号、31 号二月则可能是 28 号或 29 号。函数参数约定year四位数年份例如2012month月份取值范围0 到 110 代表一月11 代表十二月。示例getLastDayOfMonth(2012, 1)应返回29——因为 2012 年是闰年二月有 29 天。值得注意的是这个任务之所以重要正因为它要求开发者彻底理解 JavaScriptDate的月索引规则从 0 开始以及自动校正行为而不是依赖switch分支或查表去硬编码各月天数。前置知识组件式构造与月索引要理解题解先回顾 article.md 中关于new Date(year, month, date, hours, minutes, seconds, ms)的约定year应为 4 位数字出于兼容性 2 位数字也会被接受并视为19xx如98等价于1998但官方强烈建议始终使用 4 位month从0一月计数到11十二月date参数实际上表示月中的第几天缺省时假定为1hours/minutes/seconds/ms缺省时均假定为0。正是月从 0 开始这个约定为下一节下一月第 0 天的解法埋下了伏笔当我们想表达二月的最后一天时可以直接构造三月 0 号。核心思路下一月的第 0 天就是本月的最后一天官方解答的思路非常精妙见 solution.md用下一个月创建日期但把日参数传为 0。正常情况下日期从 1 开始但技术上我们可以传入任意数字Date对象会自动调整。当传入0时它表示该月 1 号的前一天也就是上一个月的最后一天。完整实现function getLastDayOfMonth(year, month) { let date new Date(year, month 1, 0); return date.getDate(); } alert( getLastDayOfMonth(2012, 0) ); // 31 alert( getLastDayOfMonth(2012, 1) ); // 29 alert( getLastDayOfMonth(2013, 1) ); // 28逐行拆解new Date(year, month 1, 0)构造下一个月的日期但日号传0自动校正后这个Date实际指向本月的最后一天例如(2012, 1 1, 0)即2012 年 3 月 0 号校正为 2012 年 2 月 29 日date.getDate()返回该对象所代表日期的日号1 到 31即为所求。本仓库中该解法的可运行版本保存在 _js.view/solution.js与上述实现完全一致可直接在浏览器控制台或 Node.js 中运行验证。原理深挖Date 的自动校正autocorrectiongetLastDayOfMonth之所以成立完全依赖Date对象的自动校正特性。article.md 的 Autocorrection 一节对此有专门讲解自动校正是Date对象非常便捷的特性。我们可以设置超出范围的值它会自动调整。例如let date new Date(2013, 0, 32); // 2013 年 1 月 32 日 alert(date); // 实际是 2013 年 2 月 1 日越界的日期分量会被自动分配到后续月份。更直接的证据是设置 0 或负值的示例见 article.md 的 Autocorrection 小节let date new Date(2016, 0, 2); // 2016 年 1 月 2 日 date.setDate(1); // 设为当月 1 号 alert(date); date.setDate(0); // 日号最小是 1于是被解释为上一个月的最后一天 alert(date); // 2015 年 12 月 31 日可见0 号并不存在它被自动解释为该月 1 号的前一天。new Date(year, month 1, 0)正是把这个行为用于构造器参数月份 1 后第 0 天自然落在目标月份之内且一定是该月最后一天。这也意味着闰年判断完全交给引擎处理——2012 年 2 月返回 292013 年 2 月返回 28无需任何手工分支。用单元测试验证正确性本仓库为本题配备了基于 Mocha 的单元测试见 _js.view/test.js覆盖了三种典型场景describe(getLastDayOfMonth, function() { it(last day of 01.01.2012 - 31, function() { assert.equal(getLastDayOfMonth(2012, 0), 31); }); it(last day of 01.02.2012 - 29 (leap year), function() { assert.equal(getLastDayOfMonth(2012, 1), 29); }); it(last day of 01.02.2013 - 28, function() { assert.equal(getLastDayOfMonth(2013, 1), 28); }); });三个用例分别验证了大月2012 年 1 月month 0最后一天是 31闰年二月2012 年 2 月month 1最后一天是 29平年二月2013 年 2 月最后一天是 28。可以看到测试名称中的01.02.2012这类日期字面量与实现中下一月第 0 天的表述一一对应充分印证了自动校正结果的确定性。基于同一原理的等价变体理解了自动校正后求最后一天还可以写成其他等价形式它们依赖相同的机制可从 solution.md 与 article.md 的 Autocorrection 示例推导变体一先到下一月 1 号再回退一天function getLastDayOfMonth(year, month) { let date new Date(year, month 1, 1); date.setDate(date.getDate() - 1); return date.getDate(); }变体二借助 setDate(0)function getLastDayOfMonth(year, month) { let date new Date(year, month 1, 1); date.setDate(0); // 1 号的前一天 return date.getDate(); }两种变体与官方解法殊途同归都是构造一个越界日期让引擎自动校正。实践中官方解法构造器直接传 0代码最简洁也是本仓库 solution.js 采用的版本。注意事项与参数边界month 必须传 0~11若传入12new Date(year, 13, 0)会被校正为次年一月第 0 天从而得到次年 12 月的最后一天——虽然Date不会报错但结果已不符合函数契约year 建议始终使用 4 位如前置知识所述2 位年份会被当作19xx处理如98→1998容易埋下隐蔽 bug返回的是日号1~31getDate()返回的是月中的第几天不是时间戳也不是星期几使用时不要与getDay()星期几0周日混淆该函数不依赖时区差异组件式构造在本地时区下解释而某月最后一天是哪一号在任何时区都是同一结果因此无需担心 UTC 偏移问题。延伸把自动校正用到更多日期运算最后一天技巧只是自动校正的众多应用之一。本仓库 Date 章节 还展示了同原理的更多场景加/减天数date.setDate(date.getDate() 2)即可把 2016 年 2 月 28 日安全地推进到 3 月 1 日闰年与否交给引擎判断获取 N 天前的日号见同章节任务 Which day of month was many days ago? 及其 解答实现中通过克隆日期再setDate(getDate() - days)完成跨月回退且不修改传入的原始Date时间偏移date.setSeconds(date.getSeconds() 70)自动完成跨分钟、跨小时的进位。小结某月最后一天下一月的第 0 天即new Date(year, month 1, 0).getDate()其正确性建立在Date自动校正机制之上越界日号含 0 与负数会被自动分配到相邻月份见 article.md 的 Autocorrection 一节闰年2012 → 29与平年2013 → 28由引擎自动区分无需任何手工判断官方解法源码见 _js.view/solution.js配套 Mocha 测试见 _js.view/test.js三个用例完整覆盖大月、闰年二月、平年二月三种分支。掌握这一技巧后日历组件、账单结算日、报表统计等常见需求中的月末计算都可以一行搞定且天然免疫闰年与大小月的规则差异。赞分享文档/教程前端【免费下载链接】en.javascript.infoModern JavaScript Tutorial项目地址https://gitcode.com/gh_mirrors/en/en.javascript.info点击查看免费下载相关推荐Modern JavaScript 教程实战巧用 Date 自动校正一行代码获取任意月份最后一天Modern JavaScript 教程实战巧用 Date 自动校正一行代码获取任意月份最后一天 在 JavaScript 中判断某个月有多少天看似简单文档/教程前端30-seconds-of-code 实战用一行 JavaScript 代码计算任意月份的天数30 seconds of code 实战用一行 JavaScript 代码计算任意月份的天数 导读 在 JavaScript 中处理日期向来不算直观但计教程文档freeCodeCamp 每日编程挑战解析JavaScript 实现 Due Date9 个月后日期计算freeCodeCamp 每日编程挑战解析JavaScript 实现 Due Date9 个月后日期计算 本篇技术指南围绕 freeCodeCamp前端后端教育上一篇5个核心功能解决网盘下载痛点直链解析技术全解析下一篇突破网盘限速壁垒六大平台极速下载实战指南创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
返回列表