专用考勤计算时间差工具类

This commit is contained in:
fl 2025-02-17 18:10:21 +08:00
parent 37bedd187d
commit 908dd61ff7
1 changed files with 218 additions and 0 deletions

View File

@ -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<String> getStrDateListBetween(String startDateString, String endDateString) {
List<String> 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<String, List<AttSourceDataBean>> groupedItems, AttGroupBean attGroupBean) {
for (Map.Entry<String, List<AttSourceDataBean>> entry : groupedItems.entrySet()) {
String key = entry.getKey();
List<AttSourceDataBean> 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<AttSourceDataBean> 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;
}
}
}