为了账号安全,请及时绑定邮箱和手机立即绑定

分享新致笔试题,有关日期方面的

标签:
Java

请用JAVA(或C++)实现以下函数,基于给定的起始日期,终止日期参数计算期限(Tenor):
JAVA:
String getTenor(Date startDate, Date endDate)
C++:
std::string getTenor(const Date& startDate, const Date& endDate)

要求:
1) Tenor是指起始日与终止日之间的时间长度,以:xD, xW, xM, xY的形式表示。其中x为正整数,D为日,W为周,M为月,Y为年单位,并且Tenor只能出现1个单位(最简形式)。
比如:
getTenor(2017/3/1, 2017/4/1)
正确答案:1M
错误答案:31D
getTenor(2017/3/1, 2018/9/1)
正确答案:18M
错误答案:1.5Y (x不为整数) 或 1Y6M(出现多个单位)
2) 代码需要体现出必要的边界检查,对JAVA或C++语法的准确性不做严格要求,代码整洁,清晰即可
3) 对于实现中需要的日期相关计算函数,可进行必要的假设,不要求提供正确的类库API名称
4) 基于方法实现尽可能多的写出相应的单元测试用例,给出输入参数和期望结果,无需给出具体测试代码实现

import java.text.ParsePosition;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Date;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

public final class DateUtil {

    /**
     * 
     * @param year
     *            年份
     * @param month
     *            月份
     * @return 0不合法
     */
    public static final int getCurrentDay(int year, int month) {
        if (month == 0 || month == 2 || month == 4 || month == 6 || month == 7 || month == 9 || month == 11) {
            return 31;
        } else if (month == 3 || month == 5 || month == 8 || month == 10) {
            return 30;
        } else if (month == 1) {
            return year % 4 == 0 && year % 100 != 0 || year % 400 == 0 ? 29 : 28;
        }
        return 0;

    }

    public static final String getTenor(Date startDate, Date endDate) throws IllegalAccessException {
        if (startDate == null || endDate == null) {
            return null;
        }
        Calendar startCalendar = Calendar.getInstance();
        startCalendar.setTime(startDate);
        Calendar endCalendar = Calendar.getInstance();
        endCalendar.setTime(endDate);
        int startYear = startCalendar.get(Calendar.YEAR);
        int endYear = endCalendar.get(Calendar.YEAR);
        int startMonth = startCalendar.get(Calendar.MONTH);
        int endMonth = endCalendar.get(Calendar.MONTH);
        int startDay = startCalendar.get(Calendar.DATE);
        int endDay = endCalendar.get(Calendar.DATE);

        int diffMonth = 0;
        int diffYear = 0;
        int diffDay = 0;
        String unit = null;
        // 不同年
        if (startYear != endYear) {
            // 不同月
            if (startMonth != endMonth) {
                // 不同日
                if (startDay != endDay) {
                    diffDay = Math.abs(endDay - startDay);
                    // 月份天数+年份天数+天数
                    diffDay = diffDay + addDays(startYear, endYear, startMonth, endMonth) + addDays(startYear, endYear);
                    unit = getWeekByDay(diffDay);
                }
                // 相同日
                else if (startDay == endDay) {
                    diffYear = endYear - startYear;
                    diffMonth = endMonth - startMonth;
                    if ((diffYear > 0 && diffMonth > 0) || (diffYear < 0 && diffMonth < 0)) {
                        diffMonth = Math.abs(diffYear * 12 + diffMonth);
                    } else if (diffYear > 0 && diffMonth < 0) {
                        diffMonth = diffMonth + 12;
                        diffMonth = diffYear * 12 + diffMonth;
                    } else if (diffYear < 0 && diffMonth > 0) {
                        diffMonth = -diffMonth + 12;
                        diffMonth = -diffYear * 12 + diffMonth;
                    }

                    unit = getYearByMonth(diffMonth);
                }
            }
            // 相同月
            else if (startMonth == endMonth) {
                // 不同日
                if (startDay != endDay) {
                    diffDay = Math.abs(endDay - startDay);
                    diffDay = diffDay + addDays(startYear, endYear, startMonth, endMonth) + addDays(startYear, endYear);
                    unit = getWeekByDay(diffDay);

                }
                // 相同日
                else if (startDay == endDay) {
                    diffYear = Math.abs(endYear - startYear);
                    unit = diffYear + "Y";
                }
            }

        }
        // 相同年
        else if (startYear == endYear) {
            // 不同月
            if (startMonth != endMonth) {
                // 不同日
                if (startDay != endDay) {
                    diffDay = Math.abs(endDay - startDay);
                    diffDay += addDays(startYear, endYear, startMonth, endMonth);
                    unit = getWeekByDay(diffDay);

                }
                // 相同日
                else if (startDay == endDay) {
                    diffMonth = Math.abs(endMonth - startMonth);
                    unit = diffMonth + "M";
                }
            }
            // 相同月
            else if (startMonth == endMonth) {
                // 不同日
                if (startDay != endDay) {
                    diffDay = Math.abs(endDay - startDay);
                    unit = getWeekByDay(diffDay);

                }
                // 相同日
                else if (startDay == endDay) {
                    return "0D";
                }

            }

        }

        return unit;
    }

