索鸟网

  1. 首页
  2. 分享新致笔试题,有关日期方面的

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


请用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;

    }

}

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

相关标签: JAVA

来源地址:http://www.imooc.com/article/19141 版权归作者所有!

相关教程

  • 【师兄分享】联想五道笔试题

    1、 1)、设计函数 int atoi(char *s)。 2)、int i=(j=4,k=8,l=16,m=32); printf(“%d”, i); 输出是多少? 3)、解释局部变量、全局变量和静态变量的含义。 4)、解释堆和栈的区别。 5)、论述含参数的宏与函数的优缺点。 2、顺时针打印矩阵 题目:输入一个矩阵,按照从外向里以顺时针的顺序依次打印出每一个数字。 例
  • 网易笔试题

    昨天参加网易笔试遇到的,好难啊!!!题目要求――Java(只记得大致):    1、输入一个值,表示接下来要输入数组的个数;范围:1~10^7    2、输入一个值,表示下面数组里元素的个数;    范围:2~10^9   &nbs
  • 诡异笔试题

    一、宏#define PRINTF(a); printf("#") int main( ) { int a = 0; for(int i=0;i<5;++i) PRINTF(a+i); system("pause"); return 0; } 程序只输出一个"#"  为什么呢? 在此宏定义中, 把#define
  • 凌云光科技笔试题

    1、死锁产生的原因及解决方案 产生死锁的原因主要是: (1) 因为系统资源不足。 (2) 进程运行推进的顺序不合适。 (3) 资源分配不当等。 如果系统资源充足,进程的资源请求都能够得到满足,死锁出现的可能性就很低,否则 就会因争夺有限的资源而陷入死锁。其次,进程运行推进顺序与速度不同,也可能产生死锁。 产生死锁的四个必要条件: (1) 互斥条
  • java开发笔试题

    1.       什么是Java jvm ?jdk 和jre区别是什么? JVM:Java Virtual Mechinal(JAVA虚拟机)。JVM是JRE的一部分,它是一个虚构出来的计算机,是通过在实际的计算机上仿真模拟各种计算机功能来实现的。JVM有自己完善的硬件架构,如处理器、堆栈、寄存器等,还具有相应的指令系统。JVM 的
  • 一道笔试题引发的思考

    前两天做了一份笔试题:按照执行顺序列出下面代码的打印内容 var name = "The Window"; var object = { name : "The Object", getNameFunc : function(){ (() => { console.log(this.name)
  • 新的试题

    1 #include < stdio.h> 2 main() 3 { 4 int a =12 , b = 3 ; 5 float x = 18.5 , y = 4.6 ;                    答案(a*b)/2=2.0 6 printf ( ”%f\n",(fl
  • Nodejs方面的基础面试题

    1.什么是Nodejs? Nodejs是一个JavaScript的运行环境,是一个服务器端的“JavaScript解释器”,用于方便高效地搭建一些响应速度快、易于扩展的网络应用。它采用事件驱动、异步编程,为网络服务而设计。 2.Nodejs的优缺点 优点: (1)nodejs是基于事件驱动和无阻塞的,非常适合处理并发请求,因此构建在Nodejs上的代理服务器相比其他技术