30-seconds-of-code:使用 JavaScript 获取某月的第一天与最后一天

发布时间:2026/10/4 16:04:50
30-seconds-of-code:使用 JavaScript 获取某月的第一天与最后一天
教程文档【免费下载链接】30-seconds-of-codeCoding articles to level up your development skills项目地址https://gitcode.com/gh_mirrors/30/30-seconds-of-code点击查看免费下载导读在原生 JavaScript 中处理日期经常让人头疼但获取某月的第一天 / 最后一天这类高频需求只需借助Date构造函数与月份零索引zero-indexed的特性几行代码即可优雅解决。本文以 30-seconds-of-code 仓库中 first-last-date-of-month 文档为主线深入讲解这两个日期工具函数的实现原理、day参数传0的巧妙技巧并结合仓库内 days-in-month、is-leap-year 等姊妹文档给出可直接复制使用的完整代码与实战扩展方案。读完本文你将掌握一套不依赖任何第三方库的月份首末日期计算思路并能将其自然迁移到日历组件、月度统计报表、月末对账等真实业务场景中。先理解Date构造函数的两个关键特性在动手写代码之前先确认两个贯穿全篇的基础事实它们是整个技巧成立的根基。月份是从 0 开始计数的zero-based。在Date对象中Date.prototype.getMonth()返回的 0 代表一月January、1 代表二月February以此类推11 代表十二月。因此 first-last-date-of-month 中的代码用date.getMonth()取到的值必须原样传给构造函数而不是先加 1。Date构造函数会对超出合法范围的参数自动进位overflow。这是本技巧最核心的机制把day设为0会被解释为上个月的最后一天把month设为 12例如getMonth() 1后恰好为 12 且当天是 12 月会被自动进位到下一年的 1 月把day设为32、-1等越界值同样会被自动换算成相邻月份的合法日期。仓库中 is-leap-year 也利用了这一机制new Date(year, 1, 29).getMonth()在闰年返回1仍停留在二月在平年则因自动进位返回2被归一为三月一日。这证明越界参数自动归一是原生Date的稳定行为可以放心依赖。获取某月的第一天给定任意Date对象先用Date.prototype.getFullYear()和Date.prototype.getMonth()取出年份与月份再创建一个新Date并把日期固定为 1即可得到该月第一天const firstDateOfMonth (date new Date()) new Date(date.getFullYear(), date.getMonth(), 1); firstDateOfMonth(new Date(2015-08-11)); // 2015-08-01几点补充说明让这段代码在实战中更稳妥默认参数date new Date()让函数在没有传参时自动作用于当前月份符合 30-seconds-of-code 系列工具函数开箱即用的一贯风格返回全新对象new Date(...)每次都创建一个新的Date实例不会修改调用方传入的原始日期对象避免了 add-minutes-hours-days-to-date 中反复强调的setTime会原地修改对象这类隐患时间分量归零由于构造函数只接收年、月、日三个参数返回的日期对象时分秒会被重置为00:00:00非常适合直接用于日期范围过滤或数据库查询的起止边界。获取某月的最后一天获取最后一天无法靠数日子硬算因为每个月天数不同28、29、30、31 天不等。first-last-date-of-month 给出的解法是一个巧妙技巧不把日期设为 1而是设为0就会得到上个月的最后一天为此需要先把月份加 1。const lastDateOfMonth (date new Date()) new Date(date.getFullYear(), date.getMonth() 1, 0); lastDateOfMonth(new Date(2015-08-11)); // 2015-08-31拆解执行过程以2015-08-11为例getFullYear()得到2015getMonth()得到7八月month参数传7 1 8即九月day参数传0构造函数将其自动解释为九月的前一天即2015-08-31。这套逻辑对任意月份天然成立10 月传入new Date(y, 10, 0)得到 9 月 30 日2 月传入new Date(y, 2, 0)得到 2 月的最后一天平年 28 日、闰年 29 日由构造函数自动计算。因此无需自己维护每月天数表也不用关心闰年判断——这正是该技巧的价值所在。需要留意的是设为 0技巧与获取上个月最后一天在语义上是同一件事但用途不同本函数通过getMonth() 1把指针推进到下个月再回退一天最终锁定的是当前月的最后一天。这与 date-yesterday-today-tomorrow 中用getDate()/setDate()增减天数属于同一类利用越界自动进位的日期运算思路理解其一即可触类旁通。技巧的延伸一行代码算出某月有多少天掌握了day 0的语义后计算某个月有多少天就变成了顺理成章的副产品。仓库姊妹文档 days-in-month 直接给出了单行实现const daysInMonth (year, month) new Date(year, month, 0).getDate(); daysInMonth(2020, 12); // 31 daysInMonth(2024, 2); // 29其原理与lastDateOfMonth完全同构new Date(year, month, 0)得到的是本月第一天前一天即上个月最后一天的时间戳而Date.prototype.getDate()返回的就是这个日期的几号恰好等于上个月的天数又因为月份零索引month传入的值就是目标月的索引例如2024, 2表示三月day0回退到二月最后一天29从而自动识别出 2024 年 2 月是 29 天的闰年二月。[!TIP]如果你的入参是某月某日的Date对象而非(year, month)组合可以直接复用lastDateOfMonth的结果配合getDate()const daysInMonthFromDate date lastDateOfMonth(date).getDate(); daysInMonthFromDate(new Date(2015-08-11)); // 31结合仓库源码验证本篇在项目中的真实定位该文档并非孤立存在其在仓库中的组织方式进一步印证了内容的可靠性内容演进痕迹在 redirects.yaml 中可以看到/js/s/last-date-of-month以301状态重定向到/js/s/first-last-date-of-month说明仓库曾把获取最后一天拆分为独立条目后合并进本篇本文是两个技巧合一的权威版本集合归属本篇属于 JavaScript Date 集合slug: js/date通过tagMatcher: date自动聚合与 date-comparison、date-difference、min-max-date 等构成一套完整的原生日期处理工具箱与其他工具函数的组合潜力仓库中的 date-range-generator 用setDate(getDate() step)逐日递增生成日期区间将其与firstDateOfMonth/lastDateOfMonth组合即可生成整个自然月每一天的序列用于日历渲染或月度数据补全。实战组合构建本月完整日期列表把前文知识组装起来可以得到一个完整的月度工具函数集。以下代码综合运用了firstDateOfMonth、lastDateOfMonth与 date-range-generator 中的生成器思路// 1. 获取某月首末日期默认当月 const firstDateOfMonth (date new Date()) new Date(date.getFullYear(), date.getMonth(), 1); const lastDateOfMonth (date new Date()) new Date(date.getFullYear(), date.getMonth() 1, 0); // 2. 逐日遍历某月所有日期复用时保证不污染原对象 const dateRange function* (start, end, step 1) { for ( let d new Date(start); d new Date(end); d.setDate(d.getDate() step) ) yield new Date(d); }; // 3. 输出本月全部日期 const monthDates (date new Date()) [...dateRange(firstDateOfMonth(date), lastDateOfMonth(date))]; monthDates(new Date(2015-08-11)); // [2015-08-01, 2015-08-02, ..., 2015-08-31]在真实项目中这类组合可以直接支撑日历组件以firstDateOfMonth为起点、lastDateOfMonth为终点铺满网格月度报表以首日为查询起点、末日 23:59:59 为查询终点圈定无遗漏的数据范围月末结算lastDateOfMonth天然适配当月最后一天到期/对账等业务规则日期差值统计配合 date-difference 中的差值算法可计算月份跨度。注意事项与边界使用上述技巧时有几点需要铭记以免在生产环境中踩坑本地时区语义new Date(year, month, day)按运行环境本地时区解析。在中国时区UTC8下通常无碍但若服务器运行在 UTCtoISOString()输出的字符串可能比预期早/晚一天。需要跨时区稳定输出时应改用Date.UTC()组合toISOString()或按 date-comparison 中介绍的方式统一比较基准。默认参数的副作用firstDateOfMonth()不传参时返回的是当前月份的首日而 date-yesterday-today-tomorrow 中提醒过Date对象是可变的。若下游代码在结果上调用setDate()等方法会改变该实例建议按需对返回值做一次浅拷贝。月份零索引的换算若你的数据源如数据库返回采用 1–12 表示月份传给new Date()前必须减 1否则会出现月份偏移一整月的隐性错误。总结原生 JavaScript 的Date对象虽然 API 不够友好但其月份零索引 越界参数自动进位两大特性让获取某月第一天和最后一天这类任务有了极其简洁的解法new Date(y, m, 1)与new Date(y, m 1, 0)。以此为基石days-in-month 中的天数计算、is-leap-year 中的闰年判断、date-range-generator 中的整月遍历都能在不引入任何第三方日期库的前提下顺畅实现。把这几个十几行的工具函数收进你的代码库日后的日历、报表与对账逻辑都会变得更加干净利落。赞分享教程文档【免费下载链接】30-seconds-of-codeCoding articles to level up your development skills项目地址https://gitcode.com/gh_mirrors/30/30-seconds-of-code点击查看免费下载相关推荐30-seconds-of-code 实战用一行 JavaScript 代码计算任意月份的天数30 seconds of code 实战用一行 JavaScript 代码计算任意月份的天数 导读 在 JavaScript 中处理日期向来不算直观但计教程文档30-seconds-of-code用数组解构提取 JavaScript 数组最后一个元素30 seconds of code用数组解构提取 JavaScript 数组最后一个元素 数组解构destructuring assignment是 E教程文档30 Seconds of Code用 slice 与 filter 取 JavaScript 数组的第 n 个元素30 Seconds of Code用 slice 与 filter 取 JavaScript 数组的第 n 个元素 数组按索引取值是 JavaScript教程文档创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考