    /**
     * 
     * @param startYear
     *            开始年份
     * @param endYear
     *            结束年份
     * @return 年份份返回天数
     */
    public static final int addDays(int startYear, int endYear) {
        int beginYear = Math.min(startYear, endYear);
        int dueYear = Math.max(startYear, endYear);
        int days = 0;
        for (int i = beginYear; i < dueYear; ++i) {
            days += leapYear(i);
        }
        return days;
    }

    /**
     * 
     * @param startMonth
     *            开始月份
     * @param endMonth
     *            结束月份
     * @return 月份返回天数
     */
    public static final int addDays(int startYear, int endYear, int startMonth, int endMonth) {
        int beginYear = Math.min(startYear, endYear);
        int dueYear = Math.max(startYear, endYear);
        int beginMonth = Math.min(startMonth, endMonth);
        int dueMonth = Math.max(startMonth, endMonth);
        int days = 0;// 天数
        while (beginYear < dueYear) {
            for (int i = beginMonth; i < dueMonth; ++i) {
                days += getCurrentDay(beginYear, i);
            }
            ++beginYear;

        }
        return days;
    }

    /**
     * 
     * @param start
     *            开始日期
     * @param end
     *            结束日期
     * @return 日期之间的时间 格式为xD, xW, xM, xY,并且只有一个单位
     * @throws IllegalAccessException
     */
    public static final String getTenor(String start, String end) throws IllegalAccessException {
        if (start == null || end == null) {
            return null;
        }
        Date startDate = strToDate(start);
        Date endDate = strToDate(end);
        return getTenor(startDate, endDate);
    }

    /**
     * 
     * @param diffDay
     *            天数
     * @return 一周为7天
     */

    public static String getWeekByDay(int diffDay) {
        String unit = null;
        if (diffDay % 7 == 0) {
            unit = diffDay / 7 + "W";
        } else {
            unit = diffDay + "D";
        }

        return unit;
    }

    /**
     * 
     * @param diffMonth
     *            月份
     * @return 一年12个月
     */
    public static String getYearByMonth(int diffMonth) {
        String unit = null;
        if (diffMonth % 12 == 0) {
            unit = diffMonth / 12 + "Y";
        } else {
            unit = diffMonth + "M";
        }
        return unit;
    }

    public static final void illegalDate(String strDate) {
        if (strDate != null) {
            String[] strDates = strDate.split("/");
            illegalDate(strDates);
        }
    }

    public static final void illegalDate(String strDate, String formart) {
        if (strDate != null && formart != null) {
            String[] strDates = strDate.split(formart);
            illegalDate(strDates);
        }
    }

