碰到个处理批次号的需求,处理成各种特殊的格式,方法还比较粗糙,可以优化,这里只做个记录。不仅仅适用于日期的格式化处理,特殊的字符规则都可以使用。
通过这个方法,维护成 "yyMMddpkx"这种特殊的格式,就能让客户随意修改生成的规则。
public class BatchNoTypeHandler {
public static final String delimiter = "-";
//年月日排口流水号
public static final String checkVal = "yMdpkx";
public static void main(String[] args) {
System.out.println(handler("2024-04-02-01-01-01", "yyMMddpkx"));
}
/**
* 批次号和转换的格式
* 2024-01-02
*/
public static String handler(String batchNo, String batchNoType) {
if (batchNo == null) {
throw new ConditionException("批次号不能为空");
}
if (batchNoType == null) {
return batchNo;
}
List<String> list = Arrays.asList(batchNo.split(delimiter));
if (list.size() < 5) {
throw new ConditionException("批次号不符合要求");
}
//获取日期 年月日
String year = list.get(0);
String month = list.get(1);
String day = list.get(2);
//排
String row = list.get(3);
//口
String port = list.get(4);
//序列号
String sn = list.get(5);
Calendar cal = Calendar.getInstance();
cal.set(Integer.parseInt(year), Integer.parseInt(month) - 1, Integer.parseInt(day));
for (int i = 0; i < checkVal.length(); i++) {
String searchStr = String.valueOf(checkVal.charAt(i));
Integer firstNum = firstNum(batchNoType, searchStr);
Integer repeatNum = repeatNum(batchNoType, searchStr);
if (repeatNum == 0) {
//表示没有匹配到
continue;
}
String repeatStr = repeatStr(searchStr, repeatNum);
switch (searchStr) {
case "p"://排
if (checkOne(repeatStr, "p")) {
String temp = retain(2, row, 1);
batchNoType = batchNoType.replace(repeatStr, temp);
}else{
batchNoType = batchNoType.replace(repeatStr, row);
}
break;
case "k"://口
if (checkOne(repeatStr, "k")) {
String temp = retain(2, port, 1);
batchNoType = batchNoType.replace(repeatStr, temp);
}else{
batchNoType = batchNoType.replace(repeatStr, port);
}
break;
case "x"://序列号
if (checkOne(repeatStr, "x")) {
String temp = retain(2, sn, 1);
batchNoType = batchNoType.replace(repeatStr, temp);
}else{
batchNoType = batchNoType.replace(repeatStr, sn);
}
break;
default:
String temp = dateHandler(cal, repeatStr);
batchNoType = batchNoType.replace(repeatStr, temp);
}
}
return batchNoType;
}
/**
* 重复计算的str
*/
public static String repeatStr(String str, Integer repeatNum) {
StringBuilder repeatStr = new StringBuilder();
for (int i = 0; i < repeatNum; i++) {
repeatStr.append(str);
}
return repeatStr.toString();
}
/**
* 计算第一次的位置
*/
public static Integer firstNum(String str, String searchStr) {
return str.indexOf(searchStr);
}
/**
* 计算重复出现几次
*/
public static Integer repeatNum(String str, String searchStr) {
return str.split(searchStr,-1).length - 1;
}
/**
* 日期字符
* 支持周和季度的匹配 W:周 Q:季度
* W Q默认都是两位
*/
public static String dateHandler(Calendar cal, String pattern) {
//如果包含Q 表示季度
if (pattern.contains("QQ")) {
int month = cal.get(Calendar.MONTH);
int quarter = month % 3 == 0 ? month / 3 : month / 3 + 1;
pattern = pattern.replace("QQ", "0" + quarter);
}
if (pattern.contains("WW")) {
int week = cal.get(Calendar.WEEK_OF_YEAR);
if (week < 10) {
pattern = pattern.replace("WW", "0" + week);
} else {
pattern = pattern.replace("WW", String.valueOf(week));
}
}
if (pattern.contains("ABC")) {
String[] split = pattern.split("ABC");
String suffix = split[0];
LocalDateTime nowDate = LocalDateTime.now();
int month = nowDate.getMonth().getValue();
if (month < 10) {
pattern = suffix + month;
}
if (month == 10) {
pattern = suffix + "'A'";
}
if (month == 11) {
pattern = suffix + "'B'";
}
if (month == 12) {
pattern = suffix + "'C'";
}
if (split.length > 1) {
pattern = pattern + split[1];
}
}
//SimpleDateFormat y 和 yyy需要特殊处理
if (checkOne(pattern, "y")) {
String year = String.valueOf(cal.get(Calendar.YEAR));
String y = year.substring(year.length() - 1);
pattern = pattern.replace("y", y);
}
if (checkOne(pattern, "yyy")) {
String year = String.valueOf(cal.get(Calendar.YEAR));
String y = year.substring(year.length() - 3);
pattern = pattern.replace("yyy", y);
}
SimpleDateFormat sdf = new SimpleDateFormat(pattern);
return sdf.format(cal.getTime());
}
/**
* 只出现一次
*/
public static boolean checkOne(String str, String words) {
return str.indexOf(words) == str.lastIndexOf(words);
}
/**
* 保留 截取多出来的
*
* @param type 1:开头 2:结尾
* @param valueStr 数据
* @param length 保留长度
* @return 处理后数据
*/
public static String retain(int type, String valueStr, int length) {
String newStr = "";
if (type == 1) {
newStr = valueStr.substring(0, length);
} else {
newStr = valueStr.substring(valueStr.length() - length, valueStr.length());
}
return newStr;
}
/**
* 补足
*
* @param type 1:开头 2:结尾
* @param valueStr 数据
* @param length 补足长度
* @param content 要补的内容
* @return 处理后数据
*/
public static String makeup(int type, String valueStr, int length, String content) {
//如果长度一致,返回
if (length == valueStr.length()) {
return valueStr;
}
if (length < valueStr.length()) {
throw new ConditionException(valueStr + "数据长度大于配置长度");
}
String newStr = "";
//要补的长度
int makeupSize = length - valueStr.length();
char[] makeupContentArray = content.toCharArray();
int index = 0;
StringBuilder sb = new StringBuilder();
if (type == 1) {
for (int i = 0; i < makeupSize; i++) {
sb.append(makeupContentArray[index]);
if ((index + 1) < makeupContentArray.length) {
index += 1;
} else {
index = 0;
}
}
sb.append(valueStr);
} else {
sb.append(valueStr);
for (int i = 0; i < makeupSize; i++) {
sb.append(makeupContentArray[index]);
if ((index + 1) < makeupContentArray.length) {
index += 1;
} else {
index = 0;
}
}
}
newStr = sb.toString();
return newStr;
}
}