常用的日期时间工具类:org.apache.commons.lang3.time.DateUtils、org.apache.commons.lang3.time.DateFormatUtils。
引入 Maven 依赖:
org.apache.commons
commons-lang3
为方便测试,再引入 Junit 的 Maven 依赖:
junit
junit
>>> 将 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");
为了等下方便打印日期,先准备一个打印方法:
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
>>> 遍历包含日期 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 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 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 DateUtils.iterator(final Calendar focus, final int rangeStyle)
Iterator DateUtils.iterator(final Object focus, final int rangeStyle)