commons-lang 之 DateUtils 和 DateFormatUtils

1. 准备

常用的日期时间工具类:org.apache.commons.lang3.time.DateUtils、org.apache.commons.lang3.time.DateFormatUtils。

引入 Maven 依赖:

<dependency>
    <groupId>org.apache.commons</groupId>
    <artifactId>commons-lang3</artifactId>
</dependency>

为方便测试,再引入 Junit 的 Maven 依赖:

<dependency>
    <groupId>junit</groupId>
    <artifactId>junit</artifactId>
</dependency>

2. DateFormatUtils 的 format() 方法(Date -> String)

>>> 将 java.util.Date 类型的日期数据转换成指定格式的 String 字符串。

【###】其他方法实现

//import java.text.SimpleDateFormat;
//String sdf.format(Date date)
Date date = new Date();
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
String str = sdf.format(date);

【###】DateFormatUtils.format() 方法实现

//String DateFormatUtils.format(Date date, String pattern)
Date date = new Date();
String str = DateFormatUtils.format(date,"yyyy-MM-dd HH:mm:ss");
System.out.println(date.toString()); //Mon Nov 26 22:42:22 CST 2018
System.out.println(str); //2018-11-26 22:42:22

DateFormatUtils 的 format() 方法还有许多的重载方法,列举两个:

//String DateFormatUtils.format(long millis, String pattern)
Date date = new Date();
String str = DateFormatUtils.format(date.getTime(),"yyyy-MM-dd HH:mm:ss");

//String DateFormatUtils.format(Calendar calendar, String pattern)
Date date2 = new Date();
Calendar cal = Calendar.getInstance();
cal.setTime(date2);
String str2 = DateFormatUtils.format(cal,"yyyy-MM-dd HH:mm:ss");

3. DateUtils

为了等下方便打印日期,先准备一个打印方法:

public void printDate(Date date){
    String format = DateFormatUtils.format(date, "yyyy-MM-dd HH:mm:ss");
    System.out.println(format);
}

(1)Date DateUtils.parseDate(final String str, final String... parsePatterns)

>>> 将 String 类型的日期数据转换成 Date 类型的日期数据(String -> Date)。

【###】其他方法实现

//import java.text.SimpleDateFormat;
//Date sdf.parse(String source) throws ParseException
String str = "2018-11-27 20:40:33";
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
Date date = null;
try {
    date = sdf.parse(str);
}catch (ParseException e){
    e.printStackTrace();
}

【###】DateUtils.parseDate() 方法实现

//Date DateUtils.parseDate(final String str, final String... parsePatterns) throws ParseException
String str = "2018.11.22 15:21:44";
Date date = null;
try {
    date = DateUtils.parseDate(str, "yyyy.MM.dd HH:mm:ss");
}catch (ParseException e){
    e.printStackTrace();
}

通过该方法的参数可以发现,第二个参数(日期格式)可以有多个值。传入多个格式,如果多个格式中至少有一个可以成功解析该字符串,就可以成功解析;否则方法将报错。

//Date DateUtils.parseDate(final String str, final String... parsePatterns) throws ParseException
String str = "2018.11.22";
Date date = null;
String[] formArray = {"yyyy-MM-dd","yyyy.MM.dd"};
try {
    //传入字符串数组
    date = DateUtils.parseDate(str, formArray);
    //或者这样也可以
    //date = DateUtils.parseDate(str, "yyyy-MM-dd","yyyy.MM.dd");
}catch (ParseException e){
    e.printStackTrace();
}

该方法的重载方法:

Date DateUtils.parseDate(final String str, final Locale locale, final String... parsePatterns)
//该方法中,Locale locale 参数指定语言环境,如果为空,则默认为当前系统的语言环境

(2)Date DateUtils.parseDateStrictly(final String str, final String... parsePatterns)

>>> 将 String 类型的日期数据转换成 Date 类型的日期数据(String -> Date)。

该方法和 DateUtils.parseDate() 方法作用相同,只不过它对于字符串的要求更严格。

