小巧实用日期处理 - DateUtil

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

主要由下面四部分组成

输入图片说明

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

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

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

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

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

示例:

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

结果:

  1. 2012-10-16 23:49:21.525

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

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

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

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

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

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

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

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

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

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

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

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

示例:

  1. DateUtil.toDate("2016-02-33", DatePattern.COMMON_DATE) = 2016-03-04
  2. DateUtil.toDate("2016-06-28T01:21:12-0800", "yyyy-MM-dd'T'HH:mm:ssZ") = 2016-06-28 17:21:12
  3. 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

普通程序员 是这么写的:

  1. /**
  2. * 获取优惠券,有效期
  3. * @return
  4. */
  5. private Date[] getTimes(){
  6. Date start = new Date();
  7. //优惠券enddate
  8. Calendar calendar = Calendar.getInstance();
  9. calendar.setTime(start);
  10. calendar.add(Calendar.MONTH,1);
  11. calendar.add(Calendar.DATE, 1);
  12. calendar.set(Calendar.HOUR_OF_DAY, 0);
  13. calendar.set(Calendar.MINUTE, 0);
  14. calendar.set(Calendar.SECOND, 0);
  15. calendar.set(Calendar.MILLISECOND, 0);
  16. Date end = calendar.getTime();
  17. Date[] dates = {start,end};
  18. return dates;
  19. }

聪明程序员 是这么写的

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

4.2 实例2 导出数据

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

普通程序员 是这么写的:

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

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

聪明程序员 是这么写的

  1. /* 获取上一周的数据 */
  2. Date startDate =DateUtil.getFirstDateOfThisDay(DateUtil.addDay(new Date(), -7));
  3. 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. 综合运用:

下面代码 美化

  1. // 判断是否支持当日达和COD
  2. private void judgeDelivery(Long areaCode,DefaultReturnResult defaultReturnResult){
  3. boolean flag = false;
  4. DeliveryArea area = deliveryareaManager.findEnableDeliveryAreaByCode(areaCode + "");
  5. DeliveryAreaViewCommand areaViewCommand = (DeliveryAreaViewCommand) ConvertUtils.convertTwoObject(new DeliveryAreaViewCommand(), area);
  6. if (Validator.isNotNullOrEmpty(area)){
  7. AreaDeliveryMode areaMode = areaModeManager.findAreaDeliveryModeByAreaId(area.getId());
  8. if (null != areaMode){
  9. areaViewCommand = (DeliveryAreaViewCommand) ConvertUtils.convertTwoObject(areaViewCommand, areaMode);
  10. defaultReturnResult.setReturnObject(areaMode);
  11. DateFormat df = new SimpleDateFormat("HH:mm:ss");
  12. Date now = new Date();
  13. try{
  14. now = df.parse(df.format(now));
  15. if (areaViewCommand.getFirstDayDelivery().equals(AreaDeliveryMode.YES) && Validator.isNotNullOrEmpty(areaViewCommand.getFirstDeliveryStartTime()) && Validator.isNotNullOrEmpty(areaViewCommand.getFirstDeliveryEndTime())){
  16. // 时间是否允许
  17. now = df.parse(df.format(now));
  18. flag = (now.before(df.parse(areaMode.getFirstDeliveryEndTime()))) && (now.after(df.parse(areaMode.getFirstDeliveryStartTime())));
  19. defaultReturnResult.setResult(flag);
  20. }
  21. // 是否支持次日达
  22. if (areaMode.getSecondDayDelivery().equals(AreaDeliveryMode.YES) && Validator.isNotNullOrEmpty(areaMode.getSecondDeliveryStartTime()) && Validator.isNotNullOrEmpty(areaMode.getSecondDeliveryEndTime())){
  23. // 时间是否允许
  24. now = df.parse(df.format(now));
  25. flag = (now.before(df.parse(areaMode.getSecondDeliveryEndTime()))) && (now.after(df.parse(areaMode.getSecondDeliveryStartTime())));
  26. defaultReturnResult.setResult(flag);
  27. }
  28. if (areaMode.getThirdDayDelivery().equals(AreaDeliveryMode.YES) && Validator.isNotNullOrEmpty(areaMode.getThirdDeliveryStartTime()) && Validator.isNotNullOrEmpty(areaMode.getThirdDeliveryEndTime())){
  29. // 时间是否允许
  30. flag = (now.before(df.parse(areaMode.getSecondDeliveryEndTime()))) && (now.after(df.parse(areaMode.getSecondDeliveryStartTime())));
  31. defaultReturnResult.setResult(flag);
  32. }
  33. defaultReturnResult.setReturnObject(areaViewCommand);
  34. }catch (ParseException e){
  35. LOGGER.error("DateFormat Format ERROR !", e);
  36. }
  37. }else{
  38. defaultReturnResult.setResult(false);
  39. defaultReturnResult.setStatusCode("deliveryArea.has.not.areamode");
  40. }
  41. }else{
  42. defaultReturnResult.setResult(false);
  43. defaultReturnResult.setStatusCode("deliveryArea.not.exist");
  44. }
  45. }

