Skip to content
This repository has been archived by the owner on Aug 20, 2021. It is now read-only.

小巧实用日期处理 DateUtil

feilong edited this page Nov 21, 2016 · 3 revisions

在JAVA开发中,避免不了对日期的操作,但是Java本身对 DateCalendar 对象使用起来混乱并且复杂,故使用此工具类做了封装。

主要由下面四部分组成

输入图片说明

我们先来看出镜率最高的两个转换的方法 DateUtil.toString(Date, String) , DateUtil.toDate(String, String...)

1.DateUtil.toString(Date, String) 方法

这就是我们常用来做 Date类型转成字符串类型的方法 通常我们会这么写

SimpleDateFormat simpleDateFormat = new SimpleDateFormat("ddMMyyyy");
String birth = simpleDateFormat.format(date);

如果有小伙伴不小心把 simpleDateFormat 声明成类的变量,在并发的情况下,可能会出现异常,参见 SimpleDateFormat在多线程下不安全 此时你可以直接使用:

示例:

DateUtil.toString(Tue Oct 16 23:49:21 CST 2012,DatePattern.COMMON_DATE_AND_TIME_WITH_MILLISECOND) 

结果:

2012-10-16 23:49:21.525

此外,也经常看到小伙伴是这样创建时间戳文件夹的

Calendar calendar = Calendar.getInstance();
String userDefinedPath = calendar.get(Calendar.YEAR) + "/"
				+ (calendar.get(Calendar.MONTH) + 1) + "/"
				+ calendar.get(Calendar.DAY_OF_MONTH) + "/" + "propertyImage"
				+ "/";

我们可以有更简单的代码:

String userDefinedPath = DateUtil.toString(new Date(), "YYYY/MM/dd/") + "propertyImage/";

可以看到,代码更加简洁明了

2.DateUtil.toDate(String, String...) 方法

DateUtil.toString(Date, String) 相反的,就是将字符串转成 Date 格式

将时间字符串 dateString 使用一个或者多个不同的 datePattern 模式按照顺序转换成date类型. 经常我们会看到小伙伴写出下面的代码:

SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm");
Date publishTimeDate = null;
try{
    publishTimeDate = simpleDateFormat.parse(publishTime);
}catch (ParseException e1){
    e1.printStackTrace();
}

可以看到直接使用 SimpleDateFormat 来写代码的话, 代码行数较多,并且还需要自行处理 ParseException checkedException异常, 而且catch里面一般都是写的都是无用代码 此时你可以一行代码搞定:

Date publishTimeDate = DateUtil.toDate(publishTime, DatePattern.COMMON_DATE_AND_TIME_WITHOUT_SECOND);

该方法,如果转换有异常,会将 ParseException 转成 IllegalArgumentException 返回,是 UnCheckedException异常 ,非强行要求捕获处理

示例:

DateUtil.toDate("2016-02-33", DatePattern.COMMON_DATE)                   = 2016-03-04
DateUtil.toDate("2016-06-28T01:21:12-0800", "yyyy-MM-dd'T'HH:mm:ssZ")    = 2016-06-28 17:21:12
DateUtil.toDate("2016-06-28T01:21:12+0800", "yyyy-MM-dd'T'HH:mm:ssZ")    = 2016-06-28 01:21:12

注意:

  • 转换的时候,使用日历的宽松模式,参见 java.text.DateFormat.setLenient(boolean),即支持传入"2016-02-33",会转换成 2016-03-04
  • 如果能解析所有的字符串,那么视为成功
  • 如果没有任何的模式匹配,将会抛出异常

下面出场的是经常会用作报表数据统计的方法获得 今天00:00:00,这个月第一天,这个星期第一天,今年第一天

3. 用作数据统计

