计算宝宝年龄大小
2020-01-16 本文已影响0人
nyzstar
背景
有一天,产品经理提了一个需求,说我们产品宝宝年龄的计算有点问题,和用户的认知有偏差。
我们之前采用的是标准的日期间隔计算的生日,但是和用户(国人)的认知有偏差。
年龄计算基本规则(国人认知,即产品需求)
已知参数:开始日期startDate 和 结束日期endDate
分别对应的年月日为sYear,sMonth,sDay 和eYear,eMonth,eDay;
-
年龄的天数
- 日期同年同月 eDay-sDay+1 结果就是年龄的天数
例如 20190101与20190103 就是3-1+1=3天 - 日期非同年同月 满月为基准,eDay 到满月的天数
例如 20190101月20190303 就是 2个月2天
-
年龄满月的概念(天数达到满月,月份+1)
sMonth+1;sDay 的日期 即为满月。(对于日期比较,大家可以把下个月理解为结束日期的那个月,eMonth)
简单的可以理解为:下个月的sDay的当天为满月,例如20190110的满月就是20190210。不过,在计算的时候满月并不是那么简单,有一些边界情况需要特殊处理
- sDay 大于下个月的天数
此时满月应该是下个月的月末,例如1月31日的满月是2月28(闰年是2月29),因为2月不可能有31天,那满月就是下个月的月末
代码实现
Android ( iOS 或者其他语言 可以参考实现)
import java.util.Calendar;
import java.util.Date;
import java.util.Locale;
public static BabyBornInfo caculateBornInfo(Calendar bornCalendar, Calendar nowCalendar) {
BabyBornInfo bornInfo = new BabyBornInfo();
int nowday = nowCalendar.get(Calendar.DAY_OF_MONTH);
int nowMonthdays = nowCalendar.getActualMaximum(Calendar.DATE);
boolean isNowMonthEnd = (nowday >= nowMonthdays);
int bornday = bornCalendar.get(Calendar.DAY_OF_MONTH);
int day = nowday - bornday;
int month = nowCalendar.get(Calendar.MONTH) - bornCalendar.get(Calendar.MONTH);
int year = nowCalendar.get(Calendar.YEAR) - bornCalendar.get(Calendar.YEAR);
//如果当前天等于月份天数 并且当前天小于出生天 则只计算月份差,算满月
//计算逻辑如下 如果nowday 大于bornday 则正常计算差值即可
//天数不够
if(day < 0){
if (isNowMonthEnd){ //月末默认满月
day = 0;
}
}
if (day < 0) {
//天不够 则应该先计算上个月月末距离的时间 递归
Calendar preMonthCalendar = Calendar.getInstance(Locale.CHINA);
preMonthCalendar.setTime(nowCalendar.getTime());
preMonthCalendar.add(Calendar.MONTH, -1);//得到上一个月,用来得到上个月的天数。
preMonthCalendar.set(Calendar.DAY_OF_MONTH,preMonthCalendar.getActualMaximum(Calendar.DAY_OF_MONTH));
BabyBornInfo preMothonInfo = caculateBornInfo(bornCalendar,preMonthCalendar);
day = preMothonInfo.day+nowday;
month = preMothonInfo.month;
year = preMothonInfo.year;
} else {
if (month < 0) {
month = (month + 12) % 12;
year--;
} else if (month > 12){
year++;
}
if (month == 0 && year == 0){
//同年同月,天数+1
day++;
}
}
bornInfo.year = year;
bornInfo.month = month;
bornInfo.day = day;
return bornInfo;
}
public static class BabyBornInfo {
public int year;
public int month;
public int day;
}
写在最后
- 没啥好说的