import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date;
import java.util.List;
import org.apache.log4j.Logger;
/**
* 日期工具类
*
* @author ZengWenfeng
* @email 117791303@QQ.COM
* @date 2020.06.01
*/
public class DateUtil
{
private static Logger logger = Logger.getLogger(DateUtil.class);
private static final String DATE_FORMAT_yyyy_MM_dd = "yyyy-MM-dd";
private static final String DATE_FORMAT_yyyyMMdd = "yyyyMMdd";
private static final String DATE_FORMAT_yyyyMMddHHmmss = "yyyyMMddHHmmss";//yyyyMMddHHmmss
private static final String DATE_FORMAT_HHmmss = "HHmmss";//HHmmss
private static final String DATE_FORMAT_yyyyMMddHHmmssSSS = "yyyyMMddHHmmssSSS";//"yyyyMMddHHmmssSSS"
private static final String DATE_TYPE_WORK = "00";//工作日
private static final String DATE_TYPE_NEW_YEAR_S_DAY = "10";//元旦
private static final String DATE_TYPE_SPRING_FESTIVAL = "20";//春节
private static final String DATE_TYPE_QING_MING_FESTIVAL = "30";//清明节
private static final String DATE_TYPE_LABOR_DAY = "40";//劳动节
private static final String DATE_TYPE_THE_DRAGON_BOAT_FESTIVAL = "50";//端午节
private static final String DATE_TYPE_MID_AUTUMN_FESTIVAL = "60";//中秋节
private static final String DATE_TYPE_NATIONAL_DAY = "70";//国庆节
private static final String DATE_TYPE_ANTI_JAPANESE_WAR_ANNIVERSARY = "80";//抗战纪念日
private static final String DATE_TYPE_OTHER_HOLIDAY = "90";//其他
private static final String WEEK_TYPE_SUNDAY = "0";//星期日
private static final String WEEK_TYPE_MONDAY = "1";//星期一
private static final String WEEK_TYPE_TUESDAY = "2";//星期二
private static final String WEEK_TYPE_WEDNESDAY = "3";//星期三
private static final String WEEK_TYPE_THURSDAY = "4";//星期四
private static final String WEEK_TYPE_FRIDAY = "5";//星期五
private static final String WEEK_TYPE_SATURDAY = "6";//星期六
/**
* 根据日期格式化类型将字符串转换为日期
*
* @author ZengWenfeng
* @email 117791303@QQ.COM
* @date 2020.06.01
* @param strDate
* @param format
* @return
*/
public static Date parseStrToDate(String strDate, String format)
{
SimpleDateFormat sdf = new SimpleDateFormat(format);
try
{
return sdf.parse(strDate);
}
catch (ParseException e)
{
//e.printStackTrace();
logger.error("ERROR:字符串【" + strDate + "】无法转换为格式【" + format + "】的日期,将返回空值。", e);
return null;
}
}
/**
* 将类型为yyyyMMddHHmmss字符串转换为日期
*
* @author ZengWenfeng
* @email 117791303@QQ.COM
* @date 2020.06.01
* @param strDate
* @param format
* @return
*/
public static Date parseStrToDate_yyyyMMddHHmmss(String strDate)
{
return parseStrToDate(strDate, DATE_FORMAT_yyyyMMddHHmmss);
}
/**
* 将类型为yyyyMMdd字符串转换为日期
*
* @author ZengWenfeng
* @email 117791303@QQ.COM
* @date 2020.06.01
* @param strDate
* @param format
* @return
*/
public static Date parseStrToDate_yyyyMMdd(String strDate)
{
return parseStrToDate(strDate, DATE_FORMAT_yyyyMMdd);
}
/**
* 将类型为yyyy-MM-dd字符串转换为日期
*
* @author ZengWenfeng
* @email 117791303@QQ.COM
* @date 2020.06.01
* @param strDate
* @param format
* @return
*/
public static Date parseStrToDate_yyyy_MM_dd(String strDate)
{
return parseStrToDate(strDate, DATE_FORMAT_yyyy_MM_dd);
}
/**
* 获取某天制定时间,返回日期类型
*
* @author ZengWenfeng
* @email 117791303@QQ.COM
* @date 2020.06.01
* @param strDate 2020.06.01 12:00:00
* @param strTime 08:30:00
* @param format yyyyMMddHHmmss
* @return Date 2020.06.01 08:30:00
*/
public static Date getCurDateStartTime(Date date, String strTime, String format)
{
String strDate = getStrFromDate_yyyyMMdd(date) + strTime;
return parseStrToDate(strDate, format);
}
/**
* 根据格式化类型获取时间相应的字符串
*
* @author ZengWenfeng
* @email 117791303@QQ.COM
* @date 2020.06.01
* @param date
* @param format
* @return
*/
public static String getStrFromDate(Date date, String format)
{
SimpleDateFormat sdf = new SimpleDateFormat(format);
return sdf.format(date);
}
/**
* 根据格式化类型获取时间相应的字符串
*
* @author ZengWenfeng
* @email 117791303@QQ.COM
* @date 2020.06.01
* @param date
* @return yyyyMMddHHmmss
*/
public static String getStrFromDate_yyyyMMddHHmmss(Date date)
{
return getStrFromDate(date, DATE_FORMAT_yyyyMMddHHmmss);
}
/**
* 根据格式化类型获取时间相应的字符串
*
* @author ZengWenfeng
* @email 117791303@QQ.COM
* @date 2020.06.01
* @param date
* @param format
* @return yyyyMMddHHmmssSSS
*/
public static String getStrFromDate_yyyyMMddHHmmssSSS(Date date)
{
return getStrFromDate(date, DATE_FORMAT_yyyyMMddHHmmssSSS);
}
/**
* 根据格式化类型获取时间相应的字符串
*
* @author ZengWenfeng
* @email 117791303@QQ.COM
* @date 2020.06.01
* @param date
* @param format
* @return ddHHmmss
*/
public static String getStrFromDate_HHmmss(Date date)
{
return getStrFromDate(date, DATE_FORMAT_HHmmss);
}
/**
* 根据格式化类型获取时间相应的字符串
*
* @author ZengWenfeng
* @email 117791303@QQ.COM
* @date 2020.06.01
* @param date
* @param format
* @return yyyyMMdd
*/
public static String getStrFromDate_yyyyMMdd(Date date)
{
return getStrFromDate(date, DATE_FORMAT_yyyyMMdd);
}
/**
* 根据格式化类型获取时间相应的字符串
*
* @author ZengWenfeng
* @email 117791303@QQ.COM
* @date 2020.06.01
* @param date
* @param format
* @return yyyyMMdd
*/
public static String getStrFromDate_yyyy_MM_dd(Date date)
{
return getStrFromDate(date, DATE_FORMAT_yyyy_MM_dd);
}
/**
* 判断给定日期是否是工作日
*
* @author ZengWenfeng
* @date 2020.06.17
* @param date
* @return
*/
public static boolean isWorkDay(Date date)
{
//
boolean isWorkDay = false;
//
Calendar c = Calendar.getInstance();
c.setTime(date);
// 1、7 周日、周六不是工作日
if (c.get(Calendar.DAY_OF_WEEK) == Calendar.SUNDAY || c.get(Calendar.DAY_OF_WEEK) == Calendar.SATURDAY)
{
isWorkDay = false;
}
// 2\3\4\5\6 周一、周二、周三、周四、周五是工作日
else
{
isWorkDay = true;
}
//
return isWorkDay;
}
/**
* 判断给定日期是否是工作日
*
* @author ZengWenfeng
* @date 2020.06.17
* @param date 当前输入日期
* @param listHoliday 节假日调休日列表
* @return
*/
public static boolean isWorkDay(Date date, List<Date> listHoliday)
{
//
boolean isWorkDay = isWorkDay(date);
//
if (listHoliday != null && listHoliday.size() > 0)
{
for (int i = 0; i < listHoliday.size(); i++)
{
Date curDate = listHoliday.get(i);
if (curDate == null)
{
continue;
}
// 比较相等,则假期
if (getStrFromDate_yyyyMMdd(curDate).equals(getStrFromDate_yyyyMMdd(date)))
{
isWorkDay = false;
}
}
}
//
return isWorkDay;
}
/**
*
*
* @param startDate
* @param cnt
* @return
*/
public static Date getTomorrow(Date startDate)
{
Calendar c = Calendar.getInstance();
c.setTime(startDate);
c.add(Calendar.DATE, 1);
return c.getTime();
}
/**
* 获取当前时间加上(24小时 * ratio)后的时间
*
* @author ZengWenfeng
* @date 2020.07.04
* @param startDate
* @param ratio
* @return
*/
public static Date getNewTime(Date startDate, double ratio)
{
//
Double d = 24 * 60 * 60 * ratio;
int n = d.intValue();
//
int _day = n / (24 * 60 * 60);
int _hour = (n - _day * 24 * 60 * 60) / (60 * 60);
int _minute = (n - _day * 24 * 60 * 60 - _hour * 60 * 60) / 60;
int _second = n - _day * 24 * 60 * 60 - _hour * 60 * 60 - _minute * 60;
//
Calendar c = Calendar.getInstance();
c.setTime(startDate);
c.add(Calendar.DATE, _day);
c.add(Calendar.HOUR, _hour);
c.add(Calendar.MINUTE, _minute);
c.add(Calendar.SECOND, _second);
//
return c.getTime();
}
/**
* 获取当前时间加上(24小时 * ratio)后的时间
*
* @author ZengWenfeng
* @date 2020.07.04
* @param startDate
* @param ratio
* @return
*/
public static Date getNewTime2(Date startDate, double ratio)
{
//
Double d = 24 * 60 * 60 * ratio;
int n = d.intValue();
//
Calendar c = Calendar.getInstance();
c.setTime(startDate);
c.add(Calendar.SECOND, n);
//
return c.getTime();
}
/**
* 调整偏离值
*
* @param startDate
* @param cnt
* @param listHoliday
* @return
*/
public static int adjustOffset(Date startDate, int cnt, List<Date> listHoliday)
{
if (isWorkDay(startDate, listHoliday))
{
return cnt + 1;
}
else
{
return cnt;
}
}
/**
* 计算下一个工作日
*
* @author ZengWenfeng
* @email 117791303@QQ.COM
* @date 2020.06.01
* @param startDate
* @param cnt
* @return
*/
public static Date getNextWorkDate(Date startDate, int cnt)
{
if (isWorkDay(startDate))
{
cnt = cnt - 1;
if (cnt == 0)
{
return startDate;
}
else
{
getNextWorkDate(getTomorrow(startDate), cnt);
}
}
else
{
getNextWorkDate(getTomorrow(startDate), cnt);
}
//
return startDate;
}
/**
* 计算下一个工作日
*
* @author ZengWenfeng
* @email 117791303@QQ.COM
* @date 2020.06.01
* @param startDate
* @param cnt
* @param listHoliday
* @return
*/
public static Date getNextWorkDate(Date startDate, int cnt, List<Date> listHoliday)
{
//
if (isWorkDay(startDate, listHoliday))
{
cnt = cnt - 1;
if (cnt == 0)
{
return startDate;
}
startDate = getTomorrow(startDate);
startDate = getNextWorkDate(startDate, cnt, listHoliday);
}
else
{
startDate = getTomorrow(startDate);
startDate = getNextWorkDate(startDate, cnt, listHoliday);
}
//
return startDate;
}
/**
* 获取业务开始时间<br>
* <br>
* 假设时效区间为[083000 173059]<br>
* <br>
* 系统时间:2020.06.23 19:23<br>
* 1)2020.06.23为工作日 <br>
* 2)19:23超出时效区间换算第二天起始时间,则实际开始时间为2020.06.24 08:30<br>
* <br>
* 系统时间:2020.06.25 12:23<br>
* 1)2020.06.25为节假日,端午节 <br>
* 2)换算下一个工作日起始时间,则实际开始时间为2020.06.29 08:30<br>
* <br>
*
* @author ZengWenfeng
* @email 117791303@QQ.COM
* @date 2020.06.01
* @param curDate
* @param timelineBegin
* @param timelineEnd
* @param listHoliday
* @return
*/
public static Date getBizStartDate(Date curDate, String timelineBegin, String timelineEnd, List<Date> listHoliday)
{
//
Date nextDate = getNextWorkDate(curDate, 1, listHoliday);
//
String strCurDate = getStrFromDate_HHmmss(nextDate);
//
int intCurDate = Integer.parseInt(strCurDate);
int intTimelineBegin = Integer.parseInt(timelineBegin);
int intTimelineEnd = Integer.parseInt(timelineEnd);
//
if (intTimelineBegin <= intCurDate && intCurDate <= intTimelineEnd)
{
return nextDate;
}
else
{
return getCurDateStartTime(nextDate, timelineBegin, DATE_FORMAT_yyyyMMddHHmmss);
}
}
//-------------------------------------------------------------------------------------------------------------
//--2020.07.05 修改输入值为小数计算,输入日历列表 List<String[]> listDay = new ArrayList<String[]>();
//--{"2020-07-06", "00"} 工作日
//--{"2020-07-07", "00"} 工作日
//--{"2020-07-08", "00"} 工作日
//--{"2020-07-09", "00"} 工作日
//--{"2020-07-10", "00"} 工作日
//--{"2020-07-11", "09"} 其他(周六)
//--{"2020-07-12", "09"} 其他(周日)
//-------------------------------------------------------------------------------------------------------------
/**
* 判断给定日期是否是工作日
*
* @author ZengWenfeng
* @date 2020.06.17
* @param date 当前输入日期
* @param listDayMsg 节假日调休日列表 //--{"2020-07-06", "00"} 工作日 //--{"2020-07-07", "00"} 工作日
* //--{"2020-07-08", "00"} 工作日 //--{"2020-07-09", "00"} 工作日 //--{"2020-07-10", "00"} 工作日
* //--{"2020-07-11", "09"} 其他(周六) //--{"2020-07-12", "09"} 其他(周日)
* @return
*/
public static boolean isWorkDay2(Date date, List<String[]> listDayMsg)
{
//
boolean isWorkDay = isWorkDay(date);
//
if (listDayMsg != null && listDayMsg.size() > 0)
{
for (int i = 0; i < listDayMsg.size(); i++)
{
String[] dayMsg = listDayMsg.get(i);
if (dayMsg == null || dayMsg.length < 2)
{
continue;
}
String _date = dayMsg[0] == null ? "" : dayMsg[0];
String _dateType = dayMsg[1] == null ? "" : dayMsg[1];
// 比较相等, 类型不等于“00”,才是假日{"2020-07-06", "09"}
if (getStrFromDate_yyyy_MM_dd(date).equals(_date))
{
// private static final String DATE_TYPE_WORK = "00";//工作日
// private static final String DATE_TYPE_NEW_YEAR_S_DAY = "01";//元旦
// private static final String DATE_TYPE_SPRING_FESTIVAL = "02";//春节
// private static final String DATE_TYPE_QING_MING_FESTIVAL = "03";//清明节
// private static final String DATE_TYPE_LABOR_DAY = "04";//劳动节
// private static final String DATE_TYPE_THE_DRAGON_BOAT_FESTIVAL = "05";//端午节
// private static final String DATE_TYPE_MID_AUTUMN_FESTIVAL = "06";//中秋节
// private static final String DATE_TYPE_NATIONAL_DAY = "07";//国庆节
// private static final String DATE_TYPE_ANTI_JAPANESE_WAR_ANNIVERSARY = "08";//抗战纪念日
// private static final String DATE_TYPE_OTHER_HOLIDAY = "09";//其他
//工作日
if (DATE_TYPE_WORK.equals(_dateType))
{
isWorkDay = true;
break;
}
//假期
else if (DATE_TYPE_NEW_YEAR_S_DAY.equals(_dateType) || DATE_TYPE_NEW_YEAR_S_DAY.equals(_dateType) || DATE_TYPE_SPRING_FESTIVAL.equals(_dateType) || DATE_TYPE_QING_MING_FESTIVAL.equals(_dateType) || DATE_TYPE_LABOR_DAY.equals(_dateType) || DATE_TYPE_THE_DRAGON_BOAT_FESTIVAL.equals(_dateType) || DATE_TYPE_MID_AUTUMN_FESTIVAL.equals(_dateType) || DATE_TYPE_NATIONAL_DAY.equals(_dateType) || DATE_TYPE_ANTI_JAPANESE_WAR_ANNIVERSARY.equals(_dateType) || DATE_TYPE_OTHER_HOLIDAY.equals(_dateType))
{
isWorkDay = false;
break;
}
}
}
}
//
return isWorkDay;
}
/**
* 调整偏离值
*
* @param startDate
* @param cnt
* @param listDayMsg
* @return
*/
public static double adjustOffset2(Date startDate, double cnt, List<String[]> listDayMsg)
{
if (isWorkDay2(startDate, listDayMsg))
{
return cnt;
}
else
{
return cnt - 1;
}
}
/**
* 计算下一个工作日
*
* @author ZengWenfeng
* @email 117791303@QQ.COM
* @date 2020.06.01
* @param startDate
* @param cnt
* @param listHoliday
* @return
*/
public static Date getNextWorkDate2(Date startDate, double cnt, List<String[]> listDayMsg)
{
//如果是工作日
if (isWorkDay2(startDate, listDayMsg))
{
// 0 <= 0.3 < 1
if (cnt < 0)
{
return startDate;
}
else if (0 <= cnt && cnt < 1)
{
return getNewTime2(startDate, cnt);
}
else
{
cnt = cnt - 1;
startDate = getNextWorkDate2(getTomorrow(startDate), cnt, listDayMsg);
}
}
//不是工作日
else
{
startDate = getNextWorkDate2(getTomorrow(startDate), cnt, listDayMsg);
}
return startDate;
}
/**
* 获取业务开始时间<br>
* <br>
* 假设时效区间为[083000 173059]<br>
* <br>
* 系统时间:2020.06.23 19:23<br>
* 1)2020.06.23为工作日 <br>
* 2)19:23超出时效区间换算第二天起始时间,则实际开始时间为2020.06.24 08:30<br>
* <br>
* 系统时间:2020.06.25 12:23<br>
* 1)2020.06.25为节假日,端午节 <br>
* 2)换算下一个工作日起始时间,则实际开始时间为2020.06.29 08:30<br>
* <br>
*
* @author ZengWenfeng
* @email 117791303@QQ.COM
* @date 2020.06.01
* @param curDate
* @param timelineBegin
* @param timelineEnd
* @param listHoliday
* @return
*/
public static Date getBizStartDate2(Date curDate, String timelineBegin, String timelineEnd, List<String[]> listDayMsg)
{
// 工作日
if (isWorkDay2(curDate, listDayMsg))
{
// 获取当前时间 2020.06.24 14:12:12
String strCurDate = getStrFromDate_HHmmss(curDate);
//
int intCurDate = Integer.parseInt(strCurDate);
int intTimelineBegin = Integer.parseInt(timelineBegin);
int intTimelineEnd = Integer.parseInt(timelineEnd);
// 2020.06.24 08:30:00 <= 2020.06.24 14:12:12 <= 2020.06.24 17:29:59
if (0 <= intCurDate && intCurDate < intTimelineBegin)
{
return getCurDateStartTime(curDate, timelineBegin, DATE_FORMAT_yyyyMMddHHmmss);
}
else if (intTimelineBegin <= intCurDate && intCurDate <= intTimelineEnd)
{
//2020.06.24 14:12:12
return curDate;
}
// 2020.06.24 18:29:59
else if (intTimelineEnd < intCurDate && intCurDate <= 235959)
{
//2020.06.25 08:30:00
curDate = getCurDateStartTime(curDate, timelineBegin, DATE_FORMAT_yyyyMMddHHmmss);
curDate = getTomorrow(curDate);
curDate = getBizStartDate2(curDate, timelineBegin, timelineEnd, listDayMsg);
}
else
{
return curDate;
}
}
//节假日
else
{
curDate = getCurDateStartTime(curDate, timelineBegin, DATE_FORMAT_yyyyMMddHHmmss);
curDate = getTomorrow(curDate);
curDate = getBizStartDate2(curDate, timelineBegin, timelineEnd, listDayMsg);
}
return curDate;
}
/**
* 获取当前系统时间
*
* @author xucy
* @return
*/
public static Date getCurrDate()
{
Date currDate = null;
//流程初始节点
SimpleDateFormat sdf2 = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
try
{
currDate = sdf2.parse(sdf2.format(new Date()));
}
catch (Exception e)
{
e.printStackTrace();
}
return currDate;
}
/**
* 仅用于测试
*
* @author ZengWenfeng
* @email 117791303@QQ.COM
* @date 2020.06.01
* @param args
*/
public static void main(String[] args)
{
List<String[]> listDayMsg = new ArrayList<String[]>();
String[] arrStr = new String[2];
arrStr[0] = "2020-06-25";
arrStr[1] = DATE_TYPE_THE_DRAGON_BOAT_FESTIVAL;
listDayMsg.add(arrStr);
arrStr = new String[2];
arrStr[0] = "2020-06-26";
arrStr[1] = DATE_TYPE_THE_DRAGON_BOAT_FESTIVAL;
listDayMsg.add(arrStr);
arrStr = new String[2];
arrStr[0] = "2020-06-28";
arrStr[1] = DATE_TYPE_WORK;
listDayMsg.add(arrStr);
Date d9 = parseStrToDate_yyyyMMddHHmmss("20200628083922");
System.out.println("d9 : " + d9);
boolean b9 = isWorkDay2(d9, listDayMsg);
System.out.println("是否工作日 : " + (b9 ? "Y" : "N"));
Date _realStartDate9 = getBizStartDate2(d9, "083000", "173059", listDayMsg);
System.out.println("业务开始时间 : " + getStrFromDate_yyyyMMddHHmmss(_realStartDate9));
System.out.println("实际截止时间 : " + getNextWorkDate2(_realStartDate9, 1.1, listDayMsg));
}
}