方法 Description
DateUtil.getFirstDateOfThisDay(Date) 获得指定日期 date的 00:00:00.000时间.
DateUtil.getFirstDateOfThisMonth(Date) 获得指定日期date所在月的第一天,00:00:00.000到毫秒.
DateUtil.getFirstDateOfThisWeek(Date) 获得指定日期 date 所在的星期第一天(周日) 00:00:00.000 到毫秒.
DateUtil.getFirstDateOfThisYear(Date) 获得指定日期date所在年的第一天,00:00:00.000 到毫秒.
DateUtil.getLastDateOfThisDay(Date) 获得指定日期 date的 23:59:59.999时间.
DateUtil.getLastDateOfThisMonth(Date) 获得指定日期date所在月的最后一天,23:59:59.999 到毫秒.
DateUtil.getLastDateOfThisWeek(Date) 获得指定日期所在星期的最后一天(周六) 23:59:59.999 到毫秒.
DateUtil.getLastDateOfThisYear(Date) 获得指定日期date所在年的最后一天 23:59:59.999 到毫秒.

4. 时间运算

方法 Description
DateUtil.addYear(Date, int) 指定日期 date,加减年份.
DateUtil.addMonth(Date, int) 指定日期 date加减月份.
DateUtil.addWeek(Date, int) 指定日期 date加减星期 .
DateUtil.addDay(Date, int) 指定日期 date加减天数.
DateUtil.addHour(Date, int) 指定日期 date加减小时.
DateUtil.addMinute(Date, int) 指定日期 date加减分钟.
DateUtil.addSecond(Date, int) 指定日期 date加减秒.
DateUtil.addMillisecond(Date, int) 指定日期 date加减毫秒.

4.1 实例1 生成优惠券

程序员鼓励师:小帅哥,帮我生成一张优惠券,有效期截至到是下个月1号 00:00:00

普通程序员 是这么写的:

    /**
     * 获取优惠券,有效期
     * @return
     */
    private Date[] getTimes(){
        Date start = new Date();
        //优惠券enddate
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(start);
        calendar.add(Calendar.MONTH,1);
        calendar.add(Calendar.DATE, 1);
        calendar.set(Calendar.HOUR_OF_DAY, 0);
        calendar.set(Calendar.MINUTE, 0);
        calendar.set(Calendar.SECOND, 0);
        calendar.set(Calendar.MILLISECOND, 0);
        Date end = calendar.getTime();
        
        Date[] dates = {start,end};
        return dates;
    }

聪明程序员 是这么写的

    /**
     * 获取优惠券,有效期
     * @return
     */
    private Date[] getTimes(){
        Date start = new Date();
        Date[] dates = { start, DateUtil.getFirstDateOfThisDay(DateUtil.addMonth(start, 1)) };
        return dates;
    }

4.2 实例2 导出数据

程序员鼓励师:小帅哥,帮我导出7天以来的订阅邮件数据

普通程序员 是这么写的:

/* 获取上一周的数据 */
java.util.Calendar c = java.util.Calendar.getInstance();
c.add(java.util.Calendar.DAY_OF_WEEK, -7);
Date startDate = c.getTime();
Date curDate = new Date();

细细一琢磨,这段代码如果执行的话,如果系统较卡,执行到这段代码的时候,会有数据丢失

聪明程序员 是这么写的

/* 获取上一周的数据 */
Date startDate =DateUtil.getFirstDateOfThisDay(DateUtil.addDay(new Date(), -7));
Date curDate = new Date();

5. 取到date某个时间属性

方法 Description
DateUtil.getYear(Date) 获得指定日期 date中的年份.
DateUtil.getMonth(Date) 获得指定日期 date中的月份 (已经+1处理).
DateUtil.getWeekOfYear(Date) 获得指定日期所在星期的最后一天(周六) 23:59:59.999 到毫秒.
DateUtil.getDayOfYear(Date) 获得指定日期 date是当年中的第几天.
DateUtil.getDayOfMonth(Date) 获得指定日期 date是当前月的几号.
DateUtil.getDayOfWeek(Date) 获得指定日期date在当前星期是星期几.
DateUtil.getHourOfDay(Date) 获得指定日期date中的小时(24小时制).
DateUtil.getHourOfYear(Date) 获得指定日期date在它一年中的小时数.
DateUtil.getMinute(Date) 获得指定日期date中的分钟.
DateUtil.getSecond(Date) 获得指定日期date中的秒.
DateUtil.getSecondOfDay(Date) 获得指定日期date在当天中的秒数,最大值86400.
DateUtil.getSecondOfHour(Date) 获得指定日期date在当前小时中的秒数,最大值3600.
DateUtil.getTime(Date) 返回自 1970年1月1 日 00:00:00 GMT 以来,此 Date 对象表示的毫秒数.

