1、增加时间范围取值

This commit is contained in:
llllon 2025-09-05 15:57:11 +08:00
parent 1c56a38f81
commit 95c00610f6
5 changed files with 140 additions and 107 deletions

View File

@ -201,6 +201,7 @@ public class ProductionDataSyncServiceImpl implements DataSyncService {
boolean hasMore;
RDSAPI rdsapi = null;
SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
SimpleDateFormat simpleDateFormat2 = new SimpleDateFormat("yyyy-MM-dd");
try {
rdsapi = SDK.getCCAPI().getRDSAPI(ccId);
@ -230,8 +231,8 @@ public class ProductionDataSyncServiceImpl implements DataSyncService {
for (int i = 0; i < timeRanges.size(); i++) {
Date[] range = timeRanges.get(i);
String startDate = simpleDateFormat.format(range[0]);
String endDate = simpleDateFormat.format(range[1]);
String startDate = simpleDateFormat2.format(range[0]);
String endDate = simpleDateFormat2.format(range[1]);
LOGGER.info("正在处理第 {} 个时间区间: {} 至 {}", i + 1, startDate, endDate);
if ("ORACLE".equalsIgnoreCase(DBname)) {
@ -345,8 +346,11 @@ public class ProductionDataSyncServiceImpl implements DataSyncService {
// 如果时间字段存在添加时间范围条件
if (timeField != null && !timeField.isEmpty()) {
conditionBuilder.append(" AND ")
.append(timeField)
.append(" BETWEEN ? AND ? ORDER BY " + timeField + "");
.append(timeField).append(" >= ?")
.append(" AND ")
.append(timeField).append(" < ?")
.append(" ORDER BY ").append(timeField);
//.append(" BETWEEN ? AND ? ORDER BY " + timeField + "");
if (jezd != null && !jezd.isEmpty()) {
conditionBuilder.append(", " + jezd + " ");
}
@ -354,8 +358,12 @@ public class ProductionDataSyncServiceImpl implements DataSyncService {
}
} else if (timeField != null && !timeField.isEmpty()) {
// 没有分区字段但时间字段存在使用时间范围条件
conditionBuilder.append(timeField)
.append(" BETWEEN ? AND ? ORDER BY " + timeField + "");
/*conditionBuilder.append(timeField)
.append(" BETWEEN ? AND ? ORDER BY " + timeField + "");*/
conditionBuilder.append(timeField).append(" >= ?")
.append(" AND ")
.append(timeField).append(" < ?")
.append(" ORDER BY ").append(timeField);
if (jezd != null && !jezd.isEmpty()) {
conditionBuilder.append(", " + jezd + " ");
}
@ -455,61 +463,73 @@ public class ProductionDataSyncServiceImpl implements DataSyncService {
}
/**
* 将时间范围拆分为多个区间确保区间连续且不重叠
* @param startDate 开始时间yyyy-MM-dd格式时间部分为00:00:00
* @param endDate 结束时间yyyy-MM-dd格式时间部分为00:00:00
* @param daysInterval 间隔天数
* @return 时间区间列表每个区间的结束时间调整为23:59:59以确保覆盖完整日期
* 将时间范围拆分为多个区间确保区间连续下一个区间的开始时间 = 上一个区间的结束时间且无重叠
* 所有日期均强制转换为 yyyy-MM-dd 格式时间部分固定为 00:00:00
* @param startDate 开始时间建议传入 yyyy-MM-dd 格式若含时间部分会自动截断为 00:00:00
* @param endDate 结束时间建议传入 yyyy-MM-dd 格式若含时间部分会自动截断为 00:00:00
* @param daysInterval 每个区间的间隔天数例如传入 7 表示每个区间覆盖 7 2024-01-01~2024-01-08
* @return 时间区间列表每个元素为 [开始时间, 结束时间]均为 yyyy-MM-dd 00:00:00 格式
*/
private static List<Date[]> splitTimeRange(Date startDate, Date endDate, int daysInterval) {
List<Date[]> ranges = new ArrayList<>();
public static List<Date[]> splitTimeRange(Date startDate, Date endDate, int daysInterval) {
// 1. 入参合法性校验避免无效区间或负间隔
if (startDate == null || endDate == null) {
throw new IllegalArgumentException("开始时间和结束时间不可为 null");
}
if (daysInterval < 1) {
throw new IllegalArgumentException("间隔天数必须大于等于 1");
}
// 2. 初始化日历并强制截断时间部分确保所有日期都是 yyyy-MM-dd 00:00:00
Calendar calendar = Calendar.getInstance();
setTimeToStartOfDay(calendar); // 先重置时间再设日期避免原日期含时间的影响
calendar.setTime(startDate);
Date currentStart = calendar.getTime();
// 调整结束时间以包含完整日期
Calendar endCal = Calendar.getInstance();
setTimeToStartOfDay(endCal);
endCal.setTime(endDate);
endCal.set(Calendar.HOUR_OF_DAY, 23);
endCal.set(Calendar.MINUTE, 59);
endCal.set(Calendar.SECOND, 59);
endCal.set(Calendar.MILLISECOND, 999);
Date adjustedEndDate = endCal.getTime();
while (calendar.getTime().before(adjustedEndDate)) {
// 区间开始时间当前日期的00:00:00
Date rangeStart = calendar.getTime();
// 增加间隔天数-1天然后设置为23:59:59作为区间结束时间
calendar.add(Calendar.DAY_OF_MONTH, daysInterval - 1);
calendar.set(Calendar.HOUR_OF_DAY, 23);
calendar.set(Calendar.MINUTE, 59);
calendar.set(Calendar.SECOND, 59);
calendar.set(Calendar.MILLISECOND, 999);
Date rangeEnd = calendar.getTime();
// 如果区间结束时间超过最终结束时间使用最终结束时间
if (rangeEnd.after(adjustedEndDate)) {
rangeEnd = adjustedEndDate;
Date finalEnd = endCal.getTime();
// 额外校验开始时间不能晚于结束时间
if (currentStart.after(finalEnd)) {
throw new IllegalArgumentException("开始时间不能晚于结束时间");
}
List<Date[]> ranges = new ArrayList<>();
// 3. 循环拆分区间核心逻辑确保下一个开始 = 上一个结束
while (true) {
// 计算当前区间的结束时间开始时间 + 间隔天数 2024-01-01 + 7天 = 2024-01-08
calendar.add(Calendar.DAY_OF_MONTH, daysInterval);
setTimeToStartOfDay(calendar); // 再次确保时间部分为 00:00:00
Date currentEnd = calendar.getTime();
// 处理最后一个区间若计算的结束时间超过最终结束时间强制对齐到 finalEnd
if (currentEnd.after(finalEnd)) {
currentEnd = finalEnd;
}
ranges.add(new Date[]{rangeStart, rangeEnd});
// 准备下一个区间的开始时间当前区间结束时间的下一天00:00:00
calendar.add(Calendar.MILLISECOND, 1); // 加1毫秒到下一天
calendar.set(Calendar.HOUR_OF_DAY, 0);
calendar.set(Calendar.MINUTE, 0);
calendar.set(Calendar.SECOND, 0);
calendar.set(Calendar.MILLISECOND, 0);
// 如果已经达到或超过结束时间则退出循环
if (calendar.getTime().after(adjustedEndDate)) {
// 添加当前区间 [currentStart, currentEnd]
ranges.add(new Date[]{currentStart, currentEnd});
// 终止条件当前区间的结束时间已等于最终结束时间无需继续拆分
if (currentEnd.equals(finalEnd)) {
break;
}
// 准备下一个区间的开始时间当前结束时间满足连续要求
currentStart = currentEnd;
}
return ranges;
}
/**
* 工具方法 Calendar 的时间部分强制设置为当天 00:00:00截断时分秒毫秒
* @param calendar 待处理的 Calendar 实例 null
*/
private static void setTimeToStartOfDay(Calendar calendar) {
if (calendar == null) {
throw new IllegalArgumentException("Calendar 实例不可为 null");
}
calendar.set(Calendar.HOUR_OF_DAY, 0); // 24小时制0 表示凌晨 0
calendar.set(Calendar.MINUTE, 0); // 分钟设为 0
calendar.set(Calendar.SECOND, 0); // 秒设为 0
calendar.set(Calendar.MILLISECOND, 0); // 毫秒设为 0
}
/**
* 字段映射转换
* @param source 源数据记录

View File

@ -233,6 +233,7 @@ public class PurchaseDataSyncServiceImpl implements DataSyncService {
boolean hasMore;
RDSAPI rdsapi = null;
SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
SimpleDateFormat simpleDateFormat2 = new SimpleDateFormat("yyyy-MM-dd");
try {
rdsapi = SDK.getCCAPI().getRDSAPI(ccId);
DBUtils.SUPPLY supply = rdsapi.getSupply();
@ -260,8 +261,8 @@ public class PurchaseDataSyncServiceImpl implements DataSyncService {
for (int i = 0; i < timeRanges.size(); i++) {
Date[] range = timeRanges.get(i);
String startDate = simpleDateFormat.format(range[0]);
String endDate = simpleDateFormat.format(range[1]);
String startDate = simpleDateFormat2.format(range[0]);
String endDate = simpleDateFormat2.format(range[1]);
LOGGER.info("正在处理第 {} 个时间区间: {} 至 {}", i + 1, startDate, endDate);
if ("ORACLE".equalsIgnoreCase(DBname)) {
@ -374,8 +375,11 @@ public class PurchaseDataSyncServiceImpl implements DataSyncService {
// 如果时间字段存在添加时间范围条件
if (timeField != null && !timeField.isEmpty()) {
conditionBuilder.append(" AND ")
.append(timeField)
.append(" BETWEEN ? AND ? ORDER BY " + timeField + "");
.append(timeField).append(" >= ?")
.append(" AND ")
.append(timeField).append(" < ?")
.append(" ORDER BY ").append(timeField);
//.append(" BETWEEN ? AND ? ORDER BY " + timeField + "");
if (jezd != null && !jezd.isEmpty()) {
conditionBuilder.append(", " + jezd + " ");
}
@ -383,8 +387,12 @@ public class PurchaseDataSyncServiceImpl implements DataSyncService {
}
} else if (timeField != null && !timeField.isEmpty()) {
// 没有分区字段但时间字段存在使用时间范围条件
conditionBuilder.append(timeField)
.append(" BETWEEN ? AND ? ORDER BY " + timeField + "");
/*conditionBuilder.append(timeField)
.append(" BETWEEN ? AND ? ORDER BY " + timeField + "");*/
conditionBuilder.append(timeField).append(" >= ?")
.append(" AND ")
.append(timeField).append(" < ?")
.append(" ORDER BY ").append(timeField);
if (jezd != null && !jezd.isEmpty()) {
conditionBuilder.append(", " + jezd + " ");
}
@ -437,61 +445,73 @@ public class PurchaseDataSyncServiceImpl implements DataSyncService {
}
/**
* 将时间范围拆分为多个区间确保区间连续且不重叠
* @param startDate 开始时间yyyy-MM-dd格式时间部分为00:00:00
* @param endDate 结束时间yyyy-MM-dd格式时间部分为00:00:00
* @param daysInterval 间隔天数
* @return 时间区间列表每个区间的结束时间调整为23:59:59以确保覆盖完整日期
* 将时间范围拆分为多个区间确保区间连续下一个区间的开始时间 = 上一个区间的结束时间且无重叠
* 所有日期均强制转换为 yyyy-MM-dd 格式时间部分固定为 00:00:00
* @param startDate 开始时间建议传入 yyyy-MM-dd 格式若含时间部分会自动截断为 00:00:00
* @param endDate 结束时间建议传入 yyyy-MM-dd 格式若含时间部分会自动截断为 00:00:00
* @param daysInterval 每个区间的间隔天数例如传入 7 表示每个区间覆盖 7 2024-01-01~2024-01-08
* @return 时间区间列表每个元素为 [开始时间, 结束时间]均为 yyyy-MM-dd 00:00:00 格式
*/
private static List<Date[]> splitTimeRange(Date startDate, Date endDate, int daysInterval) {
List<Date[]> ranges = new ArrayList<>();
public static List<Date[]> splitTimeRange(Date startDate, Date endDate, int daysInterval) {
// 1. 入参合法性校验避免无效区间或负间隔
if (startDate == null || endDate == null) {
throw new IllegalArgumentException("开始时间和结束时间不可为 null");
}
if (daysInterval < 1) {
throw new IllegalArgumentException("间隔天数必须大于等于 1");
}
// 2. 初始化日历并强制截断时间部分确保所有日期都是 yyyy-MM-dd 00:00:00
Calendar calendar = Calendar.getInstance();
setTimeToStartOfDay(calendar); // 先重置时间再设日期避免原日期含时间的影响
calendar.setTime(startDate);
Date currentStart = calendar.getTime();
// 调整结束时间以包含完整日期
Calendar endCal = Calendar.getInstance();
setTimeToStartOfDay(endCal);
endCal.setTime(endDate);
endCal.set(Calendar.HOUR_OF_DAY, 23);
endCal.set(Calendar.MINUTE, 59);
endCal.set(Calendar.SECOND, 59);
endCal.set(Calendar.MILLISECOND, 999);
Date adjustedEndDate = endCal.getTime();
while (calendar.getTime().before(adjustedEndDate)) {
// 区间开始时间当前日期的00:00:00
Date rangeStart = calendar.getTime();
// 增加间隔天数-1天然后设置为23:59:59作为区间结束时间
calendar.add(Calendar.DAY_OF_MONTH, daysInterval - 1);
calendar.set(Calendar.HOUR_OF_DAY, 23);
calendar.set(Calendar.MINUTE, 59);
calendar.set(Calendar.SECOND, 59);
calendar.set(Calendar.MILLISECOND, 999);
Date rangeEnd = calendar.getTime();
// 如果区间结束时间超过最终结束时间使用最终结束时间
if (rangeEnd.after(adjustedEndDate)) {
rangeEnd = adjustedEndDate;
Date finalEnd = endCal.getTime();
// 额外校验开始时间不能晚于结束时间
if (currentStart.after(finalEnd)) {
throw new IllegalArgumentException("开始时间不能晚于结束时间");
}
List<Date[]> ranges = new ArrayList<>();
// 3. 循环拆分区间核心逻辑确保下一个开始 = 上一个结束
while (true) {
// 计算当前区间的结束时间开始时间 + 间隔天数 2024-01-01 + 7天 = 2024-01-08
calendar.add(Calendar.DAY_OF_MONTH, daysInterval);
setTimeToStartOfDay(calendar); // 再次确保时间部分为 00:00:00
Date currentEnd = calendar.getTime();
// 处理最后一个区间若计算的结束时间超过最终结束时间强制对齐到 finalEnd
if (currentEnd.after(finalEnd)) {
currentEnd = finalEnd;
}
ranges.add(new Date[]{rangeStart, rangeEnd});
// 准备下一个区间的开始时间当前区间结束时间的下一天00:00:00
calendar.add(Calendar.MILLISECOND, 1); // 加1毫秒到下一天
calendar.set(Calendar.HOUR_OF_DAY, 0);
calendar.set(Calendar.MINUTE, 0);
calendar.set(Calendar.SECOND, 0);
calendar.set(Calendar.MILLISECOND, 0);
// 如果已经达到或超过结束时间则退出循环
if (calendar.getTime().after(adjustedEndDate)) {
// 添加当前区间 [currentStart, currentEnd]
ranges.add(new Date[]{currentStart, currentEnd});
// 终止条件当前区间的结束时间已等于最终结束时间无需继续拆分
if (currentEnd.equals(finalEnd)) {
break;
}
// 准备下一个区间的开始时间当前结束时间满足连续要求
currentStart = currentEnd;
}
return ranges;
}
/**
* 工具方法 Calendar 的时间部分强制设置为当天 00:00:00截断时分秒毫秒
* @param calendar 待处理的 Calendar 实例 null
*/
private static void setTimeToStartOfDay(Calendar calendar) {
if (calendar == null) {
throw new IllegalArgumentException("Calendar 实例不可为 null");
}
calendar.set(Calendar.HOUR_OF_DAY, 0); // 24小时制0 表示凌晨 0
calendar.set(Calendar.MINUTE, 0); // 分钟设为 0
calendar.set(Calendar.SECOND, 0); // 秒设为 0
calendar.set(Calendar.MILLISECOND, 0); // 毫秒设为 0
}
/**
* 处理并插入数据到目标表
* @param sourceData 源数据列表

View File

@ -178,6 +178,7 @@ public class SaleDataSyncServiceImpl implements DataSyncService {
boolean hasMore;
RDSAPI rdsapi = null;
SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
SimpleDateFormat simpleDateFormat2 = new SimpleDateFormat("yyyy-MM-dd");
try {
rdsapi = SDK.getCCAPI().getRDSAPI(ccId);
DBUtils.SUPPLY supply = rdsapi.getSupply();
@ -204,8 +205,8 @@ public class SaleDataSyncServiceImpl implements DataSyncService {
for (int i = 0; i < timeRanges.size(); i++) {
Date[] range = timeRanges.get(i);
String startDate = simpleDateFormat.format(range[0]);
String endDate = simpleDateFormat.format(range[1]);
String startDate = simpleDateFormat2.format(range[0]);
String endDate = simpleDateFormat2.format(range[1]);
LOGGER.info("正在处理第 {} 个时间区间: {} 至 {}", i + 1, startDate, endDate);
if ("ORACLE".equalsIgnoreCase(DBname)) {
@ -449,7 +450,7 @@ public class SaleDataSyncServiceImpl implements DataSyncService {
* @param daysInterval 每个区间的间隔天数例如传入 7 表示每个区间覆盖 7 2024-01-01~2024-01-08
* @return 时间区间列表每个元素为 [开始时间, 结束时间]均为 yyyy-MM-dd 00:00:00 格式
*/
private static List<Date[]> splitTimeRange(Date startDate, Date endDate, int daysInterval) {
public static List<Date[]> splitTimeRange(Date startDate, Date endDate, int daysInterval) {
// 1. 入参合法性校验避免无效区间或负间隔
if (startDate == null || endDate == null) {
throw new IllegalArgumentException("开始时间和结束时间不可为 null");
@ -457,7 +458,6 @@ public class SaleDataSyncServiceImpl implements DataSyncService {
if (daysInterval < 1) {
throw new IllegalArgumentException("间隔天数必须大于等于 1");
}
// 2. 初始化日历并强制截断时间部分确保所有日期都是 yyyy-MM-dd 00:00:00
Calendar calendar = Calendar.getInstance();
setTimeToStartOfDay(calendar); // 先重置时间再设日期避免原日期含时间的影响
@ -468,34 +468,27 @@ public class SaleDataSyncServiceImpl implements DataSyncService {
setTimeToStartOfDay(endCal);
endCal.setTime(endDate);
Date finalEnd = endCal.getTime();
// 额外校验开始时间不能晚于结束时间
if (currentStart.after(finalEnd)) {
throw new IllegalArgumentException("开始时间不能晚于结束时间");
}
List<Date[]> ranges = new ArrayList<>();
// 3. 循环拆分区间核心逻辑确保下一个开始 = 上一个结束
while (true) {
// 计算当前区间的结束时间开始时间 + 间隔天数 2024-01-01 + 7天 = 2024-01-08
calendar.add(Calendar.DAY_OF_MONTH, daysInterval);
setTimeToStartOfDay(calendar); // 再次确保时间部分为 00:00:00
Date currentEnd = calendar.getTime();
// 处理最后一个区间若计算的结束时间超过最终结束时间强制对齐到 finalEnd
if (currentEnd.after(finalEnd)) {
currentEnd = finalEnd;
}
// 添加当前区间 [currentStart, currentEnd]
ranges.add(new Date[]{currentStart, currentEnd});
// 终止条件当前区间的结束时间已等于最终结束时间无需继续拆分
if (currentEnd.equals(finalEnd)) {
break;
}
// 准备下一个区间的开始时间当前结束时间满足连续要求
currentStart = currentEnd;
}