美化后:

  1. // 判断是否支持当日达和COD
  2. private void judgeDelivery(Long areaCode,DefaultReturnResult defaultReturnResult){
  3. DeliveryArea deliveryArea = deliveryareaManager.findEnableDeliveryAreaByCode(areaCode + "");
  4. if (isNullOrEmpty(deliveryArea)){
  5. defaultReturnResult.setResult(false);
  6. defaultReturnResult.setStatusCode("deliveryArea.not.exist");
  7. return;
  8. }
  9. //************************************************************************
  10. DeliveryAreaViewCommand deliveryAreaViewCommand = (DeliveryAreaViewCommand) ConvertUtils.convertTwoObject(new DeliveryAreaViewCommand(), deliveryArea);
  11. AreaDeliveryMode areaDeliveryMode = areaModeManager.findAreaDeliveryModeByAreaId(deliveryArea.getId());
  12. if (isNullOrEmpty(areaDeliveryMode)){
  13. defaultReturnResult.setResult(false);
  14. defaultReturnResult.setStatusCode("deliveryArea.has.not.areamode");
  15. return;
  16. }
  17. //************************************************************************
  18. deliveryAreaViewCommand = (DeliveryAreaViewCommand) ConvertUtils.convertTwoObject(deliveryAreaViewCommand, areaDeliveryMode);
  19. Date now = toDate(DateUtil.toString(new Date(), COMMON_TIME), COMMON_TIME);
  20. boolean flag = false;
  21. //************************************************************************************************
  22. String firstDeliveryStartTime = deliveryAreaViewCommand.getFirstDeliveryStartTime();
  23. String firstDeliveryEndTime = deliveryAreaViewCommand.getFirstDeliveryEndTime();
  24. if (YES.equals(deliveryAreaViewCommand.getFirstDayDelivery()) && isNotNullOrEmpty(firstDeliveryStartTime) && isNotNullOrEmpty(firstDeliveryEndTime)){
  25. // 时间是否允许
  26. flag = DateUtil.isInTime(now, toDate(areaDeliveryMode.getFirstDeliveryStartTime(), COMMON_TIME), toDate(areaDeliveryMode.getFirstDeliveryEndTime(), COMMON_TIME));
  27. }
  28. // 是否支持次日达
  29. String secondDeliveryEndTime = areaDeliveryMode.getSecondDeliveryEndTime();
  30. String secondDeliveryStartTime = areaDeliveryMode.getSecondDeliveryStartTime();
  31. if (YES.equals(areaDeliveryMode.getSecondDayDelivery()) && isNotNullOrEmpty(secondDeliveryStartTime) && isNotNullOrEmpty(secondDeliveryEndTime)){
  32. // 时间是否允许
  33. flag = DateUtil.isInTime(now, toDate(secondDeliveryStartTime, COMMON_TIME), toDate(secondDeliveryEndTime, COMMON_TIME));
  34. }
  35. String thirdDeliveryStartTime = areaDeliveryMode.getThirdDeliveryStartTime();
  36. String thirdDeliveryEndTime = areaDeliveryMode.getThirdDeliveryEndTime();
  37. if (YES.equals(areaDeliveryMode.getThirdDayDelivery()) && isNotNullOrEmpty(thirdDeliveryStartTime) && isNotNullOrEmpty(thirdDeliveryEndTime)){
  38. // 时间是否允许
  39. flag = DateUtil.isInTime(now, toDate(secondDeliveryStartTime, COMMON_TIME), toDate(secondDeliveryEndTime, COMMON_TIME));
  40. }
  41. //************************************************************************************************
  42. defaultReturnResult.setResult(flag);
  43. defaultReturnResult.setReturnObject(deliveryAreaViewCommand);
  44. }