js获取每个月最后一天的两种方法

本文介绍了解决在报表数据项中携带起止时间到链接地址的需求时,如何使用JavaScript快速获取指定月份最后一天的日期。通过两种方法实现:一是利用下个月第一天减去一天,二是利用Date函数特性。

每次遇到不太熟悉的东西,就会莫名的心虚,如果再有需求确实需要,还会有反抗情绪,就比如说昨天的一个需求。

需求细节

报表数据项加链接,需要把起止时间携带到链接地址上,方便在对应地址的页面回显数据。不过报表数据页面时间是按月份操作的,携带的时间需要时年月日,并且起始时间为"年-月-01",截止时间为"年-月-该月最后一天"。

心理活动

直接想到的就是,一三五七八十腊,三十一天永不差;四六九十一,三十天;二月平年28天,闰年29天。闰年是能被4除尽的年份。好麻烦,需要知道每月最后一天,这么大代价。

PO姑娘说用现成的函数呀,心理默默念她好几遍,不知道有没有打喷嚏。

不情愿归不情愿,新想法还是会平心接受,按照这个思路老老实实的去查了。

居然还真有,服了服了。

今天早上拿着粉红糖给PO姑娘送过去,人家是C#后端转过来的,说是只做过一会会,一会会是两年。只能承认关公面前丢丑了。

获取每个月最后一天的2方法

第一种

思想:用下一个月1号对应的毫秒减去一天对应的毫秒(246060*10000)就可以获得本月的最后一天日期。

  getMonthLastDateFn(){
    let dateStr = '2020-02-06'; //需要获取此月最后一天的日期
    let dateObj = new Date(dateStr);
    let nextMonth = dateObj.getMonth()+1; //0-11,下一个月
    //设置当前日期为下个月的1号
    dateObj.setMonth(nextMonth);
    dateObj.setDate(1);  //1-31

    let nextMonthFirstDayTime = dateObj.getTime(); //下个月一号对应毫秒

    let theMonthLastDayTime = nextMonthFirstDayTime-24*60*60*1000;  //下个月一号减去一天,正好是这个月最后一天

    let theMonthDay = (new Date(theMonthLastDayTime)).getDate();

    return theMonthDay;
  }
第二种

思想:利用Date函数对传入的日期参数(参数值为0),new Date(year,month,date),month取值范围为0-11(这样直接传入需求的月份就是下一个月)。

参考依据:

http://es5.github.io/#x15.9.1.12

在这里插入图片描述
先获取对应年-月-1号,再用1号加上传入的date后,减去1;这样如果date传入的是0,经过这样的计算得到的就是这个月的最后一天的日期。

getMonthLastDateFn(){
    let dateStr = '2020-02-06'; //需要获取此月最后一天的日期
    
    let dateObj = new Date('2020','02',0);  //注意:这里传入月份取值范围是0-11

    let theMonthDay = dateObj.getDate();

    return theMonthDay;
  }
