专用考勤计算时间差工具类
This commit is contained in:
parent
37bedd187d
commit
908dd61ff7
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
Loading…
Reference in New Issue