package com.java110.dto.importData;
|
|
import java.math.BigDecimal;
|
import java.text.SimpleDateFormat;
|
import java.time.LocalDate;
|
import java.time.YearMonth;
|
import java.time.format.DateTimeFormatter;
|
import java.time.format.DateTimeParseException;
|
import java.time.format.ResolverStyle;
|
import java.time.temporal.TemporalAdjusters;
|
import java.util.Calendar;
|
import java.util.Date;
|
import java.util.Locale;
|
|
public class Vtil {
|
|
public static boolean isValidDbDate(String dateStr) {
|
// 1. 空值/空字符串直接返回false
|
if (dateStr == null || dateStr.trim().isEmpty()) {
|
return false;
|
}
|
|
// 2. 定义严格的日期格式化器(yyyy-MM-dd),禁止宽松解析
|
DateTimeFormatter dateFormatter = DateTimeFormatter.ofPattern("yyyy-MM-dd")
|
.withResolverStyle(java.time.format.ResolverStyle.STRICT);
|
|
try {
|
// 3. 尝试解析字符串为LocalDate
|
LocalDate.parse(dateStr, dateFormatter);
|
// 解析成功,说明格式和日期都合法
|
return true;
|
} catch (DateTimeParseException e) {
|
// 解析失败(格式错误/日期非法,如2024-02-30),返回false
|
return false;
|
}
|
}
|
|
public static String defaultValue(Object o) {
|
// 1. 如果入参为null,直接返回空字符串
|
if (o == null) {
|
return null;
|
}
|
|
// 2. 将对象转为字符串并去除首尾空格
|
String str = o.toString().trim();
|
|
// 3. 如果处理后是空字符串(原字符串只有空格),返回null;否则返回处理后的字符串
|
return str.isEmpty() ? null : str;
|
}
|
|
public static String defaultValue(Object o, String defaultValue) {
|
// 1. 如果入参为null,直接返回空字符串
|
if (o == null) {
|
return defaultValue;
|
}
|
|
// 2. 将对象转为字符串并去除首尾空格
|
String str = o.toString().trim();
|
|
// 3. 如果处理后是空字符串(原字符串只有空格),返回null;否则返回处理后的字符串
|
return str.isEmpty() ? defaultValue : str;
|
}
|
|
public static String defaultValueToNumber(Object obj) {
|
// 1. 处理null值
|
if (obj == null) {
|
return null;
|
}
|
|
// 2. 将对象转为字符串(兼容各种类型)
|
String originalStr = String.valueOf(obj);
|
|
// 3. 使用正则表达式替换所有非数字字符
|
// \\D 匹配所有非数字字符(等价于 [^0-9])
|
String numericStr = originalStr.replaceAll("\\D", "");
|
|
// 4. 返回处理后的纯数字字符串
|
return numericStr;
|
}
|
|
public static Double defaultDouble(Object o) {
|
return o == null || o.equals("") ? null : Double.parseDouble(defaultValue(o));
|
}
|
|
public static Double defaultDoubleSplit(Object o) {
|
return o == null || o.equals("") ? null : Double.parseDouble(defaultValue(o).split("/")[0]);
|
}
|
|
public static String defaultValueToNull(Object o) {
|
return o == null || o.equals("") ? null : o.toString();
|
}
|
|
public static String appendHyphenToRight(String str) {
|
// 1. 判空:null 或 去除首尾空格后为空字符串,都视为"空"
|
if (str == null || str.trim().isEmpty()) {
|
return str; // 空值直接返回,保持原有状态(null还是空字符串)
|
}
|
// 2. 非空则右侧拼接"-"
|
return str + "-";
|
}
|
|
public static String defaultValueToDate(Object o) {
|
// 空值直接返回null(原有逻辑)
|
if (o == null || o.toString().isEmpty()) {
|
return null;
|
}
|
|
try {
|
// 尝试将对象转换为数字(兼容Excel日期序列号,如44747)
|
double excelDateNum = Double.parseDouble(o.toString());
|
|
// Excel 1900日期系统基准(修正闰日bug,实际基准是1899-12-30)
|
Calendar calendar = Calendar.getInstance();
|
calendar.set(1899, 11, 30, 0, 0, 0); // 月份从0开始,11代表12月
|
calendar.set(Calendar.MILLISECOND, 0);
|
|
// 计算对应的实际日期
|
calendar.add(Calendar.DAY_OF_MONTH, (int) excelDateNum);
|
|
// 格式化为yyyy-MM-dd的日期字符串
|
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
|
return sdf.format(calendar.getTime());
|
} catch (NumberFormatException e) {
|
// 非数字类型,执行原有逻辑返回toString()
|
return o.toString();
|
}
|
}
|
|
public static BigDecimal defaultNum(Object o) {
|
if (o == null || o.toString().isEmpty()) {
|
return new BigDecimal(0);
|
}
|
try {
|
return o == null ? new BigDecimal(0) : new BigDecimal(o.toString());
|
}catch (Exception e) {
|
throw new IllegalArgumentException("数值转换错误!:" + o.toString());
|
}
|
}
|
public static String defaultValueToDate(Object o, String state, Object value) {
|
// 空值直接返回null(原有逻辑)
|
if (o == null || o.toString().isEmpty() || o.toString().equals("0")) {
|
return null;
|
}
|
|
String input = o.toString().trim();
|
// 定义年月格式的解析器
|
DateTimeFormatter ymFormatter = DateTimeFormatter.ofPattern("yyyy/M")
|
.withLocale(Locale.CHINA)
|
.withResolverStyle(ResolverStyle.LENIENT); // 宽松解析,兼容各种合法格式
|
|
try {
|
// 先解析为YearMonth(专门处理年月的类,不会缺少日期维度)
|
YearMonth yearMonth = YearMonth.parse(input, ymFormatter);
|
|
// 根据state参数处理日期
|
if ("start".equals(state)) {
|
// state为start时返回当月第一天
|
LocalDate firstDay = yearMonth.atDay(1);
|
return firstDay.toString();
|
} else if ("end".equals(state)) {
|
// state为end时返回当月最后一天
|
LocalDate lastDay = yearMonth.atEndOfMonth();
|
return lastDay.toString();
|
}
|
} catch (DateTimeParseException e) {
|
try {
|
ymFormatter = DateTimeFormatter.ofPattern("yyyy-M")
|
.withLocale(Locale.CHINA)
|
.withResolverStyle(ResolverStyle.LENIENT); // 宽松解析,兼容各种合法格式
|
|
// 先解析为YearMonth(专门处理年月的类,不会缺少日期维度)
|
YearMonth yearMonth = YearMonth.parse(input, ymFormatter);
|
|
// 根据state参数处理日期
|
if ("start".equals(state)) {
|
// state为start时返回当月第一天
|
LocalDate firstDay = yearMonth.atDay(1);
|
return firstDay.toString();
|
} else if ("end".equals(state)) {
|
// state为end时返回当月最后一天
|
LocalDate lastDay = yearMonth.atEndOfMonth();
|
return lastDay.toString();
|
}
|
} catch (DateTimeParseException e1) {
|
try {
|
ymFormatter = DateTimeFormatter.ofPattern("yyyy.M")
|
.withLocale(Locale.CHINA)
|
.withResolverStyle(ResolverStyle.LENIENT); // 宽松解析,兼容各种合法格式
|
|
// 先解析为YearMonth(专门处理年月的类,不会缺少日期维度)
|
YearMonth yearMonth = YearMonth.parse(input, ymFormatter);
|
|
// 根据state参数处理日期
|
if ("start".equals(state)) {
|
// state为start时返回当月第一天
|
LocalDate firstDay = yearMonth.atDay(1);
|
return firstDay.toString();
|
} else if ("end".equals(state)) {
|
// state为end时返回当月最后一天
|
LocalDate lastDay = yearMonth.atEndOfMonth();
|
return lastDay.toString();
|
}
|
} catch (Exception e3) {
|
try {
|
try {
|
// 尝试将对象转换为数字(兼容Excel日期序列号,如44747)
|
double excelDateNum = Double.parseDouble(o.toString());
|
|
// Excel 1900日期系统基准(修正闰日bug,实际基准是1899-12-30)
|
Calendar calendar = Calendar.getInstance();
|
calendar.set(1899, 11, 30, 0, 0, 0); // 月份从0开始,11代表12月
|
calendar.set(Calendar.MILLISECOND, 0);
|
|
// 计算对应的实际日期
|
calendar.add(Calendar.DAY_OF_MONTH, (int) excelDateNum);
|
|
// 格式化为yyyy-MM-dd的日期字符串
|
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
|
return sdf.format(calendar.getTime());
|
} catch (NumberFormatException e6) {
|
// 非数字类型,执行原有逻辑返回toString()
|
return defaultValue(value, null);
|
}
|
} catch (Exception e2) {
|
|
}
|
}
|
}
|
}
|
|
// 非目标格式或state不匹配时,返回原始字符串(原有逻辑)
|
return defaultValue(value, null);
|
}
|
|
public static String defaultValueToDate(Object o, String state) {
|
return defaultValueToDate(o, state, o);
|
}
|
|
/**
|
* 处理数字字符串,按指定小数位数截取,特殊值返回默认值
|
* @param count 待处理的数字字符串
|
* @param i 保留的小数位数
|
* @param value 默认返回值(当count为空/为null/为0时)
|
* @return 处理后的字符串
|
*/
|
public static String processCount(String count, Integer i, String value) {
|
// 1. 处理count为空、null或"0"的情况,直接返回默认值value
|
if (count == null || count.trim().isEmpty() || "0".equals(count.trim())) {
|
return value;
|
}
|
|
// 2. 处理保留小数位数为null或负数的边界情况(默认保留0位小数)
|
int keepDecimalPlaces = (i == null || i < 0) ? 0 : i;
|
|
// 3. 分割整数部分和小数部分
|
String[] parts = count.split("\\.");
|
String integerPart = parts[0];
|
String decimalPart = parts.length > 1 ? parts[1] : "";
|
|
// 4. 截取小数部分到指定长度(不足则补0,超过则截断)
|
StringBuilder resultBuilder = new StringBuilder(integerPart);
|
if (keepDecimalPlaces > 0) {
|
resultBuilder.append(".");
|
// 截取小数部分,长度不超过keepDecimalPlaces
|
String truncatedDecimal = decimalPart.length() >= keepDecimalPlaces
|
? decimalPart.substring(0, keepDecimalPlaces)
|
: String.format("%-" + keepDecimalPlaces + "s", decimalPart).replace(' ', '0');
|
resultBuilder.append(truncatedDecimal);
|
}
|
|
return resultBuilder.toString();
|
}
|
|
/**
|
* 增强版日期处理工具方法
|
* @param date 原始日期对象(可为null或无效对象)
|
* @param test 标识:start-当月第一天;end-当月最后一天;空/null-原日期
|
* @param format 目标日期格式(如yyyy-MM-dd HH:mm:ss)
|
* @param timeText 时分秒控制:start-00:00:00;end-23:59:59(逻辑同test)
|
* @param configDate date异常时返回的兜底值
|
* @return 处理后的日期字符串(异常时返回configDate)
|
*/
|
public static String processDateEnhanced(Date date, String test, String format, String timeText, String configDate) {
|
// 1. 优先处理date为空/异常的情况,直接返回兜底值configDate
|
if (date == null) {
|
return configDate;
|
}
|
|
// 2. 校验格式参数,若格式为空/无效,也返回兜底值
|
if (format == null || format.trim().isEmpty()) {
|
return configDate;
|
}
|
|
Calendar calendar = null;
|
try {
|
// 3. 尝试初始化Calendar并设置日期,捕获解析/转换异常
|
calendar = Calendar.getInstance();
|
calendar.setTime(date);
|
} catch (Exception e) {
|
// date无法解析(如非标准日期对象),返回兜底值
|
return configDate;
|
}
|
|
// 4. 统一处理test和timeText的大小写,避免匹配问题
|
String testNormalized = (test == null) ? "" : test.trim().toLowerCase();
|
String timeTextNormalized = (timeText == null) ? "" : timeText.trim().toLowerCase();
|
|
// 5. 调整日期(start/end)
|
if ("start".equals(testNormalized)) {
|
// start:当月第一天
|
calendar.set(Calendar.DAY_OF_MONTH, 1);
|
} else if ("end".equals(testNormalized)) {
|
// end:当月最后一天(自动适配大小月/2月)
|
calendar.set(Calendar.DAY_OF_MONTH, calendar.getActualMaximum(Calendar.DAY_OF_MONTH));
|
}
|
// test为空/其他值:不调整日期
|
|
// 6. 调整时分秒(基于timeText)
|
if ("start".equals(timeTextNormalized)) {
|
// start:00:00:00.000
|
calendar.set(Calendar.HOUR_OF_DAY, 0);
|
calendar.set(Calendar.MINUTE, 0);
|
calendar.set(Calendar.SECOND, 0);
|
calendar.set(Calendar.MILLISECOND, 0);
|
} else if ("end".equals(timeTextNormalized)) {
|
// end:23:59:59.999
|
calendar.set(Calendar.HOUR_OF_DAY, 23);
|
calendar.set(Calendar.MINUTE, 59);
|
calendar.set(Calendar.SECOND, 59);
|
calendar.set(Calendar.MILLISECOND, 999);
|
}
|
// timeText为空/其他值:不调整时分秒
|
|
// 7. 按指定格式格式化日期并返回
|
try {
|
SimpleDateFormat sdf = new SimpleDateFormat(format);
|
return sdf.format(calendar.getTime());
|
} catch (Exception e) {
|
// 格式化失败(如格式字符串非法),返回兜底值
|
return configDate;
|
}
|
}
|
|
public static String getMonth(String month) {
|
try {
|
if (month.length() == 1) {
|
month = "0" + month;
|
}
|
} catch (Exception e) {
|
return month;
|
}
|
return month;
|
}
|
}
|