6. 时间比较

方法 Description
DateUtil.isEquals(Date, Date, String) 在相同格式下 datePattern,将两个日期转成字符串判断是否相等.
DateUtil.isInTime(Date, Date, Date) 判断指定日期 date 是否在 beginDate 和 endDate两个时间之间.
DateUtil.isBefore(Date, Date) 判断指定日期 date是否 在 whenDate时间之前.
DateUtil.isAfter(Date, Date) 判断指定日期 date是否在 whenDate时间之后.

7. DateUtil.isLeapYear(int)

判断指定年 year 是否为闰年

8. 综合运用:

下面代码 美化

    // 判断是否支持当日达和COD
    private void judgeDelivery(Long areaCode,DefaultReturnResult defaultReturnResult){
        boolean flag = false;
        DeliveryArea area = deliveryareaManager.findEnableDeliveryAreaByCode(areaCode + "");
        DeliveryAreaViewCommand areaViewCommand = (DeliveryAreaViewCommand) ConvertUtils.convertTwoObject(new DeliveryAreaViewCommand(), area);
        if (Validator.isNotNullOrEmpty(area)){
            AreaDeliveryMode areaMode = areaModeManager.findAreaDeliveryModeByAreaId(area.getId());
            if (null != areaMode){
                areaViewCommand = (DeliveryAreaViewCommand) ConvertUtils.convertTwoObject(areaViewCommand, areaMode);
                defaultReturnResult.setReturnObject(areaMode);
                DateFormat df = new SimpleDateFormat("HH:mm:ss");
                Date now = new Date();
                try{
                    now = df.parse(df.format(now));
                    if (areaViewCommand.getFirstDayDelivery().equals(AreaDeliveryMode.YES) && Validator.isNotNullOrEmpty(areaViewCommand.getFirstDeliveryStartTime()) && Validator.isNotNullOrEmpty(areaViewCommand.getFirstDeliveryEndTime())){
                        // 时间是否允许
                        now = df.parse(df.format(now));
                        flag = (now.before(df.parse(areaMode.getFirstDeliveryEndTime()))) && (now.after(df.parse(areaMode.getFirstDeliveryStartTime())));
                        defaultReturnResult.setResult(flag);

                    }

                    // 是否支持次日达
                    if (areaMode.getSecondDayDelivery().equals(AreaDeliveryMode.YES) && Validator.isNotNullOrEmpty(areaMode.getSecondDeliveryStartTime()) && Validator.isNotNullOrEmpty(areaMode.getSecondDeliveryEndTime())){
                        // 时间是否允许
                        now = df.parse(df.format(now));
                        flag = (now.before(df.parse(areaMode.getSecondDeliveryEndTime()))) && (now.after(df.parse(areaMode.getSecondDeliveryStartTime())));
                        defaultReturnResult.setResult(flag);
                    }

                    if (areaMode.getThirdDayDelivery().equals(AreaDeliveryMode.YES) && Validator.isNotNullOrEmpty(areaMode.getThirdDeliveryStartTime()) && Validator.isNotNullOrEmpty(areaMode.getThirdDeliveryEndTime())){
                        // 时间是否允许
                        flag = (now.before(df.parse(areaMode.getSecondDeliveryEndTime()))) && (now.after(df.parse(areaMode.getSecondDeliveryStartTime())));
                        defaultReturnResult.setResult(flag);
                    }
                    defaultReturnResult.setReturnObject(areaViewCommand);
                }catch (ParseException e){
                    LOGGER.error("DateFormat Format ERROR !", e);
                }
            }else{
                defaultReturnResult.setResult(false);
                defaultReturnResult.setStatusCode("deliveryArea.has.not.areamode");
            }
        }else{
            defaultReturnResult.setResult(false);
            defaultReturnResult.setStatusCode("deliveryArea.not.exist");
        }
    }