    /**
     * 
     * @param strDates
     *            非法参数判断
     */
    public static final void illegalDate(String[] strDates) {
        if (strDates != null) {
            int length = strDates.length;
            if (length == 3) {
                String yearStr = strDates[0];
                if (!isNumeric(yearStr)) {
                    throw new IndexOutOfBoundsException("年份为" + yearStr + "是非法的");
                }
                int year = Integer.parseInt(yearStr);
                String monthStr = strDates[1];
                if (!isNumeric(monthStr)) {
                    throw new IndexOutOfBoundsException("月份为" + monthStr + "是非法的");
                }
                int month = Integer.parseInt(monthStr);
                if (month < 1 || month > 12) {
                    throw new IndexOutOfBoundsException("月份为" + monthStr + "是非法的");
                }
                String dayStr = strDates[2];
                if (!isNumeric(dayStr)) {
                    throw new IndexOutOfBoundsException("天数为" + dayStr + "是非法的");
                }
                int day = Integer.parseInt(dayStr);
                if (month == 1 || month == 3 || month == 5 || month == 7 || month == 8 || month == 10 || month == 12) {
                    if (day < 0 || day > 31) {
                        throw new IndexOutOfBoundsException("月份为" + monthStr + ",天数为" + dayStr + "是非法的");
                    }

                } else if (month == 4 || month == 6 || month == 9 || month == 10) {
                    if (day < 0 || day > 30) {
                        throw new IndexOutOfBoundsException("月份为" + monthStr + ",天数为" + dayStr + "是非法的");
                    }

                } else if (month == 2) {
                    if (day < 0 || day > leapMonth(year)) {
                        throw new IndexOutOfBoundsException("月份为" + monthStr + ",天数为" + dayStr + "是非法的");
                    }
                }

            } else if (length != 3) {
                throw new IndexOutOfBoundsException("参数个数为" + length + "是非法的");
            }
        }
    }

    /**
     * 
     * @param str
     *            日期字符串
     * @return 日期是否是正数
     */
    public static final boolean isNumeric(String str) {
        Pattern pattern = Pattern.compile("[0-9]+");
        Matcher isNum = pattern.matcher(str);
        if (!isNum.matches()) {
            return false;
        }
        return true;
    }

    /**
     * 
     * @param year
     *            年份
     * @return 2月份的天数
     */
    public static final int leapMonth(int year) {
        return year % 4 == 0 && year % 100 != 0 || year % 400 == 0 ? 29 : 28;
    }

    /**
     * 
     * @param year
     *            年份
     * @return 闰年或平年天数
     */
    public static final int leapYear(int year) {
        return year % 4 == 0 && year % 100 != 0 || year % 400 == 0 ? 366 : 365;
    }

    /**
     * 
     * @param strDate
     *            日期格式字符串 yyyy/M/d
     * @return 日期
     */
    public static final Date strToDate(String strDate) {
        if (strDate != null) {
            illegalDate(strDate);
            SimpleDateFormat formatter = new SimpleDateFormat("yyyy/M/d");
            ParsePosition pos = new ParsePosition(0);
            Date strtodate = formatter.parse(strDate, pos);
            return strtodate;
        }
        return null;

    }

    public static final Date strToDate(String strDate, String format) {
        if (strDate != null && format != null) {
            SimpleDateFormat formatter = new SimpleDateFormat(format);
            ParsePosition pos = new ParsePosition(0);
            Date strtodate = formatter.parse(strDate, pos);
            return strtodate;
        }
        return null;

    }

}

希望高人指点一下,看看还有什么逻辑错误,还有什么状况没有判断到,还有什么地方可以灵活点。还有什么地方是可以优化的

点击查看更多内容
TA 点赞

若觉得本文不错,就分享一下吧!

评论

作者其他优质文章

正在加载中
JAVA开发工程师
手记
粉丝
56
获赞与收藏
363

关注作者,订阅最新文章

阅读免费教程

  • 推荐
  • 评论
  • 收藏
  • 共同学习,写下你的评论
感谢您的支持,我会继续努力的~
扫码打赏,你说多少就多少
赞赏金额会直接到老师账户
支付方式
打开微信扫一扫,即可进行扫码打赏哦
今天注册有机会得

100积分直接送

付费专栏免费学

大额优惠券免费领

立即参与 放弃机会
意见反馈 帮助中心 APP下载
官方微信

举报

0/150
提交
取消