常用工具类总结
日期日历星期周六日
/** * 判断是不是中国法定节假日 包含以下日期: 注意了 不包含清明节、中秋节、端午节,因为是农历无法自动设置 * 一、元旦:1月1日至3日 * 二、春节: 7天 * 三、清明节:无 * 四、劳动节:5月1日至5日 * 五、端午节:无 * 六、中秋节:无 * 七、国庆节:10月1日至5日 */ public static Boolean isHoliday(Date date) { Calendar cal = Calendar.getInstance(); cal.setTime(date); int mon = cal.get(Calendar.MONTH) + 1; int day = cal.get(Calendar.DATE); List<int[]> normalHoliday = new ArrayList<>(); // 元旦 normalHoliday.add(new int[]{1, 1}); // 劳动节 normalHoliday.add(new int[]{5, 1}); normalHoliday.add(new int[]{5, 2}); normalHoliday.add(new int[]{5, 3}); normalHoliday.add(new int[]{5, 4}); normalHoliday.add(new int[]{5, 5}); // 国庆节 normalHoliday.add(new int[]{10, 1}); normalHoliday.add(new int[]{10, 2}); normalHoliday.add(new int[]{10, 3}); normalHoliday.add(new int[]{10, 4}); normalHoliday.add(new int[]{10, 5}); for (int[] normalItem : normalHoliday) { if (mon == normalItem[0] && day == normalItem[1]) { return true; } } cal.set(Calendar.HOUR_OF_DAY, +24); for (int i = 0; i < 7; i++) { ChineseDate theDate = new ChineseDate(cal.getTime()); String dateName = theDate.getFestivals(); cal.set(Calendar.HOUR_OF_DAY, -24); if (dateName.contains("春节")) { System.out.println("是春节"); return true; } } return false; }
/** * @Author: qiaochengqiang * @Date: 2022/7/13 * @Description: 将Date格式转换为String 方便比较 计算每个月的工作日和休息日 **/ public static Map<String, List<String>> getAllWorkDateStr(Date date){ Map<String, List<String>> map = new HashMap<>(); List<String> workDays = new ArrayList<>(); List<String> weekDays = new ArrayList<>(); Calendar cal = Calendar.getInstance(); cal.setTime(date); int year = cal.get(Calendar.YEAR); int month = cal.get(Calendar.MONTH) + 1; cal.set(Calendar.DATE, 1); SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd"); while (cal.get(Calendar.YEAR) == year && cal.get(Calendar.MONTH) < month) { int day = cal.get(Calendar.DAY_OF_WEEK); if (!(day == Calendar.SUNDAY || day == Calendar.SATURDAY)) { String format1 = ""; try { format1 = format.format((Date) cal.getTime().clone()); } catch (Exception e) { e.printStackTrace(); } workDays.add(format1); } else { String format1 = ""; try { format1 = format.format((Date) cal.getTime().clone()); } catch (Exception e) { e.printStackTrace(); } weekDays.add(format1); } cal.add(Calendar.DATE, 1); } map.put("workDays", workDays); map.put("weekDays", weekDays); return map; } //获取某个时间段的所有日期 public static List<String> findDates(String dBegin, String dEnd) throws ParseException, java.text.ParseException { //日期工具类准备 SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd"); //设置开始时间 Calendar calBegin = Calendar.getInstance(); calBegin.setTime(format.parse(dBegin)); //设置结束时间 Calendar calEnd = Calendar.getInstance(); calEnd.setTime(format.parse(dEnd)); //装返回的日期集合容器 List<String> Datelist = new ArrayList<String>(); //将第一个月添加里面去 Datelist.add(format.format(calBegin.getTime())); // 每次循环给calBegin日期加一天,直到calBegin.getTime()时间等于dEnd while (format.parse(dEnd).after(calBegin.getTime())) { // 根据日历的规则,为给定的日历字段添加或减去指定的时间量 calBegin.add(Calendar.DAY_OF_MONTH, 1); Datelist.add(format.format(calBegin.getTime())); } return Datelist; } /** * * @param nowTime 当前时间 * @param startTime 开始时间 * @param endTime 结束时间 * @return * @author sunran 判断当前时间在时间区间内 */ public static boolean isEffectiveDate(Date nowTime, Date startTime, Date endTime) { if (nowTime.getTime() == startTime.getTime() || nowTime.getTime() == endTime.getTime()) { return true; } Calendar date = Calendar.getInstance(); date.setTime(nowTime); Calendar begin = Calendar.getInstance(); begin.setTime(startTime); Calendar end = Calendar.getInstance(); end.setTime(endTime); if (date.after(begin) && date.before(end)) { return true; } else { return false; } } // 获取每月的第一天 public static long getDayOne() throws ParseException { SimpleDateFormat format=new SimpleDateFormat("yyyy-MM-dd"); //获取当天日期 SimpleDateFormat sdf11 = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); Calendar c = Calendar.getInstance(); c.add(Calendar.MONTH, 0); c.set(Calendar.DAY_OF_MONTH,1); String firstday= format.format(c.getTime()); Date onTime = sdf11.parse(firstday+" 00:00:00"); return DateUtils.getMillis(onTime); } // 获取每月的最后一天 public static long getDayEnd() throws ParseException { SimpleDateFormat format=new SimpleDateFormat("yyyy-MM-dd"); //获取当天日期 SimpleDateFormat sdf11 = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); Calendar c = Calendar.getInstance(); c.add(Calendar.MONTH, 0); c.set(Calendar.DAY_OF_MONTH,1); String firstday= format.format(c.getTime()); Date onTime = sdf11.parse(firstday+" 00:00:00"); return DateUtils.getMillis(onTime); } /** * String类型 转换为Date, 如果参数长度为10 转换格式”yyyy-MM-dd“ 如果参数长度为19 转换格式”yyyy-MM-dd * HH:mm:ss“ * @param text String类型的时间值 */ public void setAsText(String text) throws IllegalArgumentException { if (StringUtils.hasText(text)) { try { if (text.indexOf(":") == -1 && text.length() == 10) { setValue(DateUtils.date_sdf.get().parse(text)); } else if (text.indexOf(":") > 0 && text.length() == 19) { setValue(DateUtils.datetimeFormat.get().parse(text)); } else { throw new IllegalArgumentException("Could not parse date, date format is error "); } } catch (ParseException ex) { IllegalArgumentException iae = new IllegalArgumentException("Could not parse date: " + ex.getMessage()); iae.initCause(ex); throw iae; } } else { setValue(null); } }
根据开始时间、工作天数(可小数)、每天工作时长、上班时间、下班时间 计算结束时间(自动跳过周六日以及法定节假日)
public static void main(String[] args) { String startTime = "2022-07-14 9:00:00"; //String startTime = "2022-09-09 9:00:00"; Double makeTianshi = 4.1; //36 - 9 = 27 getEndDateStr(startTime,makeTianshi,0,0,0); } /** * @Author: qiaochengqiang * @Date: 2022/7/14 * @Description: 根据开始时间、工作天数(可小数)、每天工作时长、上班时间、下班时间 计算结束时间(自动跳过周六日以及法定节假日) * 1、将工作时长转换为秒,在开始时间进行加运算,得到第一次的结束时间 * 2、判断第一次的结束时间是否在下班之前,如果在,则直接作为最后结果 * 3、第一次的结束时间在当天下班后,使用当天的下班时间减去当天的开始时间,计算剩余的工作量 * 4、将剩余工作量转换成天,并向下取整,然后根据当天的上班时间加1再加剩余天数,相加时一定要判断是否为休息日 * 5、剩余工作量减去加的天数减一得到剩余时间 * 6、加上最后的剩余时间,判断是否在下班之前,在下班之前则得到最后结果 * 7、得不到结果则继续加1 * 8、加一之后再次判断是否在休息日,如果不是则得到最后结果 * 切记 按秒计算即可,到毫秒时数据总是丢失精度,莫名其妙丢失一秒左右,当计算时变为除不尽的小数,取整就会出错!!! **/ public static String getEndDateStr(String startTime,Double makeTianshi,int workingHours,int workShift,int closingTime){ String endTime = ""; if (workingHours == 0){ //工作时长 如果没有设置 默认为9个小时 workingHours = 9; } if (workShift == 0){ //上班时间 没有设置 默认是当天 9点上班 workShift = 9; } if (closingTime == 0){ //下班时间 没有设置 默认是当天 18点下班 closingTime = 18; } //2022/7/12 将时间转换为秒 每天9个小时 int makeTianshiSecond = (int) (makeTianshi * workingHours * 60 * 60); //2022/7/12 日历类 提供添加时间 //任务开始时间 Calendar calendarStart = Calendar.getInstance(); //工作日下班时间 开始时间的当天下班时间 Calendar calendarGoOffWork = Calendar.getInstance(); //工作日上班时间 开始时间的当天上班时间 Calendar calendarGoToWork = Calendar.getInstance(); SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); SimpleDateFormat dateFormat01 = new SimpleDateFormat("yyyy-MM-dd"); Date start = new Date(); try { start = dateFormat.parse(startTime); calendarStart.setTime(start); calendarGoOffWork.set(start.getYear()+1900,start.getMonth(),start.getDate()); calendarGoToWork.set(start.getYear()+1900,start.getMonth(),start.getDate()); //将工作日的下班时间 calendarGoOffWork.set(Calendar.HOUR_OF_DAY, closingTime);//控制时 calendarGoOffWork.set(Calendar.MINUTE, 0);//控制分 calendarGoOffWork.set(Calendar.SECOND, 0);//控制秒 String format01 = dateFormat.format(calendarGoOffWork.getTime()); System.out.println("calendarGoOffWork:>>>>"+format01); //工作日上班时间 calendarGoToWork.set(Calendar.HOUR_OF_DAY, workShift);//控制时 calendarGoToWork.set(Calendar.MINUTE, 0);//控制分 calendarGoToWork.set(Calendar.SECOND, 0);//控制秒 String format02 = dateFormat.format(calendarGoOffWork.getTime()); //2022/7/13 一个月21.75天 每天9个小时 需要扣除 上下班以外时间以及法定节假日时间 上下班时间 9:00 - 18:00 String formatCalendarStart01 = dateFormat.format(calendarStart.getTime()); System.out.println("calendarStart添加秒数之前:>>>>"+formatCalendarStart01); calendarStart.add(Calendar.SECOND, makeTianshiSecond); String formatCalendarStart02 = dateFormat.format(calendarStart.getTime()); System.out.println("calendarStart添加秒数之后:>>>>"+formatCalendarStart02); //2022/7/13 将添加之后的时间跟下班时间进行比较 超出下班时间的 设置到下一天 boolean before = calendarStart.before(calendarGoOffWork); //如果结束时间 在当天下班前 直接进行赋值如果结果一样 则证明正好等于下班的时间 if (before) { Date makeEndDate = calendarStart.getTime(); endTime = dateFormat.format(makeEndDate); System.out.println("最终结果>>>>>>>>>>>"+endTime); } else { //结束时间在下班后 进行处理 // 将下班时间 和 计划开始时间 转换为毫秒 String format03 = dateFormat.format(calendarGoOffWork.getTime()); //需要重新赋值 因为上边代码已经进行添加处理了 所以需要进行重置 calendarStart.setTime(start); String format04 = dateFormat.format(calendarStart.getTime()); System.out.println("超出一天后的计算>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>"); System.out.println("calendarGoOffWork>>>>>>>>>>>>>"+format03); System.out.println("calendarStart>>>>>>>>>>>>>"+format04); long goOffWorkTimeInMillis = calendarGoOffWork.getTimeInMillis(); long calendarStartTimeInMillis = calendarStart.getTimeInMillis(); //当天的剩余时间 当天下班时间 - 开始时间 long remainingDuration = goOffWorkTimeInMillis - calendarStartTimeInMillis; //工作时长 剩余时间 将总花费时长 - 当天剩余的时间 //转换为秒 remainingDuration = makeTianshiSecond - (int)remainingDuration/1000; System.out.println("第一次剩余时间》》》》》》》》》》"+remainingDuration/60/60); //2022/7/13 根据剩余时间 计算出需要几天 每天按照工作时长计算 double l = remainingDuration / 60 / 60 / workingHours; System.out.println(l); int dayNums = (int) Math.floor(l); System.out.println("day>>>>>>>>>>>>>"+dayNums); Map<String, List<String>> workDates = DateUtils.getAllWorkDateStr(start); List<String> workDays = workDates.get("workDays"); List<String> weekDays = workDates.get("weekDays"); if (dayNums > 1) { //因为当天已经无法完成 所以首先要根据每天的工作上班时间加一天再加dayNums天 for (int i = 0; i < dayNums; i++) { //2022/7/14 逐个添加 添加后判断是否为周末或者法定节假日 calendarGoToWork.add(Calendar.DAY_OF_YEAR, 1); Date time = calendarGoToWork.getTime(); String str = dateFormat01.format(time); System.out.println("str1 >>>>>>>>>>>>>>"+str); //如果为法定节假日 再加1 while (weekDays.contains(str) || DateUtils.inHoliday(str)) { calendarGoToWork.add(Calendar.DAY_OF_YEAR, 1); time = calendarGoToWork.getTime(); str = dateFormat01.format(time); System.out.println("str2 >>>>>>>>>>>>>>"+str); } } //因为现在是年月日格式 如果结束时间为2022-07-14 也需要 加上九个小时 所以将剩余天数减1 计算出剩余时间 在下边加上即可 dayNums -= 1; remainingDuration = remainingDuration - dayNums*workingHours*60*60; System.out.println("第二次剩余时间》》》》》》》》》》"+remainingDuration/60/60); }else { //因为当天已经无法完成 所以首先要根据每天的工作上班时间加一天 calendarGoToWork.add(Calendar.DAY_OF_YEAR, 1); //如果今天是月末最后一天 日历类 会自动跳到下个月 已经处理好了 将剩余时间进行添加 } System.out.println("calendarGoToWork + N 天之后>>>>>>>>>>>>>"+dateFormat.format(calendarGoToWork.getTime())); //然后再将剩余时间 按照秒相加 System.out.println("添加了秒:"+remainingDuration/60); calendarGoToWork.add(Calendar.SECOND, (int) (remainingDuration)); System.out.println("calendarGoToWork + N 天之后 再加秒>>>>>>>>>>>>>"+dateFormat.format(calendarGoToWork.getTime())); //得到最终的结束时间 新增之后的结果可能会超过下班时间 所以下边还需要进行处理 Date makeEndDate = calendarGoToWork.getTime(); //因为获取的休息日和工作日 都是按照 yyyy-MM-dd 这个格式返回的 所以将最后的结束时间进行转换 方便对比 String makeEndDateStr = dateFormat01.format(makeEndDate); System.out.println("makeEndDate>>>>>>>>>>>>>"+dateFormat.format(makeEndDate)); //2022/7/14 根据最终结果 判断是否已经下班 如果下班自动加1 //下班时间根据最终日期重新赋值 calendarGoOffWork.set(makeEndDate.getYear()+1900,makeEndDate.getMonth(),makeEndDate.getDate(),closingTime,0,0); System.out.println("calendarGoToWork1111111111111111111111"+dateFormat.format(calendarGoToWork.getTime())); System.out.println("calendarGoOffWork222222222222222222222"+dateFormat.format(calendarGoOffWork.getTime())); int i = calendarGoToWork.compareTo(calendarGoOffWork); if (i > 0){ goOffWorkTimeInMillis = calendarGoOffWork.getTimeInMillis(); calendarStartTimeInMillis = calendarGoToWork.getTimeInMillis(); //剩余时间 计算之后的最终时间 - 当天下班时间 remainingDuration = calendarStartTimeInMillis - goOffWorkTimeInMillis; calendarGoToWork.set(makeEndDate.getYear()+1900,makeEndDate.getMonth(),makeEndDate.getDate(),workShift,0,0); calendarGoToWork.add(Calendar.DAY_OF_YEAR, 1); calendarGoToWork.add(Calendar.SECOND, (int) (remainingDuration/1000)); makeEndDateStr = dateFormat01.format(calendarGoToWork.getTime()); } //2022/7/13 获取所有的休息日和工作日 具体格式是字符创类型的时间 格式为 yyyy-MM-dd Date goToWorkTime = new Date(); if (workDays.contains(makeEndDateStr)) { //结束时间在工作日集合中 直接进行赋值 System.out.println("最后是什么》》》》》》》"+dateFormat01.format(calendarGoToWork.getTime())); goToWorkTime = calendarGoToWork.getTime(); } else { //结束时间在休息日中 则循环加1 直到 不在休息日中 // 2022/7/13 检查是否在休息日 或者 法定节假日 while (weekDays.contains(makeEndDateStr) || DateUtils.inHoliday(makeEndDateStr)) { System.out.println("最后是什么》》》》》》》"+dateFormat01.format(calendarGoToWork.getTime())); calendarGoToWork.add(Calendar.DAY_OF_YEAR, 1); makeEndDate = calendarGoToWork.getTime(); makeEndDateStr = dateFormat01.format(makeEndDate); } goToWorkTime = calendarGoToWork.getTime(); } endTime = dateFormat.format(goToWorkTime); System.out.println("最终结果>>>>>>>>>>>"+endTime); } } catch (Exception e) { e.printStackTrace(); } return endTime; }
/** * @Author: qiaochengqiang * @Date: 2022/7/19 * @Description: 获取当月第一天或者最后一天 按照type类型 **/ public static String getMonthDay(int month,String type){ String dateStr = ""; Date date = new Date(); //月份需要加1 date.setMonth(month+1); SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd"); LocalDate localDate = LocalDate.parse(simpleDateFormat.format(date)); if ("start".equals(type)){ LocalDate firstDay = localDate.with(TemporalAdjusters.firstDayOfMonth()); // 获取当前月的第一天 dateStr = firstDay.toString(); }else if ("end".equals(type)){ LocalDate lastDay = localDate.with(TemporalAdjusters.lastDayOfMonth()); // 获取当前月的最后一天 dateStr = String.valueOf(lastDay); } return dateStr; }