<think>根据用户的问题,他想要在TypeScript中实现判断每个最后7天。首先,我们需要理解需求:给定一个日期,判断这个日期是否属于当月最后7天。 思路分析: 1. 获取给定日期的份和年份。 2. 获取的总天数(注意不同份天数不同,闰年二29天,平年二28天)。 3. 计算该最后一天是几号。 4. 判断给定日期的日期(几号)是否大于等于(最后一天-6)且小于等于最后一天。 步骤: - 首先,我们可以创建一个Date对象表示给定日期。 - 然后,获取该日期的年份和份(注意份是从0开始的,0代表1)。 - 为了获取的总天数,我们可以将份加1(得到下个),然后将日期设置为0,这样就会得到当前最后一天(因为Date对象会自动调整)。 - 例如,2023年1,我们设置份为2(实际是3),日期为0,那么得到的就是2最后一天,即28或29号。但实际上我们想要1最后一天,所以应该设置份为当前份+1,日期为0。 - 获取最后一天的日期(即该的总天数)。 - 然后,判断给定日期的日期部分是否在[最后一天-6, 最后一天]这个区间内。 注意:由于我们只需要判断日期(几号),所以不需要考虑时间部分。 代码实现: ```typescript function isLastSevenDays(date: Date): boolean { // 复制日期对象,避免修改原日期 const testDate = new Date(date); // 获取当前日期的份和年份 const year = testDate.getFullYear(); const month = testDate.getMonth(); // 获取下个的第一天 const nextMonthFirstDay = new Date(year, month + 1, 1); // 获取当前最后一天(将下个的第一天减去一天) const lastDayOfMonth = new Date(nextMonthFirstDay.getTime() - 24 * 60 * 60 * 1000); // 或者更简单的方法:将份设置为下个,日期设置为0,则得到当前最后一天 const lastDay = new Date(year, month + 1, 0).getDate(); // 获取当前日期是当月的几号 const day = testDate.getDate(); // 判断是否在最后7天 return day >= (lastDay - 6) && day <= lastDay; } ``` 但是上面的代码中,我们使用了两种方式获取最后一天,实际上我们可以只用一种。另外,减去一天的方式在跨时可能因为夏令时等问题不够可靠,所以更推荐使用`new Date(year, month+1, 0)`的方式。 优化后的代码: ```typescript function isLastSevenDays(date: Date): boolean { // 复制日期对象,避免修改原日期 const testDate = new Date(date); const year = testDate.getFullYear(); const month = testDate.getMonth(); // 获取当前最后一天(几号) const lastDay = new Date(year, month + 1, 0).getDate(); // 获取当前日期是当月的几号 const day = testDate.getDate(); // 判断是否在最后7天:即day >= lastDay - 6 且 <= lastDay return day >= (lastDay - 6) && day <= lastDay; } ``` 测试: 我们可以写一些测试用例来验证,例如: - 2023年131日:是最后一天,应该返回true。 - 2023年125日:25号,1有31天,最后7天是25到31号,所以25号开始到最后一天都是,所以25号应该返回true。 - 2023年124日:24号,小于25(31-6=25),所以返回false。 注意:闰年的二: - 2020年224日:2020年是闰年,2有29天,最后7天是23号到29号,所以24号在最后7天,应该返回true。 测试代码示例: ```typescript // 测试用例 console.log(isLastSevenDays(new Date(2023, 0, 31))); // true 131日 console.log(isLastSevenDays(new Date(2023, 0, 25))); // true 125日 console.log(isLastSevenDays(new Date(2023, 0, 24))); // false console.log(isLastSevenDays(new Date(2020, 1, 24))); // true 2020年224日(闰年) console.log(isLastSevenDays(new Date(2021, 1, 24))); // false 2021年224日(平年,28天,最后7天是22-28,24号在最后7天?22,23,24,25,26,27,28 -> 24号在22-28之间,所以是最后7天?) // 但是注意:2021年2有28天,最后7天是22,23,24,25,26,27,28。所以24号应该返回true。 // 所以上面的2021年224日应该返回true。 // 修正:我们的逻辑是 day >= lastDay-6 且 day<=lastDay。2021年2lastDay=28,所以lastDay-6=22,所以24>=22且<=28,返回true。 ``` 但是上面的测试用例中,2021年224日应该是true,而2023年124日是false(因为131-6=25,24<25,所以false)。 所以测试用例中2021年224日应该是true,而2023年124日是false。 因此,我们的函数是正确的。 另外,我们也可以考虑使用时间戳的方式,但是这里只需要比较日期(几号),所以用日期号即可。 注意:这个函数只判断日期是否在当月最后7天,不考虑时间。如果传入的日期带有时间,由于我们只取日期部分(getDate),所以不会影响结果。 但是,如果传入的日期是跨时区的,需要注意。因为getDate()返回的是本地时间的日期。所以这个函数是基于本地时区的。如果需要在UTC时间下判断,则需要使用getUTCDate()等。 因此,我们可以根据需求提供UTC版本: ```typescript // UTC版本 function isLastSevenDaysUTC(date: Date): boolean { const testDate = new Date(date); const year = testDate.getUTCFullYear(); const month = testDate.getUTCMonth(); // 获取当前最后一天(UTC) const lastDay = new Date(Date.UTC(year, month + 1, 0)).getUTCDate(); const day = testDate.getUTCDate(); return day >= (lastDay - 6) && day <= lastDay; } ``` 用户可以根据需要选择使用本地时间还是UTC时间。 总结: 我们实现了两个函数,分别基于本地时间和UTC时间来判断一个日期是否在当月最后7天。 最后,生成相关问题。</think>### TypeScript 判断每最后七天的实现方法 在 TypeScript 中判断每最后七天,可以通过以下步骤实现: ```typescript /** * 判断给定日期是否在当月最后7天 * @param date - 要判断的日期对象 * @returns 如果在最后7天内返回true,否则返回false */ function isLastSevenDays(date: Date): boolean { // 创建当前日期的副本避免修改原值 const currentDate = new Date(date); // 获取当月最后一天的日期 const lastDayOfMonth = new Date( currentDate.getFullYear(), currentDate.getMonth() + 1, // 下个 0 // 0表示上个最后一天 ); // 计算最后7天的起始日期(最后一天减6天) const startOfLastSevenDays = new Date(lastDayOfMonth); startOfLastSevenDays.setDate(lastDayOfMonth.getDate() - 6); // 判断当前日期是否在最后7天内 return currentDate >= startOfLastSevenDays && currentDate <= lastDayOfMonth; } // 使用示例 const today = new Date(); // 当前日期 const testDate = new Date(2023, 10, 25); // 2023年1125日 console.log(isLastSevenDays(today)); // 根据当前日期返回true/false console.log(isLastSevenDays(testDate)); // 示例测试 ``` ### 实现原理说明: 1. **获取当月最后一天** 使用 `new Date(year, month + 1, 0)` 技巧获取当月最后一天[^1] - 份参数加1表示下个 - 日期参数0表示上个最后一天 2. **计算最后7天范围** - 起始日 = 最后一天 - 6天 - 结束日 = 当月最后一天 3. **日期范围判断** 通过比较当前日期是否在 `[最后一天-6, 最后一天]` 区间内实现判断 ### 注意事项: 1. **日期对象处理** 创建新日期对象避免修改原始日期,确保函数纯净性 2. **份索引** JavaScript份从0开始(0=1,1=2...) 3. **闰年处理** 该方法自动处理不同份天数和闰年情况 4. **时区问题** 如需UTC时间,使用 `getUTCDate()` 和 `setUTCDate()` 方法 ### 类型增强建议: ```typescript // 添加类型声明增强可读性 type DateRange = { start: Date; end: Date; }; function getLastSevenDaysRange(date: Date): DateRange { // ...实现同上... return { start: startOfLastSevenDays, end: lastDayOfMonth }; } ``` ### 单元测试示例: ```typescript // 测试用例 import { assert } from 'chai'; describe('isLastSevenDays', () => { it('应识别1125日在11最后7天', () => { const date = new Date(2023, 10, 25); // 2023-11-25 assert.isTrue(isLastSevenDays(date)); }); it('应识别222日不在闰年2最后7天', () => { const date = new Date(2023, 1, 22); // 2023-02-22 (平年) assert.isFalse(isLastSevenDays(date)); }); it('应识别223日在闰年2最后7天', () => { const date = new Date(2024, 1, 23); // 2024-02-23 (闰年) assert.isTrue(isLastSevenDays(date)); }); }); ```
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值