From 908dd61ff7774f1f9b0ae5de3b5a7e4f1fb3a636 Mon Sep 17 00:00:00 2001 From: fl <3098731433@qq.com> Date: Mon, 17 Feb 2025 18:10:21 +0800 Subject: [PATCH] =?UTF-8?q?=E4=B8=93=E7=94=A8=E8=80=83=E5=8B=A4=E8=AE=A1?= =?UTF-8?q?=E7=AE=97=E6=97=B6=E9=97=B4=E5=B7=AE=E5=B7=A5=E5=85=B7=E7=B1=BB?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../bonus/system/att/utils/AttTimeUtil.java | 218 ++++++++++++++++++ 1 file changed, 218 insertions(+) create mode 100644 bonus-modules/bonus-system/src/main/java/com/bonus/system/att/utils/AttTimeUtil.java diff --git a/bonus-modules/bonus-system/src/main/java/com/bonus/system/att/utils/AttTimeUtil.java b/bonus-modules/bonus-system/src/main/java/com/bonus/system/att/utils/AttTimeUtil.java new file mode 100644 index 0000000..f494c65 --- /dev/null +++ b/bonus-modules/bonus-system/src/main/java/com/bonus/system/att/utils/AttTimeUtil.java @@ -0,0 +1,218 @@ +package com.bonus.system.att.utils; + +import com.bonus.common.core.utils.DateUtils; +import com.bonus.system.att.entity.AttGroupBean; +import com.bonus.system.att.entity.AttSourceDataBean; +import lombok.extern.slf4j.Slf4j; + +import java.text.DateFormat; +import java.text.ParseException; +import java.text.SimpleDateFormat; +import java.time.Duration; +import java.time.LocalTime; +import java.time.format.DateTimeFormatter; +import java.time.format.DateTimeParseException; +import java.util.*; +import java.util.stream.Collectors; + +/** + * @author: fly + * @date: 2025/2/13 16:07 + * 考勤计算的时间对比工具类 + */ +@Slf4j +public class AttTimeUtil { + + + // 定义时间格式 + static DateTimeFormatter YY_MM_DD_HH_MM_SS = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"); + static DateTimeFormatter HH_MM_SS = DateTimeFormatter.ofPattern("HH:mm:ss"); + static DateFormat YY_MM_DD = new SimpleDateFormat("yyyy-MM-dd"); + + /** + * 判断打卡类型 + * 判断当前时间是否在早5点到中午12点之间,在则为上班打卡,中午12点到明天上午五点则为今天的下班打卡 + * @param currentTime + * @return + */ + public static int getAttTypeByTime(String currentTime) { + if (currentTime == null || currentTime.isEmpty()) { + // 如果输入为空或为空字符串,则返回默认值(例如2) + return 1; + } + try { + // 解析传入的时间字符串 + LocalTime time = LocalTime.parse(currentTime, YY_MM_DD_HH_MM_SS); + // 定义早上5点和中午12点的时间 + LocalTime morningStart = LocalTime.of(5, 0); + LocalTime noonEnd = LocalTime.of(12, 0); + // 判断时间是否在5:00到12:00之间 + if (time.isAfter(morningStart) && !time.isAfter(noonEnd)) { + return 1; // 在早上5点到12点之间 + } else { + return 2; // 其他时间 + } + } catch (DateTimeParseException e) { + // 如果时间格式不正确,返回默认值(例如2) + e.printStackTrace(); + log.error("判断打卡类型方法出错啦"); + return 1; + } + } + + /** + * 判断打卡时间归属于当天还是昨天 + * 将00:00:00 至 04:59:59 时间变成att_current_day上一天的 + * @param c + */ + public static void changeAttCurrentDay(AttSourceDataBean c) { + try { + // 解析传入的时间字符串 + LocalTime time = LocalTime.parse(c.getAttCurrentTime(), YY_MM_DD_HH_MM_SS); + // 定义早上5点和中午12点的时间 + LocalTime morningStart = LocalTime.of(0, 0); + LocalTime noonEnd = LocalTime.of(5, 0); + // 判断时间是否在0:00到05:00之间 + if (time.isAfter(morningStart) && !time.isAfter(noonEnd)) { + //获取前一天时间 + String afterDate = DateUtils.getAfterDate(c.getAttCurrentDay()); + c.setAttCurrentDay(afterDate); + } + }catch(Exception e){ + e.printStackTrace(); + log.error("判断打卡归属方法出错啦"); + } + + } + + + /** + * 获取两个日期之间的日期列表 + * @param startDateString + * @param endDateString + * @return + */ + public static List getStrDateListBetween(String startDateString, String endDateString) { + List dateList = new ArrayList<>(); + try { + // 解析开始日期和结束日期 + Date startDate = YY_MM_DD.parse(startDateString); + Date endDate = YY_MM_DD.parse(endDateString); + // 创建 Calendar 实例并设置为开始日期 + Calendar calendar = Calendar.getInstance(); + calendar.setTime(startDate); + // 循环直到当前日期超过结束日期 + while (!calendar.getTime().after(endDate)) { + // 将日期格式化为字符串,并添加到列表中 + dateList.add(YY_MM_DD.format(calendar.getTime())); + // 将日期加一天 + calendar.add(Calendar.DAY_OF_MONTH, 1); + } + } catch (ParseException ignored) { + } + return dateList; + } + + public static void processGroupedItems(Map> groupedItems, AttGroupBean attGroupBean) { + for (Map.Entry> entry : groupedItems.entrySet()) { + String key = entry.getKey(); + List items = entry.getValue(); + if (items.isEmpty()) { + continue; // 如果列表为空,跳过 + } + //五点之前的数据属于过来当天的下班打卡,不计入 + LocalTime noonEnd = LocalTime.of(5, 0); + // 获取上班时间并转换为 LocalTime 以便比较 + LocalTime toWorkTime = LocalTime.parse(attGroupBean.getToWorkTime(), HH_MM_SS); + // 初始化变量来保存最接近上班时间的数据项及其索引 + AttSourceDataBean closestBeforeToWork = null; + int closestIndex = -1; + // 遍历并查找最接近上班时间且 attType=2 的数据项 + //前面已经排过序了,取第一个就可以了 + for (int i = 0; i < items.size(); i++) { + AttSourceDataBean item = items.get(i); +// if("王义".equals(item.getName())){ +// System.out.println(111); +// } + if ("2".equals(item.getAttType())) { + // 只提取时间部分进行比较 + LocalTime recordTime = LocalTime.parse(item.getAttCurrentTime().substring(11), HH_MM_SS); + // 检查是否在上班时间之前并且是目前找到的最接近上班时间的 + if (recordTime.isBefore(toWorkTime) && recordTime.isAfter(noonEnd) && + (closestBeforeToWork == null || + recordTime.isAfter(LocalTime.parse(closestBeforeToWork.getAttCurrentTime().substring(11), HH_MM_SS)))) { + closestBeforeToWork = item; + closestIndex = i; + } + } + } + // 如果找到了符合条件的数据项,则移除它之前的所有数据,包括它自己 + if (closestIndex != -1) { + List filteredItems = items.stream() + .skip(closestIndex) // 跳过最接近上班时间的数据项及其之前的所有数据 + .collect(Collectors.toList()); + // 更新原始映射中的列表 + groupedItems.put(key, filteredItems); + } else { + // 如果没有找到符合条件的数据项,可以选择保留所有数据或清空列表 + } + } + } + + public static Duration calculateWorkDuration(LocalTime outTime, LocalTime inTime, AttGroupBean group) { + try { + DateTimeFormatter formatter = DateTimeFormatter.ofPattern("HH:mm:ss"); + // 解析上班、下班、午休开始、结束时间 + LocalTime offWorkTime = LocalTime.parse(group.getOffWorkTime(), formatter); + LocalTime breakStartTime = LocalTime.parse(group.getBreakStartTime(), formatter); + LocalTime breakEndTime = LocalTime.parse(group.getBreakEndTime(), formatter); + // 如果出勤时间在午休时间内,调整出勤时间为午休结束时间 + if (outTime.isAfter(breakStartTime) && outTime.isBefore(breakEndTime)) { + outTime = breakEndTime; + } + // 如果进入时间在午休时间内,调整进入时间为午休开始时间 + if (inTime.isAfter(breakStartTime) && inTime.isBefore(breakEndTime)) { + inTime = breakStartTime; + } + // 如果进入时间在下班时间内,调整进入时间为下班时间 + if (inTime.isAfter(offWorkTime)) { + inTime = offWorkTime; + } + // 计算总的工作时间 + Duration totalDuration = Duration.between(outTime, inTime); + // 如果时间段跨越了午休时间,减去午休时长 + if (outTime.isBefore(breakEndTime) && inTime.isAfter(breakStartTime)) { + Duration breakDuration = Duration.between(breakStartTime, breakEndTime); + totalDuration = totalDuration.minus(breakDuration); + } + return totalDuration; + } catch (DateTimeParseException e) { + // 处理解析异常,例如记录日志或返回默认值 + System.err.println("时间解析错误: " + e.getMessage()); + return null; // 或者返回一个默认的 LocalDateTime + } + } + + /** + * 判断当前时间是否大于几点 + * @param hour 时 + * @param minute 分 + * @return + */ + public static boolean timeCheck(int hour,int minute) { + // 获取当前时间 + LocalTime now = LocalTime.now(); + // 定义目标时间 hour:minutes + LocalTime targetTime = LocalTime.of(hour, minute); + + // 判断当前时间是否大于 + if (now.isAfter(targetTime)) { + System.out.println("当前时间已超过 "+hour+":"+minute+"!"); + return true; + }else { + System.out.println("当前时间还未到 "+hour+":"+minute+"!"); + return false; + } + } + +}