美化后:

    // 判断是否支持当日达和COD
    private void judgeDelivery(Long areaCode,DefaultReturnResult defaultReturnResult){
        DeliveryArea deliveryArea = deliveryareaManager.findEnableDeliveryAreaByCode(areaCode + "");
        if (isNullOrEmpty(deliveryArea)){
            defaultReturnResult.setResult(false);
            defaultReturnResult.setStatusCode("deliveryArea.not.exist");
            return;
        }

        //************************************************************************
        DeliveryAreaViewCommand deliveryAreaViewCommand = (DeliveryAreaViewCommand) ConvertUtils.convertTwoObject(new DeliveryAreaViewCommand(), deliveryArea);
        AreaDeliveryMode areaDeliveryMode = areaModeManager.findAreaDeliveryModeByAreaId(deliveryArea.getId());
        if (isNullOrEmpty(areaDeliveryMode)){
            defaultReturnResult.setResult(false);
            defaultReturnResult.setStatusCode("deliveryArea.has.not.areamode");
            return;
        }

        //************************************************************************
        deliveryAreaViewCommand = (DeliveryAreaViewCommand) ConvertUtils.convertTwoObject(deliveryAreaViewCommand, areaDeliveryMode);
        Date now = toDate(DateUtil.toString(new Date(), COMMON_TIME), COMMON_TIME);

        boolean flag = false;
        //************************************************************************************************

        String firstDeliveryStartTime = deliveryAreaViewCommand.getFirstDeliveryStartTime();
        String firstDeliveryEndTime = deliveryAreaViewCommand.getFirstDeliveryEndTime();
        if (YES.equals(deliveryAreaViewCommand.getFirstDayDelivery()) && isNotNullOrEmpty(firstDeliveryStartTime) && isNotNullOrEmpty(firstDeliveryEndTime)){
            // 时间是否允许
            flag = DateUtil.isInTime(now, toDate(areaDeliveryMode.getFirstDeliveryStartTime(), COMMON_TIME), toDate(areaDeliveryMode.getFirstDeliveryEndTime(), COMMON_TIME));
        }

        // 是否支持次日达
        String secondDeliveryEndTime = areaDeliveryMode.getSecondDeliveryEndTime();
        String secondDeliveryStartTime = areaDeliveryMode.getSecondDeliveryStartTime();
        if (YES.equals(areaDeliveryMode.getSecondDayDelivery()) && isNotNullOrEmpty(secondDeliveryStartTime) && isNotNullOrEmpty(secondDeliveryEndTime)){
            // 时间是否允许
            flag = DateUtil.isInTime(now, toDate(secondDeliveryStartTime, COMMON_TIME), toDate(secondDeliveryEndTime, COMMON_TIME));
        }

        String thirdDeliveryStartTime = areaDeliveryMode.getThirdDeliveryStartTime();
        String thirdDeliveryEndTime = areaDeliveryMode.getThirdDeliveryEndTime();
        if (YES.equals(areaDeliveryMode.getThirdDayDelivery()) && isNotNullOrEmpty(thirdDeliveryStartTime) && isNotNullOrEmpty(thirdDeliveryEndTime)){
            // 时间是否允许
            flag = DateUtil.isInTime(now, toDate(secondDeliveryStartTime, COMMON_TIME), toDate(secondDeliveryEndTime, COMMON_TIME));
        }

        //************************************************************************************************
        defaultReturnResult.setResult(flag);
        defaultReturnResult.setReturnObject(deliveryAreaViewCommand);
    }