题目
服务订购到期日
在真实的业务场景中,客户可以在任意一天订购我们的服务,订购周期可以是一个月、一个季度、半年或一年,在订购日后的这么多月的当天凌晨 0 点订单到期。
以下举例说明订购的过期计算方式:
- 在 2018-11-10 订购一个月,订购将在 2018-12-10 过期
- 在 2018-12-10 订购一个月,订购将在 2019-01-10 过期
- 在 2019-01-30 订购一个月,订购将在 2019-02-28 过期
- 在 2019-04-30 订购一个月,订购将在 2019-05-30 过期
- 在 2019-05-31 订购三个月,订购将在 2019-08-31 过期
问题1(无需编程)
假定我们每天可以收到 4 个订单,其中一个是一个月周期的,一个是一个季度周期的,一个是半年周期的,一个是一年周期的。这样的订单从很久以前,比如五年前就开始了。
请通过分析回答:在哪一天到期的订单会最多,有多少个?具体是哪几个订单?
并对分析过程进行解释。
问题2
请实现一个方法,给定订购的年月日 (year, month, day),已知订购时长是一个月,请返回订单的到期日。year, month, day 均为整数,输入已保证是正确的日期。
注:Javascript 不能使用 Date 对象和第三方库。
Javascript 请实现以下方法:
function getExpirationDate(year, month, day) {
// TODO
return [year, month, day];
}
题解
日期的问题就是要考虑好特殊情况就行主要就是2月份的28号和29号
下面是我的思路
问题1
一个月前 简称为 1m
一个季度前 简称为 3m
半年前 简称为 6m
一年前 简称为 12m
首先考虑普通日期的情况
- 非2月份的1号-29号和2月份的1号-27号
在这些普通日期中最多情况下是:1m、3m、6m、12m,各一个过期也就是最多4个
特殊情况
- 30号的情况
30号不为月底和普通情况差不多
30号为月底情况下,如果上个月也是30为月底那么将只有一个1m的订单,如果上个月是31为月底,那么将有两个1m的订单分别是上个月30号和31的订单,结合实际情况,30号最多订单情况为:2个1m、2个3m、2个6m、1个12m,也就是7个订单
- 31号的情况
如果前一个月没有31号,将不会有1m的订单,所以31号的订单最多情况不会超过30号的最多情况
- 2月份的28号
在这一天过期的订单将有
1m订单1.28、1.29、1.30、1.31
3m订单 11.28、11.29、11.30
6m订单 8.28、8.29、8.30、8.31
12m订单 上一年如果是闰年将有 2.28、2.29,如果是平年 2.28
- 2月份的29号
和28号的逻辑一样,但是肯定超不过28号的订单
答案
订单最多的一天是2.28号且上一年是闰年且今年不能是订单开始的第一年,最多是13个订单,具体是1.28、1.29、1.30、1.31、11.28、11.29、11.30、8.28、8.29、8.30、8.31、2.28、2.29
问题2
function getExpirationDate(year, month, day) {
let newYear, newMonth, newDay;
if (month === 12) {
newYear = year + 1;
newMonth = 1;
newDay = day;
} else {
newYear = year;
newMonth = month + 1;
let lastMonthDay = getMonthLastDay(year, month);
let nextMonthLastDay = getMonthLastDay(newYear, newMonth);
if (day === lastMonthDay || day > nextMonthLastDay) {
newDay = nextMonthLastDay;
} else {
newDay = day;
}
}
return [newYear, newMonth, newDay];
}
function isRunYear(year) {
return (year % 4 === 0 && year % 100 !== 0) || year % 400 === 0;
}
function getMonthLastDay(year, month) {
if (month === 2) {
return isRunYear(year) ? 29 : 28;
}
return [1, 3, 5, 7, 8, 10, 12].includes(month) ? 31 : 30;
}
console.log(getExpirationDate(2020, 1, 30)); //2020.02.29
console.log(getExpirationDate(2020, 2, 29)); //2020.03.29
console.log(getExpirationDate(2021, 2, 28)); //2021.03.28
console.log(getExpirationDate(2021, 3, 31)); //2021.04.30
console.log(getExpirationDate(2021, 12, 31)); //2022.01.31