比如,下面的代码也可以解析出Date日期,只不过得到的结果变成了“2019-07-20 00:00:00”,并不是正确的结果。

Date date = DateUtils.parseDate("2018-11-262", "yyyy-MM-dd");

而如果像下面这样写的话,会直接报错。

Date date = DateUtils.parseDateStrictly("2018-11-262", "yyyy-MM-dd");

该方法的重载方法:

Date parseDateStrictly(final String str, Locale locale, final String... parsePatterns) throws ParseException

(3)Calendar DateUtils.toCalendar(Date date)

>>> Date -> Calendar。

【###】其他方法实现

//import java.util.Calendar;
//void calendar.setTime(Date date)
Date date = new Date();
Calendar cal = Calendar.getInstance();
cal.setTime(date);

【###】DateUtils.toCalendar(Date date) 方法实现

//Calendar DateUtils.toCalendar(Date date)
Date date = new Date();
Calendar calendar = DateUtils.toCalendar(date);

该方法的重载方法: 

//TimeZone 时区设置
Calendar DateUtils.toCalendar(final Date date, final TimeZone tz)

(4)Date DateUtils.addXxx(Date date, int amount) 系列方法

>>> 给日期时间的指定部分(年/月/日/时/分/秒/毫秒)加上指定大小的值。

【###】其他方法实现

//import java.util.Calendar;
//void calendar.add(int field, int amount)
//Date calendar.getTime();

//以添加小时为例,给 "2018-11-22 14:10:37" 加 3 个小时,返回一个新的 Date 对象
Date date = new Date();
printDate(date);//2018-11-22 14:10:37

Calendar calendar = Calendar.getInstance();
calendar.setTime(date);
calendar.add(Calendar.HOUR_OF_DAY,3);
Date add3Hour = calendar.getTime();
printDate(add3Hour);//2018-11-22 17:10:37

【###】DateUtils.addXxx(Date date, int amount) 方法实现

//Date DateUtils.addXxx(Date date, int amount)
Date date = new Date();
Date addYears = DateUtils.addYears(date,2);
Date addMonths = DateUtils.addMonths(date,2);
Date addDays = DateUtils.addDays(date,2);
Date addHours = DateUtils.addHours(date,2);
Date addMInutes = DateUtils.addMinutes(date,2);
Date addSeconds = DateUtils.addSeconds(date,2);
Date addMilliseconds = DateUtils.addMilliseconds(date,2);
Date addWeeks = DateUtils.addWeeks(date,2);

//结果对比
printDate(date);//2018-11-23 10:17:14
printDate(addYears);//2020-11-23 10:17:14
printDate(addMonths);//2019-01-23 10:17:14
printDate(addDays);//2018-11-25 10:17:14
printDate(addHours);//2018-11-23 12:17:14
printDate(addMInutes);//2018-11-23 10:19:14
printDate(addSeconds);//2018-11-23 10:17:16
printDate(addMilliseconds);//2018-11-23 10:17:14
printDate(addWeeks);//2018-12-07 10:17:14

这一系列方法其实就是对 Calendar 类中对应方法的封装。

如果某个部分的值加上后超过最大值,则该部分左侧部分进1。比如,Date对象值为 “2018-11-27 21:52:10”,加上 10 个小时后,结果为 “2018-11-28 07:52:10”,加满24小时后,继续从头开始数,而天数加 1。

显然,第二个参数为正数时是加;如果为负数,则为减。

(5)Date DateUtils.truncate(Date date, int field)

>>> 截取日期时间的部分值,截取部分外的其他部分使用默认初始值(年、月、日、时、分、秒 的默认初始值分别为:0001、01、01、00、00、00)。

//Date DateUtils.truncate(Date date, int field)
Date date = new Date();
printDate(date);//2018-11-23 09:29:53
Date result = null;

