Browse Source

日期支持加减天数

master
han\hanst 2 months ago
parent
commit
fb41bcf03a
  1. 1
      src/main/java/com/gaotao/modules/base/entity/ReportLabelList.java
  2. 134
      src/main/java/com/gaotao/modules/base/service/Impl/LabelDataProcessorServiceImpl.java

1
src/main/java/com/gaotao/modules/base/entity/ReportLabelList.java

@ -46,6 +46,7 @@ public class ReportLabelList {
private String dateExtractType;
private String firstWeekDate;
private String firstDayOfWeek;
private Integer dateOffsetDays;
private String dateFormat;
private String dateSeparator;
private String yearDigits;

134
src/main/java/com/gaotao/modules/base/service/Impl/LabelDataProcessorServiceImpl.java

@ -1,6 +1,7 @@
package com.gaotao.modules.base.service.Impl;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.SerializationFeature;
import com.gaotao.modules.api.entity.IfsBoxLabel;
import com.gaotao.modules.api.service.IfsApiService;
import com.gaotao.modules.base.entity.LabelSettingData;
@ -17,6 +18,7 @@ import org.springframework.stereotype.Service;
import java.math.BigDecimal;
import java.math.RoundingMode;
import java.text.DecimalFormat;
import java.text.SimpleDateFormat;
import java.time.LocalDate;
import java.time.ZoneId;
import java.time.format.DateTimeFormatter;
@ -787,6 +789,12 @@ public class LabelDataProcessorServiceImpl implements LabelDataProcessorService
return dateValue;
}
// 日期偏移处理正数加天负数减天
Integer dateOffsetDays = element.getDateOffsetDays();
if (dateOffsetDays != null && dateOffsetDays != 0) {
date = date.plusDays(dateOffsetDays.longValue());
}
switch (extractType) {
case "year":
return String.valueOf(date.getYear());
@ -813,6 +821,23 @@ public class LabelDataProcessorServiceImpl implements LabelDataProcessorService
* 解析日期字符串
*/
private LocalDate parseDate(String dateValue) {
String normalizedValue = dateValue != null ? dateValue.trim() : "";
if (normalizedValue.isEmpty()) {
return null;
}
// 去除字符串两端引号兼容 "\"2024-09-14T00:00:00\"" 这类数据
if ((normalizedValue.startsWith("\"") && normalizedValue.endsWith("\""))
|| (normalizedValue.startsWith("'") && normalizedValue.endsWith("'"))) {
normalizedValue = normalizedValue.substring(1, normalizedValue.length() - 1).trim();
}
// 优先使用java.time处理避免宽松解析导致错误日期例如 7203-12-23
LocalDate javaTimeParsedDate = parseDateByJavaTime(normalizedValue);
if (javaTimeParsedDate != null) {
return javaTimeParsedDate;
}
String[] patterns = {
// 年月日
"yyyy-MM-dd", "yyyy/MM/dd", "yyyy.MM.dd",
@ -826,6 +851,14 @@ public class LabelDataProcessorServiceImpl implements LabelDataProcessorService
"MM-dd-yyyy HH:mm:ss", "MM/dd/yyyy HH:mm:ss", "MM.dd.yyyy HH:mm:ss",
"yyyyMMdd HHmmss",
// ISO时间格式T分隔
"yyyy-MM-dd'T'HH:mm:ss",
"yyyy-MM-dd'T'HH:mm:ss.SSS",
"yyyy-MM-dd'T'HH:mm:ssX",
"yyyy-MM-dd'T'HH:mm:ss.SSSX",
"yyyy-MM-dd'T'HH:mm:ssXXX",
"yyyy-MM-dd'T'HH:mm:ss.SSSXXX",
// 年月日 + 时分
"yyyy-MM-dd HH:mm", "yyyy/MM/dd HH:mm", "yyyy.MM.dd HH:mm",
"dd-MM-yyyy HH:mm", "dd/MM/yyyy HH:mm", "dd.MM.yyyy HH:mm",
@ -833,11 +866,13 @@ public class LabelDataProcessorServiceImpl implements LabelDataProcessorService
"yyyyMMdd HHmm",
// 带毫秒
"yyyy-MM-dd HH:mm:ss.SSS", "yyyy/MM/dd HH:mm:ss.SSS", "yyyy.MM.dd HH:mm:ss.SSS"
"yyyy-MM-dd HH:mm:ss.S", "yyyy-MM-dd HH:mm:ss.SS", "yyyy-MM-dd HH:mm:ss.SSS",
"yyyy/MM/dd HH:mm:ss.S", "yyyy/MM/dd HH:mm:ss.SS", "yyyy/MM/dd HH:mm:ss.SSS",
"yyyy.MM.dd HH:mm:ss.S", "yyyy.MM.dd HH:mm:ss.SS", "yyyy.MM.dd HH:mm:ss.SSS"
};
try {
Date date = DateUtils.parseDate(dateValue.trim(), patterns);
Date date = DateUtils.parseDateStrictly(normalizedValue, patterns);
return date.toInstant().atZone(ZoneId.systemDefault()).toLocalDate();
} catch (Exception e) {
log.debug("日期解析失败: {}", dateValue);
@ -845,6 +880,97 @@ public class LabelDataProcessorServiceImpl implements LabelDataProcessorService
}
}
/**
* 使用java.time严格解析日期优先处理ISO格式与数据库常见时间戳字符串
*/
private LocalDate parseDateByJavaTime(String dateValue) {
// 兼容纯数字时间戳/毫秒/微秒/纳秒
LocalDate epochDate = parseEpochTimestamp(dateValue);
if (epochDate != null) {
return epochDate;
}
try {
return LocalDate.parse(dateValue, DateTimeFormatter.ISO_LOCAL_DATE);
} catch (Exception ignored) {
}
try {
return java.time.LocalDateTime.parse(dateValue, DateTimeFormatter.ISO_LOCAL_DATE_TIME).toLocalDate();
} catch (Exception ignored) {
}
try {
return java.time.OffsetDateTime.parse(dateValue, DateTimeFormatter.ISO_OFFSET_DATE_TIME).toLocalDate();
} catch (Exception ignored) {
}
try {
return java.time.ZonedDateTime.parse(dateValue, DateTimeFormatter.ISO_ZONED_DATE_TIME).toLocalDate();
} catch (Exception ignored) {
}
try {
return java.time.Instant.parse(dateValue).atZone(ZoneId.systemDefault()).toLocalDate();
} catch (Exception ignored) {
}
// 兼容数据库常见字符串2024-09-14 00:00:00.0
try {
java.time.format.DateTimeFormatter formatter = new java.time.format.DateTimeFormatterBuilder()
.appendPattern("yyyy-MM-dd HH:mm:ss")
.optionalStart()
.appendFraction(java.time.temporal.ChronoField.NANO_OF_SECOND, 1, 9, true)
.optionalEnd()
.toFormatter();
return java.time.LocalDateTime.parse(dateValue, formatter).toLocalDate();
} catch (Exception ignored) {
}
// 兼容数据库常见字符串2024/09/14 00:00:00.0
try {
java.time.format.DateTimeFormatter formatter = new java.time.format.DateTimeFormatterBuilder()
.appendPattern("yyyy/MM/dd HH:mm:ss")
.optionalStart()
.appendFraction(java.time.temporal.ChronoField.NANO_OF_SECOND, 1, 9, true)
.optionalEnd()
.toFormatter();
return java.time.LocalDateTime.parse(dateValue, formatter).toLocalDate();
} catch (Exception ignored) {
}
return null;
}
/**
* 解析纯数字时间戳字符串
*/
private LocalDate parseEpochTimestamp(String dateValue) {
if (dateValue == null || !dateValue.matches("^-?\\d+(\\.\\d+)?$")) {
return null;
}
try {
BigDecimal numericValue = new BigDecimal(dateValue);
long epoch = numericValue.longValue();
long absEpoch = Math.abs(epoch);
// 判定时间戳单位并转换为毫秒
// 10位左右毫秒13位左右微秒16位左右纳秒19位左右
if (absEpoch >= 1_000_000_000_000_000_000L) {
epoch = epoch / 1_000_000L; // 纳秒 -> 毫秒
} else if (absEpoch >= 1_000_000_000_000_000L) {
epoch = epoch / 1_000L; // 微秒 -> 毫秒
} else if (absEpoch < 100_000_000_000L) {
epoch = epoch * 1_000L; // -> 毫秒
}
return java.time.Instant.ofEpochMilli(epoch).atZone(ZoneId.systemDefault()).toLocalDate();
} catch (Exception ignored) {
return null;
}
}
/**
* 计算周数
*/
@ -1113,6 +1239,7 @@ public class LabelDataProcessorServiceImpl implements LabelDataProcessorService
copy.setDateExtractType(original.getDateExtractType());
copy.setFirstWeekDate(original.getFirstWeekDate());
copy.setFirstDayOfWeek(original.getFirstDayOfWeek());
copy.setDateOffsetDays(original.getDateOffsetDays());
copy.setDateFormat(original.getDateFormat());
copy.setDateSeparator(original.getDateSeparator());
copy.setYearDigits(original.getYearDigits());
@ -1598,6 +1725,9 @@ public class LabelDataProcessorServiceImpl implements LabelDataProcessorService
if (ifsBoxLabels != null && !ifsBoxLabels.isEmpty()) {
// 将IfsBoxLabel实体类转换为Map
ObjectMapper objectMapper = new ObjectMapper();
// 日期字段转为标准字符串避免默认序列化为时间戳数字
objectMapper.disable(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS);
objectMapper.setDateFormat(new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"));
for (IfsBoxLabel label : ifsBoxLabels) {
@SuppressWarnings("unchecked")
Map<String, Object> dataMap = objectMapper.convertValue(label, Map.class);

Loading…
Cancel
Save