Java工具-获取某月份天数、某月最后一天、某月工作日天数(支持自定义节假日)
因为之前在项目中有一个工作日志的功能,所以在网上找了一些相关的工具类,都是零零散散,我在这总结一下。废话不多说,上代码!
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.*;
/**
* @ClassName WorkDayUtil 计算日期、工作日相关的工具类
* @Auther JunKai
* @Date 2019/12/24
*/
public class WorkDayUtil {
/** 预设工作日数据的开始年份 */
private static final int START_YEAR = 2017;
/** 预设工作日数据的结束年份 */
private static final int END_YEAR = 5020;
/** 工作日map,true为补休,false为放假 */
public static final Map WORKDAY_MAP = new HashMap();
private static final SegmentTree SEGMENT_TREE;
private WorkDayUtil() {
}
/** 获取一个月天数 */
public static int getDaysOfMonth(Date date) {
Calendar calendar = Calendar.getInstance();
calendar.setTime(date);
return calendar.getActualMaximum(Calendar.DAY_OF_MONTH);
}
/** 获取一个月的最后一天 */
public static String getLastDay(Date date) {
SimpleDateFormat df = new SimpleDateFormat("yyyy-MM-dd");
Calendar calendar = Calendar.getInstance();
calendar.setTime(date);
int lastDays = calendar.getActualMaximum(Calendar.DAY_OF_MONTH);
Date time = calendar.getTime();
time.setDate(lastDays);
return df.format(time);
}
/** 获取一个月的第一天 */
public static String getFirstDay(Date date) {
SimpleDateFormat df = new SimpleDateFormat("yyyy-MM-dd");
Calendar calendar = Calendar.getInstance();
calendar.setTime(date);
//calendar.add(Calendar.MONTH, -1);
calendar.set(Calendar.DAY_OF_MONTH, 1);
String time = df.format(calendar.getTime());
return time;
}
/**
* 计算两个日期之间有多少个工作日
* @param startDate
* @param endDate
* @return
*/
public static int howManyWorkday(Date startDate, Date endDate) {
if (startDate.after(endDate)) {
return howManyWorkday(endDate, startDate);
}
Calendar startCalendar = Calendar.getInstance();
startCalendar.setTime(startDate);
int startDays = getDaysAfterStartYear(startCalendar) - 1; // 第一天从0开始
Calendar endCalendar = Calendar.getInstance();
endCalendar.setTime(endDate);
int endDays = getDaysAfterStartYear(endCalendar) - 1; // 第一天从0开始
if (startDays == endDays) { // 如果开始日期和结束日期在同一天的话
return isWorkDay(startDate) ? 1 : 0; // 当天为工作日则返回1天,否则0天
}
if (!START_DATE_HANDLING_STRATEGY.ifCountAsOneDay(startDate)) { // 根据处理策略,如果开始日期不算一天的话
++startDays; // 起始日期向后移一天
}
if (!END_DATE_HANDLING_STRATEGY.ifCountAsOneDay(endDate)) { // 根据处理策略,如果结束日期不算一天的话
--endDays; // 结束日期向前移一天
}
return SEGMENT_TREE.query(startDays, endDays);
}
static {
initWorkday(); // 初始化工作日map
// 计算从START_YEAR到END_YEAR一共有多少天
int totalDays = 0;
for (int year = START_YEAR; year END_YEAR) {
throw new IllegalArgumentException(String.format("系统目前仅支持计算%d年至%d年之间的工作日,无法计算%d年!", START_YEAR, END_YEAR, year));
}
int days = 0;
for (int i=START_YEAR; i= 1) {
if ((~left & 1) == 1) sum += data[left ^ 1];
if ((right & 1) == 1) sum += data[right ^ 1];
}
return sum;
}
}
/** 起始日期处理策略 */
private static final BoundaryDateHandlingStrategy START_DATE_HANDLING_STRATEGY = date -> {
Calendar calendar = Calendar.getInstance();
calendar.setTime(date);
return calendar.get(Calendar.HOUR_OF_DAY) < 12; // 如果开始时间在中午12点前,则当天也算作一天,否则不算
};
/** 结束日期处理策略 */
private static final BoundaryDateHandlingStrategy END_DATE_HANDLING_STRATEGY = date -> {
return true; // 结束时间无论几点,都算作1天
};
}
好了,这工具类就完事了!
每天进步一点点
|