result = DateUtils.truncate(date, Calendar.YEAR);//截取年,而月、日使用初始值01,时、分、秒使用初始值00
printDate(result);//2018-01-01 00:00:00
result = DateUtils.truncate(date,Calendar.MONTH);//截取年、月,而日使用初始值01,时、分、秒使用初始值00
printDate(result);//2018-11-01 00:00:00
result = DateUtils.truncate(date,Calendar.DAY_OF_MONTH);//截取年、月、日,而时、分、秒使用初始值00
printDate(result);//2018-11-23 00:00:00
result = DateUtils.truncate(date,Calendar.DATE);//截取日期部分(年月日)
printDate(result);//2018-11-23 00:00:00

result = DateUtils.truncate(date,Calendar.HOUR_OF_DAY);//截取年、月、日、时,而分、秒使用初始值00
printDate(result);//2018-11-23 09:00:00
result = DateUtils.truncate(date,Calendar.MINUTE);//截取年、月、日、时、分,而秒使用初始值00
printDate(result);//2018-11-23 09:29:00
result = DateUtils.truncate(date,Calendar.SECOND);//截取年、月、日、时、分、秒
printDate(result);//2018-11-23 09:29:53
result = DateUtils.truncate(date,Calendar.ALL_STYLES);//都不截取
printDate(result);//0001-01-01 00:00:00

该方法的重载方法:

Calendar DateUtils.truncate(final Calendar date, final int field)

//该方法虽然接收一个 Object 类型参数,但该date参数要 instanceof Date(或Calendar)
Date DateUtils.truncate(final Object date, final int field)

(6)int DateUtils.truncatedCompareTo(Date date1, Date date2, int field)

>>> 两个日期截取相同的部分进行比较。

如果 date1更大(更晚)则返回 1,如果 date2 更大(更晚)则返回 -1 ,如果相等,则返回 0。

//int DateUtils.truncatedCompareTo(final Date date1, final Date date2, final int field)
Date date1 = new Date();
Date date2 = DateUtils.addDays(date1,1);
printDate(date1);//2018-11-23 10:39:28
printDate(date2);//2018-11-24 10:39:28

int a = DateUtils.truncatedCompareTo(date1,date2,Calendar.MONTH);//两个日期都截取到月份再对比,相等,返回 0
int b = DateUtils.truncatedCompareTo(date1,date2,Calendar.DATE);//两个日期都截取到日再对比,date1更小,返回 -1
int c = DateUtils.truncatedCompareTo(date2,date1,Calendar.DATE);//两个日期都截取到日再对比,date2更大,返回 1
System.out.println(a+"  "+b+"  "+c);//0  -1  1

该方法的重载方法:

int DateUtils.truncatedCompareTo(final Calendar cal1, final Calendar cal2, final int field)

(7)boolean DateUtils.truncatedEquals(Date date1, Date date2, int field)

>>> 两个日期截取相同的部分,比较值是否相等。

//boolean DateUtils.truncatedEquals(Date date1, Date date2, int field)
Date date1 = new Date();
Date date2 = DateUtils.addDays(date1,1);
printDate(date1);//2018-11-23 10:47:02
printDate(date2);//2018-11-24 10:47:02

boolean a = DateUtils.truncatedEquals(date1,date2,Calendar.MONTH);//两个日期都截取到月份再对比,相等,返回 true
boolean b = DateUtils.truncatedEquals(date1,date2,Calendar.DATE);//两个日期都截取到日再对比,不相等,返回 false
System.out.println(a+"  "+b);//true  false

该方法的重载方法:

boolean DateUtils.testTruncatedEquals(final Calendar cal1, final Calendar cal2, final int field)

(8)boolean DateUtils.isSameDay(Date date1, Date date2)

>>> 比较两个日期是否是同一天(即年、月、日是否都相等),只比较年月日,时分秒不管。

//boolean DateUtils.isSameDay(Date date1, Date date2)
Date date1 = new Date();
Date date2 = DateUtils.addHours(date1,1);//加1小时
Date date3 = DateUtils.addDays(date1,1);//加1天

boolean sameDay = DateUtils.isSameDay(date1, date2);
boolean sameDay2 = DateUtils.isSameDay(date1, date3);
System.out.println(sameDay + " " +sameDay2);//true false

该方法的重载方法:

boolean DateUtils.isSameDay(Calendar cal1, Calendar cal2)

