2025-07-23 14:19:57 +08:00
|
|
|
|
package com.czlis.interfaceCommon.utils;
|
|
|
|
|
|
|
2025-08-09 22:28:44 +08:00
|
|
|
|
import java.io.UnsupportedEncodingException;
|
2025-09-04 18:35:55 +08:00
|
|
|
|
import java.math.BigDecimal;
|
|
|
|
|
|
import java.math.RoundingMode;
|
2025-08-28 18:13:57 +08:00
|
|
|
|
import java.util.Calendar;
|
2025-07-23 14:19:57 +08:00
|
|
|
|
import java.util.Date;
|
|
|
|
|
|
import java.util.Map;
|
|
|
|
|
|
public class LisUtil {
|
2025-08-28 18:13:57 +08:00
|
|
|
|
// 换行符常量(跨平台)
|
|
|
|
|
|
public static final String LINE_SEPARATOR = System.lineSeparator();
|
2025-07-23 14:19:57 +08:00
|
|
|
|
/**
|
|
|
|
|
|
* 生日格式为:yyyy-MM-dd
|
|
|
|
|
|
* 根据出生日期计算年龄
|
|
|
|
|
|
* @param birthday
|
|
|
|
|
|
* @return
|
|
|
|
|
|
*/
|
|
|
|
|
|
public static Map<String,String> getAgeFromBirthDay(String birthday){
|
2025-07-27 12:52:36 +08:00
|
|
|
|
return AgeUtils.getAgeFromBirthDay(birthday);
|
2025-07-23 14:19:57 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
|
* 根据年龄获取出生日期
|
|
|
|
|
|
* @param nl
|
|
|
|
|
|
* @return
|
|
|
|
|
|
*/
|
2025-07-27 12:52:36 +08:00
|
|
|
|
public static Date getBirthDayFromAge(int nl, String nldw) {
|
|
|
|
|
|
return AgeUtils.getBirthDayFromAge(nl,nldw);
|
2025-07-23 14:19:57 +08:00
|
|
|
|
}
|
2025-08-09 22:28:44 +08:00
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
|
* 按GBK编码的字节宽度截取字符串,最多取cutlens个字节(避免截取半个汉字)
|
|
|
|
|
|
* @param str 原始字符串
|
|
|
|
|
|
* @param beginidx 起始位置
|
|
|
|
|
|
* @param cutlens 截取长度
|
|
|
|
|
|
* @return 截取后的字符串
|
|
|
|
|
|
*/
|
|
|
|
|
|
public static String substringByGbkWidth(String str,int beginidx,int cutlens) {
|
|
|
|
|
|
if (str == null || str.isEmpty()) {
|
|
|
|
|
|
return "";
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
int targetWidth = cutlens; // 目标字节宽度
|
|
|
|
|
|
int currentWidth =beginidx; // 当前累计字节宽度
|
|
|
|
|
|
StringBuilder result = new StringBuilder();
|
|
|
|
|
|
|
|
|
|
|
|
for (char c : str.toCharArray()) {
|
|
|
|
|
|
// 计算当前字符在GBK编码下的字节数
|
|
|
|
|
|
int charWidth;
|
|
|
|
|
|
try {
|
|
|
|
|
|
// GBK编码中,汉字占2字节,英文等占1字节
|
|
|
|
|
|
charWidth = String.valueOf(c).getBytes("GBK").length;
|
|
|
|
|
|
} catch (UnsupportedEncodingException e) {
|
|
|
|
|
|
// 理论上GBK是Java默认支持的编码,不会走到这里
|
|
|
|
|
|
throw new RuntimeException("不支持GBK编码", e);
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// 判断加上当前字符后是否超过目标宽度
|
|
|
|
|
|
if (currentWidth + charWidth > targetWidth) {
|
|
|
|
|
|
break; // 超过则停止,不截取当前字符
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// 未超过则累加宽度并添加字符
|
|
|
|
|
|
currentWidth += charWidth;
|
|
|
|
|
|
result.append(c);
|
|
|
|
|
|
|
|
|
|
|
|
// 如果刚好达到目标宽度,提前结束
|
|
|
|
|
|
if (currentWidth == targetWidth) {
|
|
|
|
|
|
break;
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
return result.toString();
|
|
|
|
|
|
}
|
2025-08-15 19:57:36 +08:00
|
|
|
|
/**
|
|
|
|
|
|
* 使用正则表达式判断字符串是否为数字
|
|
|
|
|
|
* 支持:整数(123)、小数(123.45)、正负号(-123、+45.6)
|
|
|
|
|
|
*/
|
|
|
|
|
|
public static boolean isNumber(String str) {
|
|
|
|
|
|
if (str == null || str.trim().isEmpty()) {
|
|
|
|
|
|
return false;
|
|
|
|
|
|
}
|
|
|
|
|
|
// 正则表达式:匹配正负整数、正负小数
|
|
|
|
|
|
String regex = "^[+-]?([0-9]+(\\.[0-9]*)?|\\.[0-9]+)$";
|
|
|
|
|
|
return str.matches(regex);
|
|
|
|
|
|
}
|
|
|
|
|
|
/**
|
|
|
|
|
|
* 使用正则表达式判断字符串是否为数字
|
|
|
|
|
|
* 支持:整数(123)、小数(123.45),不包括带正负号的情况
|
|
|
|
|
|
*/
|
|
|
|
|
|
public static boolean isTureNumber(String str) {
|
|
|
|
|
|
if (str == null || str.trim().isEmpty()) {
|
|
|
|
|
|
return false;
|
|
|
|
|
|
}
|
|
|
|
|
|
// 正则表达式:仅匹配正整数、正小数(不包含正负号)
|
|
|
|
|
|
// 说明:
|
|
|
|
|
|
// ^[0-9]+(\.[0-9]*)?$ 匹配整数(如123)或带整数部分的小数(如123.45)
|
|
|
|
|
|
// |\.([0-9]+)$ 匹配纯小数(如.67)
|
|
|
|
|
|
String regex = "^[0-9]+(\\.[0-9]*)?|\\.[0-9]+$";
|
|
|
|
|
|
return str.matches(regex);
|
|
|
|
|
|
}
|
|
|
|
|
|
/**
|
|
|
|
|
|
* 将包含比较运算符的字符串转换为特定格式的数值字符串
|
|
|
|
|
|
* 不支持的格式或非数字内容将返回原值
|
|
|
|
|
|
* @param input 输入字符串,如">=123", ">123", "<=123", "<123"
|
|
|
|
|
|
* @return 转换后的字符串或原值
|
|
|
|
|
|
*/
|
|
|
|
|
|
public static String getOverNumber(String input) {
|
|
|
|
|
|
// 输入为空时返回原值
|
|
|
|
|
|
if (input == null || input.trim().isEmpty()) {
|
|
|
|
|
|
return input;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// 定义支持的运算符,按长度排序以便正确识别(先长后短)
|
|
|
|
|
|
String[] operators = {">=", "<=", ">", "<"};
|
|
|
|
|
|
String operator = null;
|
|
|
|
|
|
String numberPart = null;
|
|
|
|
|
|
|
|
|
|
|
|
// 识别运算符和数字部分
|
|
|
|
|
|
for (String op : operators) {
|
|
|
|
|
|
if (input.startsWith(op)) {
|
|
|
|
|
|
operator = op;
|
|
|
|
|
|
numberPart = input.substring(op.length());
|
|
|
|
|
|
break;
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// 未识别到支持的运算符,返回原值
|
|
|
|
|
|
if (operator == null) {
|
|
|
|
|
|
return input;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// 尝试将数字部分转换为double
|
|
|
|
|
|
double number;
|
|
|
|
|
|
try {
|
|
|
|
|
|
number = Double.parseDouble(numberPart);
|
|
|
|
|
|
} catch (NumberFormatException e) {
|
|
|
|
|
|
// 数字部分格式不正确,返回原值
|
|
|
|
|
|
return input;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// 根据运算符进行转换
|
|
|
|
|
|
switch (operator) {
|
|
|
|
|
|
case ">=":
|
|
|
|
|
|
case ">":
|
|
|
|
|
|
return String.format("%.4f", number + 0.0001);
|
|
|
|
|
|
case "<=":
|
|
|
|
|
|
case "<":
|
|
|
|
|
|
return String.format("%.4f", number - 0.0001);
|
|
|
|
|
|
default:
|
|
|
|
|
|
return input;
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
2025-09-04 18:35:55 +08:00
|
|
|
|
|
2025-08-15 19:57:36 +08:00
|
|
|
|
/**
|
2025-09-04 18:35:55 +08:00
|
|
|
|
保留指定小数位数(四舍五入)
|
|
|
|
|
|
支持比较符号 (<=、>=、<、>) 和负号 (-) 同时存在的情况
|
|
|
|
|
|
@param input 输入字符串,如 "123.1234"、">123.252"、"<=123.252"、"-45.67"、">=-89.01"
|
|
|
|
|
|
@param decimalPlaces 要保留的小数位数,需为非负整数
|
|
|
|
|
|
@return 格式化后的字符串,无法处理时返回原值
|
2025-08-15 19:57:36 +08:00
|
|
|
|
*/
|
2025-09-04 18:35:55 +08:00
|
|
|
|
public static String round (String input, int decimalPlaces) {
|
|
|
|
|
|
// 处理空输入或无效小数位数
|
|
|
|
|
|
if (input == null || input.trim ().isEmpty () || decimalPlaces < 0) {
|
2025-08-15 19:57:36 +08:00
|
|
|
|
return input;
|
|
|
|
|
|
}
|
2025-09-04 18:35:55 +08:00
|
|
|
|
// 定义比较运算符前缀(按长度排序,确保正确识别)
|
|
|
|
|
|
String [] comparisonPrefixes = {"<=", ">=", "<", ">"};
|
2025-08-15 19:57:36 +08:00
|
|
|
|
String comparisonPrefix = "";
|
2025-09-04 18:35:55 +08:00
|
|
|
|
String remainingPart = input.trim (); // 去除首尾空格
|
|
|
|
|
|
// 提取比较运算符前缀
|
2025-08-15 19:57:36 +08:00
|
|
|
|
for (String prefix : comparisonPrefixes) {
|
2025-09-04 18:35:55 +08:00
|
|
|
|
if (remainingPart.startsWith (prefix)) {
|
2025-08-15 19:57:36 +08:00
|
|
|
|
comparisonPrefix = prefix;
|
2025-09-04 18:35:55 +08:00
|
|
|
|
remainingPart = remainingPart.substring (prefix.length ()).trim (); // 去除前缀后的空格
|
2025-08-15 19:57:36 +08:00
|
|
|
|
break;
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
2025-09-04 18:35:55 +08:00
|
|
|
|
// 尝试解析剩余部分为数字(使用 BigDecimal 避免精度问题)
|
2025-08-15 19:57:36 +08:00
|
|
|
|
try {
|
2025-09-04 18:35:55 +08:00
|
|
|
|
// 解析为 BigDecimal(支持正负号和小数)
|
|
|
|
|
|
BigDecimal number = new BigDecimal (remainingPart);
|
|
|
|
|
|
// 设置四舍五入模式并保留指定小数位数
|
|
|
|
|
|
BigDecimal rounded = number.setScale (decimalPlaces, RoundingMode.HALF_UP);
|
|
|
|
|
|
// 拼接比较前缀和格式化后的数字
|
|
|
|
|
|
return comparisonPrefix + rounded.toPlainString (); //toPlainString 避免科学计数法
|
2025-08-15 19:57:36 +08:00
|
|
|
|
} catch (NumberFormatException e) {
|
2025-09-04 18:35:55 +08:00
|
|
|
|
// 数字部分无法解析时返回原值
|
2025-08-15 19:57:36 +08:00
|
|
|
|
return input;
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
2025-08-28 18:13:57 +08:00
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
|
* 根据天数返回日期,正数往后推,负数往前推
|
|
|
|
|
|
* @param day
|
|
|
|
|
|
* @return
|
|
|
|
|
|
*/
|
|
|
|
|
|
public static Date relativeDate(int day) {
|
|
|
|
|
|
// 1. 获取当前时间(基于Calendar)
|
|
|
|
|
|
Calendar calendar = Calendar.getInstance(); // 当前时间
|
|
|
|
|
|
calendar.add(Calendar.DAY_OF_MONTH, day);
|
|
|
|
|
|
// 2重置时间为00:00:00
|
|
|
|
|
|
calendar.set(Calendar.HOUR_OF_DAY, 0);
|
|
|
|
|
|
calendar.set(Calendar.MINUTE, 0);
|
|
|
|
|
|
calendar.set(Calendar.SECOND, 0);
|
|
|
|
|
|
// 3. 返回推算的出生日期
|
|
|
|
|
|
return calendar.getTime();
|
|
|
|
|
|
}
|
|
|
|
|
|
public static Date relativeDate(Date date,int day) {
|
|
|
|
|
|
// 1. 获取当前时间(基于Calendar)
|
|
|
|
|
|
Calendar calendar =Calendar.getInstance();
|
|
|
|
|
|
calendar.setTime(date);
|
|
|
|
|
|
calendar.add(Calendar.DAY_OF_MONTH, day);
|
|
|
|
|
|
// 2重置时间为00:00:00
|
|
|
|
|
|
calendar.set(Calendar.HOUR_OF_DAY, 0);
|
|
|
|
|
|
calendar.set(Calendar.MINUTE, 0);
|
|
|
|
|
|
calendar.set(Calendar.SECOND, 0);
|
|
|
|
|
|
// 3. 返回推算的出生日期
|
|
|
|
|
|
return calendar.getTime();
|
|
|
|
|
|
}
|
|
|
|
|
|
/**
|
|
|
|
|
|
* 根据天数返回日期时间,正数往后推,负数往前推
|
|
|
|
|
|
* @param day
|
|
|
|
|
|
* @return
|
|
|
|
|
|
*/
|
|
|
|
|
|
public static Date relativeDateTime(int day) {
|
|
|
|
|
|
// 1. 获取当前时间(基于Calendar)
|
|
|
|
|
|
Calendar calendar = Calendar.getInstance(); // 当前时间
|
|
|
|
|
|
// 2天:忽略小时,按整天推算
|
|
|
|
|
|
calendar.add(Calendar.DAY_OF_MONTH, day);
|
|
|
|
|
|
// 3. 返回推算的时间
|
|
|
|
|
|
return calendar.getTime();
|
|
|
|
|
|
}
|
|
|
|
|
|
public static Date relativeDateTime(Date date,int day) {
|
|
|
|
|
|
// 1. 获取当前时间(基于Calendar)
|
|
|
|
|
|
Calendar calendar = Calendar.getInstance(); // 当前时间
|
|
|
|
|
|
calendar.setTime(date);
|
|
|
|
|
|
// 2天:忽略小时,按整天推算
|
|
|
|
|
|
calendar.add(Calendar.DAY_OF_MONTH, day);
|
|
|
|
|
|
// 3. 返回推算的时间
|
|
|
|
|
|
return calendar.getTime();
|
|
|
|
|
|
}
|
2025-07-23 14:19:57 +08:00
|
|
|
|
}
|