计算宝宝年龄大小

2020-01-16  本文已影响0人  nyzstar

背景

有一天,产品经理提了一个需求,说我们产品宝宝年龄的计算有点问题,和用户的认知有偏差。
我们之前采用的是标准的日期间隔计算的生日,但是和用户(国人)的认知有偏差。

年龄计算基本规则(国人认知,即产品需求)

已知参数:开始日期startDate 和 结束日期endDate
分别对应的年月日为sYear,sMonth,sDay 和eYear,eMonth,eDay;

  1. 日期同年同月 eDay-sDay+1 结果就是年龄的天数
    例如 20190101与20190103 就是3-1+1=3天
  2. 日期非同年同月 满月为基准,eDay 到满月的天数
    例如 20190101月20190303 就是 2个月2天

sMonth+1;sDay 的日期 即为满月。(对于日期比较,大家可以把下个月理解为结束日期的那个月,eMonth)
简单的可以理解为:下个月的sDay的当天为满月,例如20190110的满月就是20190210。不过,在计算的时候满月并不是那么简单,有一些边界情况需要特殊处理

  1. 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;
    }

写在最后

上一篇下一篇

猜你喜欢

热点阅读