(9)boolean isSameInstant(Date date1, Date date2)

>>> 比较两个日期是否相等(即年、月、日、时、分、秒都相等)。

实际上是先将两个 Date 都转化为毫秒(Date getTime()),然后再进行对比的。

//boolean isSameInstant(Date date1, Date date2)
boolean sameInst1 = DateUtils.isSameInstant(new Date(),new Date());//日期时间都相同
boolean sameInst2 = DateUtils.isSameInstant(date1,date2);//date1 比 date2 早1小时
boolean sameInst3 = DateUtils.isSameInstant(date1,date3);//date1 比 date2 早1天
System.out.println(sameInst1 + " " + sameInst2 + " " + sameInst3);//true false false

该方法的重载方法:

boolean DateUtils.isSameInstant(Calendar cal1, Calendar cal2)

(10)Date DateUtils.ceiling(Date date, int field)

>>> 截取日期时间的部分值,截取的末尾部分向上取整,截取部分外的其他部分使用默认初始值(年、月、日、时、分、秒 的默认初始值分别为:0001、01、01、00、00、00)。

//Date DateUtils.ceiling(Date date, int field)
Date date = new Date();
try {
    date = DateUtils.parseDate("2018-11-23 15:59:29", "yyyy-MM-dd HH:mm:ss");
}catch (ParseException e){
    e.printStackTrace();
}

Date ceilYear = DateUtils.ceiling(date,Calendar.YEAR);
Date ceilMonth = DateUtils.ceiling(date,Calendar.MONTH);
Date ceilDay = DateUtils.ceiling(date,Calendar.DAY_OF_MONTH);
Date ceilHour = DateUtils.ceiling(date,Calendar.HOUR);
Date ceilMinute = DateUtils.ceiling(date,Calendar.MINUTE);
Date ceilSecode = DateUtils.ceiling(date,Calendar.SECOND);

printDate(date);//2018-11-23 11:32:12
printDate(ceilYear);//2019-01-01 00:00:00,截取到年,年向上取整(即+1)
printDate(ceilMonth);//2018-12-01 00:00:00,截取到月,月向上取整(即+1);如果是12月的话,月进1变成01,年进1
printDate(ceilDay);//2018-11-24 00:00:00,截取到日,日向上取整(即+1);如果是30(或28/31)的话,日进1变成01,月进1
printDate(ceilHour);//2018-11-23 12:00:00,截取到时,时向上取整(即+1);如果是23点的话,时进1变成00,日进1
printDate(ceilMinute);//2018-11-23 11:33:00,截取到分,分向上取整(即+1);如果是59分的话,分进1变成00,时进1
printDate(ceilSecode);//2018-11-23 11:32:13,截取到分,分向上取整(即+1)

该方法的重载方法:

Calendar DateUtils.ceiling(Calendar date, int field)

Date DateUtils.ceiling(Object date, int field)

(11)Date DateUtils.round(Date date, int field)

>>> 截取日期时间的部分值,截取的末尾部分四舍五入,截取部分外的其他部分使用默认初始值(年、月、日、时、分、秒 的默认初始值分别为:0001、01、01、00、00、00)。

//Date DateUtils.round(Date date, int field)
Date date = new Date();
Date roundYear = DateUtils.round(date,Calendar.YEAR);
Date roundMonth = DateUtils.round(date,Calendar.MONTH);
Date roundDay = DateUtils.round(date,Calendar.DAY_OF_MONTH);
Date roundHour = DateUtils.round(date,Calendar.HOUR);
Date roundMinute = DateUtils.round(date,Calendar.MINUTE);
Date roundSecode = DateUtils.round(date,Calendar.SECOND);

