小巧实用日期处理 - DateUtil
在JAVA开发中,避免不了对日期的操作,但是Java本身对 Date
和 Calendar
对象使用起来混乱并且复杂,故使用此工具类做了封装。
主要由下面四部分组成
我们先来看出镜率最高的两个转换的方法 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);
}