printDate(date);//2018-11-23 14:28:53
printDate(roundYear);//2019-01-01 00:00:00,截取到年,根据月份四舍五入,7月之后(包含)进1
printDate(roundMonth);/*2018-12-01 00:00:00,截取到月,根据日四舍五入,28天的月分15号(包含)
之后进1,30天的月16号(包含)之后进1,31天的月17号(包含)之后进1*/
printDate(roundDay);//2018-11-24 00:00:00,截取到日,根据小时四舍五入,12点(包含)之后进1
printDate(roundHour);//2018-11-23 14:00:00,截取到小时,根据分钟四舍五入,30分(包含)之后进1
printDate(roundMinute);//2018-11-23 14:29:00,截取到分钟,根据秒四舍五入,30秒(包含)之后进1
printDate(roundSecode);//2018-11-23 14:28:53截取到分钟,根据毫秒四舍五入

该方法的重载方法:

Calendar DateUtils.round(Calendar date, int field)

Date DateUtils.round(Object date, int field)

(12)long DateUtils.getFragmentInXxx(Date date, int fragment) 系列方法

>>> date所指时间是当前月分(年份)的第几天、date所指时间是当天(当前月份 / 年份)的第几个小时。

//long DateUtils.getFragmentInXxx(final Date date, final int fragment)
Date date = null;
try {
    date = DateUtils.parseDate("2018-02-05 01:29:29", "yyyy-MM-dd HH:mm:ss");
}catch (Exception e){

}

long day1 = DateUtils.getFragmentInDays(date,Calendar.YEAR);//日期所在年份开始到日期时间过了几天
System.out.println(day1);//36
long day2 = DateUtils.getFragmentInDays(date,Calendar.MONTH);//日期所在月份开始到日期时间过了几天
System.out.println(day2);//5

long hour1 = DateUtils.getFragmentInHours(date,Calendar.YEAR);//日期所在年份开始到日期时间过了几个小时
System.out.println(hour1);//841
long hour2 = DateUtils.getFragmentInHours(date,Calendar.MONTH);//日期所在月份开始到日期时间过了几个小时;
System.out.println(hour2);//97
long hour3 = DateUtils.getFragmentInHours(date,Calendar.DAY_OF_MONTH);//日期所在日开始到日期时间过了几个小时
System.out.println(hour3);//1

该方法的重载方法:

long DateUtils.getFragmentInMinutes(final Date date, final int fragment)
long DateUtils.getFragmentInSeconds(final Date date, final int fragment)
long DateUtils.getFragmentInMilliseconds(final Date date, final int fragment)

long DateUtils.getFragmentInDays(final Calendar cal, final int fragment)
long DateUtils.getFragmentInHours(final Calendar cal, final int fragment)
long DateUtils.getFragmentInMinutes(final Calendar cal, final int fragment)
long DateUtils.getFragmentInSeconds(final Calendar cal, final int fragment)
long DateUtils.getFragmentInMilliseconds(final Calendar cal, final int fragment)

(13)Date DateUtils.setXxx(Date date, int amount) 系列方法

>>> 给日期指定部分设置指定的值。

//Date DateUtils.setXxx(Date date, int amount)
Date date = new Date();
Date yearDate = DateUtils.setYears(date,2019);//amount取值范围,(1- )
Date monthDate = DateUtils.setMonths(date,0);//amount取值范围,(0-11)
Date dayDate = DateUtils.setDays(date,1);//amount取值范围,(1-28/30/31)
Date hourDate = DateUtils.setHours(date,0);//amount取值范围,(0-23)
Date minDate = DateUtils.setMinutes(date,59);//amount取值范围,(0-59)
Date secDate = DateUtils.setSeconds(date,59);//amount取值范围,(0-59)
Date milSecDate = DateUtils.setMilliseconds(date,999);//amount取值范围,(0-999)

printDate(date);        // 2018-11-28 01:33:14
printDate(yearDate);    // 2019-11-28 01:33:14
printDate(monthDate);   // 2018-01-28 01:33:14
printDate(dayDate);     // 2018-11-01 01:33:14
printDate(hourDate);    // 2018-11-28 00:33:14
printDate(minDate);     // 2018-11-28 01:59:14
printDate(secDate);     // 2018-11-28 01:33:59
printDate(milSecDate);  // 2018-11-28 01:33:14

(14)Iterator<Calendar> DateUtils.iterator(Date focus, int rangeStyle)

>>> 遍历包含日期 focus 所在的 rangeStyle 范围的连续星期的每一天。

例如,下面示例1中将要遍历的是,包含了当前时间(2018-11-28 01:44:00)所属月份(即2018年的11月)的连续完整的所有星期(周一作为星期的第一天)的每一天。

rangeStyle参数取值只能限制在下面这些值里:

RANGE_MONTH_SUNDAY   //包含date所在月分的连续完整星期,周日作为星期的第一天
RANGE_MONTH_MONDAY   //包含date所在月分的连续完整星期,周一作为星期的第一天
RANGE_WEEK_SUNDAY    //date所在星期,周日作为星期的第一天
RANGE_WEEK_MONDAY    //date所在星期,周一作为星期的第一天
RANGE_WEEK_RELATIVE  //date作为星期第一天的7天
RANGE_WEEK_CENTER    //date作为星期的中间一天的7天

示例: 

Date date = new Date();
printDate(date);
System.out.println("-----------");
     
//示例1   
Iterator<Calendar> iterator = DateUtils.iterator(date, DateUtils.RANGE_MONTH_MONDAY);
while(iterator.hasNext()){
    Calendar next = iterator.next();
    Date time = next.getTime();
    printDate(time);
}
System.out.println("-----------");

//示例2
Iterator<Calendar> iterator2 = DateUtils.iterator(date, DateUtils.RANGE_WEEK_RELATIVE);
while(iterator2.hasNext()){
    Calendar next = iterator2.next();
    Date time = next.getTime();
    printDate(time);
}

//打印结果
2018-11-28 01:44:00
-----------
2018-10-29 00:00:00
2018-10-30 00:00:00
2018-10-31 00:00:00
2018-11-01 00:00:00
2018-11-02 00:00:00
.....连续的日期(太多了)
2018-11-29 00:00:00
2018-11-30 00:00:00
2018-12-01 00:00:00
2018-12-02 00:00:00
-----------
2018-11-28 00:00:00
2018-11-29 00:00:00
2018-11-30 00:00:00
2018-12-01 00:00:00
2018-12-02 00:00:00
2018-12-03 00:00:00
2018-12-04 00:00:00

该方法的重载方法:

Iterator<Calendar> DateUtils.iterator(final Calendar focus, final int rangeStyle)

Iterator<Calendar> DateUtils.iterator(final Object focus, final int rangeStyle)

 

  • 12
    点赞
  • 27
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
commons-lang是一个开源的Java类库,提供了许多常用的工具类和方法,能够帮助开发者简化Java编程过程中的一些常见任务。 commons-lang 3-12.0是commons-lang类库的一个特定版本。这个版本是commons-lang 3系列的第12个发布版本,也是该系列的最新版本。它包含了在之前版本的基础上进行的一些改进和修复。 commons-lang 3-12.0版本主要提供了以下一些功能和特性: 1. 字符串操作:commons-lang提供了很多关于字符串操作的工具类和方法,如字符串连接、截取、格式化、编码解码等,使得处理字符串变得更加简单和高效。 2. 数据类型转换:commons-lang提供了各种数据类型之间的转换工具类,例如将字符串转换为整数、日期转换为字符串等,方便开发者进行各种类型的数据转换。 3. 数组操作:commons-lang提供了一些有关数组操作的工具方法,如数组的复制、填充、排序、查找等,使得开发者可以更方便地操作数组数据。 4. 异常处理:commons-lang提供了一些异常处理的工具类和方法,例如异常转换、异常堆栈信息处理等,能够帮助开发者更好地处理和记录异常信息。 同时,commons-lang还提供了其他一些实用的工具类和方法,如日期处理、随机数生成、文件操作、反射等等,能够帮助开发者提高开发效率和代码质量。 总的来说,commons-lang 3-12.0是一个非常实用的Java类库,它的存在不仅简化了Java编程中一些常见任务的处理,也提高了代码的可读性和可维护性。无论是在日常的开发工作中,还是在开发一些大型项目中,都可以考虑使用commons-lang来提升开发效率和质量。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值