1.数据比对工具
package com.micecs.erp.util;
import com.baomidou.mybatisplus.core.enums.IEnum;
import com.google.common.collect.Lists;
import com.google.common.collect.Maps;
import java.math.BigDecimal;
import java.util.*;
/**
* 数据比对工具
* 大数据量的比对,可以考虑加入多线程进行优化
*
* @author liulei, lei.liu@htouhui.com
* @version 1.0
*/
public class CompareListUtil {
public static void main(String[] args) {
complexCompare();
System.out.println("=============");
simpleCompare();
}
/**
* 大数据量比对.避免二次for循环比对,超过2000的数据就可以适当考虑
*/
public static void complexCompare() {
//1.准备源、目标端数据
List<ContentValues> sourceDataList = DataGenerateUtil.getSourceDataList();
List<ContentValues> targetDataList = DataGenerateUtil.getTargetDataList();
List<ContentValues> compareSourceDataList;
List<ContentValues> compareTargetDataList;
//2.提前设置map最大值,避免map主动扩容
Integer size = 0;
Map<ContentValues, CompareModelEnum> map = new HashMap<>(size);
if (sourceDataList.size() > targetDataList.size()) {
size = sourceDataList.size();
compareSourceDataList = new ArrayList<>(sourceDataList);
compareTargetDataList = new ArrayList<>(targetDataList);
} else {
size = targetDataList.size();
compareSourceDataList = new ArrayList<>(targetDataList);
compareTargetDataList = new ArrayList<>(targetDataList);
}
//3.设置默认数据属性:待删除
compareSourceDataList.stream().forEach(vo -> map.put(vo, CompareModelEnum.DELETE));
//4.比对数据
for (ContentValues value : compareTargetDataList) {
if (map.containsKey(value)) {
map.put(value, CompareModelEnum.UPDATE);
} else {
map.put(value, CompareModelEnum.INSERT);
}
}
//5.整理比对结果集
CompareResult insert = new CompareResult(CompareModelEnum.INSERT, Lists.newArrayList());
CompareResult update = new CompareResult(CompareModelEnum.UPDATE, Lists.newArrayList());
CompareResult delete = new CompareResult(CompareModelEnum.DELETE, Lists.newArrayList());
map.forEach((key, value) -> {
switch (value) {
case INSERT:
insert.getValues().add(key);
break;
case UPDATE:
update.getValues().add(key);
break;
default:
delete.getValues().add(key);
}
});
System.out.println("待添加:" + insert.toString());
System.out.println("待删除:" + delete.toString());
System.out.println("待修改:" + update.toString());
}
/**
* 小数据量的比较
*/
public static void simpleCompare() {
//1.准备源、目标端数据
List<ContentValues> sourceDataList = DataGenerateUtil.getSourceDataList();
List<ContentValues> targetDataList = DataGenerateUtil.getTargetDataList();
//2.比较两者的大小.将大的集合put进map中
getSimpleCompareResult(sourceDataList, targetDataList);
}
/**
* 获取两个集合不同:简单比较[对于交集是否修改/不修改,取决于源、目标相同对象的其他字段是否存在变化]
*
* @param sourceList 源
* @param targetList 目标
* @return 0-交集 1-差集 2-源存在而目标不存在
*/
public static Map<CompareModelEnum, List<ContentValues>> getSimpleCompareResult(List<ContentValues> sourceList, List<ContentValues> targetList) {
Map<CompareModelEnum, List<ContentValues>> mapList = Maps.newHashMap();
List<List<ContentValues>> result = Lists.newArrayList();
List<ContentValues> erpIdCopy = Lists.newArrayList(sourceList);
sourceList.retainAll(targetList);
result.add(new ArrayList<>(sourceList));
mapList.put(CompareModelEnum.UPDATE, sourceList);
System.out.println("比对交集:待修改的 :" + sourceList.toString());
targetList.removeAll(sourceList);
result.add(new ArrayList<>(targetList));
mapList.put(CompareModelEnum.INSERT, sourceList);
System.out.println(("比对差集:待添加的 " + targetList.toString()));
erpIdCopy.removeAll(targetList);
sourceList.addAll(targetList);
erpIdCopy.removeAll(sourceList);
result.add(new ArrayList<>(erpIdCopy));
mapList.put(CompareModelEnum.DELETE, sourceList);
System.out.println(("比对后待删除的 " + erpIdCopy.toString()));
return mapList;
}
}
/**
* 比对结果实体类
*/
@Data
class CompareResult {
private CompareModelEnum key;
private List<ContentValues> values;
public CompareResult(CompareModelEnum key, List<ContentValues> values) {
this.key = key;
this.values = values;
}
@Override
public String toString() {
return "CompareResult{" +
"key=" + key +
", values=" + values +
'}';
}
}
/**
* 比对结果枚举
*/
enum CompareModelEnum implements IEnum<Integer> {
/**
* 列举比对结果类型
*/
UPDATE(1, "待更新"),
INSERT(2, "待插入"),
DELETE(3, "待删除");
private Integer value;
private String desc;
CompareModelEnum(Integer value, String desc) {
this.value = value;
this.desc = desc;
}
@Override
public Integer getValue() {
return value;
}
public static CompareModelEnum valueOf(Integer code) {
for (CompareModelEnum value : CompareModelEnum.values()) {
if (Objects.equals(value.getValue(), code)) {
return value;
}
}
throw new RuntimeException("无匹配的");
}
}
/**
* 数据比对实体对象
*/
@Data
class ContentValues {
/**
* 询单号
*/
private String rfpNo;
/**
* 供应商类型
*/
private Integer supplierType;
/**
* 供应商ID
*/
private Long supplierId;
/**
* 比对报价
*/
private BigDecimal price;
/**
* 供应商返佣金额
*/
private BigDecimal commissionMoney;
@Override
public String toString() {
return "\nContentValues{" +
"rfpNo='" + rfpNo + '\'' +
", supplierId=" + supplierId +
", price=" + price +
", commissionMoney=" + commissionMoney +
", supplierType=" + supplierType +
'}';
}
/**
* 重写equals方法
* 因为object中的equals()方法比较的是对象的引用地址是否相等,如何你需要判断对象里的内容是否相等,则需要重写equals()方法。
* equals 相等,hashCode 必然要相等
* hashCode 相同,equals 不一定相同
*/
@Override
public boolean equals(Object obj) {
if (obj == this) {
return true;
}
if (!(obj instanceof ContentValues)) {
return false;
}
ContentValues content = (ContentValues) obj;
return supplierId.equals(content.getSupplierId()) &&
rfpNo.equals(content.getRfpNo()) &&
price.compareTo(content.getPrice()) == 0 &&
commissionMoney.compareTo(content.getCommissionMoney()) == 0;
}
/**
* 重写hashCode方法
* Java中的hashCode方法就是根据一定的规则将与对象相关的信息(比如对象的存储地址,对象的字段等)映射成一个数值,这个数值称作为散列值。
* 主要是针对HashSet和Map集合类型,比如我们在向HashSet集合里边添加新元素的时候,
* 由于set集合里边不允许元素重复,所以我们在插入新元素之前需要先判断插入元素是否存在,首先根据hashCode()方法得到该对象的hashCode值,
* 如果集合里边不存在该值,可以直接插入进去。如果已经存在,则需要再次通过equals()来比较,这样的话可以提升效率。
* <p>
* 重写equals()方法同时重写hashcode()方法?
* 就是为了保证当两个对象通过equals()方法比较相等时,那么他们的hashCode值也一定要保证相等。
*/
@Override
public int hashCode() {
return Objects.hash(supplierId, rfpNo, price, commissionMoney);
}
}
/**
* 数据构建工具类
*/
class DataGenerateUtil {
/**
* 构建源端数据
*/
public static List<ContentValues> getSourceDataList() {
List<ContentValues> list = Lists.newArrayList();
ContentValues value1 = new ContentValues();
value1.setRfpNo("rfp_01");
value1.setSupplierId(100L);
value1.setCommissionMoney(new BigDecimal(100));
value1.setPrice(new BigDecimal(1000));
value1.setSupplierType(1);
ContentValues value2 = new ContentValues();
value2.setRfpNo("rfp_01");
value2.setSupplierId(200L);
value2.setCommissionMoney(new BigDecimal(200));
value2.setPrice(new BigDecimal(2000));
value2.setSupplierType(1);
ContentValues value3 = new ContentValues();
value3.setRfpNo("rfp_02");
value3.setSupplierId(300L);
value3.setCommissionMoney(new BigDecimal(300));
value3.setPrice(new BigDecimal(3000));
value3.setSupplierType(1);
ContentValues value4 = new ContentValues();
value4.setRfpNo("rfp_03");
value4.setSupplierId(400L);
value4.setCommissionMoney(new BigDecimal(400));
value4.setPrice(new BigDecimal(4000));
value4.setSupplierType(2);
ContentValues value5 = new ContentValues();
value5.setRfpNo("rfp_03");
value5.setSupplierId(500L);
value5.setCommissionMoney(new BigDecimal(500));
value5.setPrice(new BigDecimal(5000));
value5.setSupplierType(2);
list.add(value1);
list.add(value2);
list.add(value3);
list.add(value4);
list.add(value5);
return list;
}
/**
* 构建目标端数据
*/
public static List<ContentValues> getTargetDataList() {
List<ContentValues> list = Lists.newArrayList();
ContentValues value1 = new ContentValues();
value1.setRfpNo("rfp_01");
value1.setSupplierId(100L);
value1.setCommissionMoney(new BigDecimal(100));
value1.setPrice(new BigDecimal(1000));
value1.setSupplierType(1);
ContentValues value2 = new ContentValues();
value2.setRfpNo("rfp_01");
value2.setSupplierId(200L);
value2.setCommissionMoney(new BigDecimal(2100));
value2.setPrice(new BigDecimal(21000));
value2.setSupplierType(1);
ContentValues value4 = new ContentValues();
value4.setRfpNo("rfp_04");
value4.setSupplierId(700L);
value4.setCommissionMoney(new BigDecimal(700));
value4.setPrice(new BigDecimal(7000));
value4.setSupplierType(2);
ContentValues value5 = new ContentValues();
value5.setRfpNo("rfp_03");
value5.setSupplierId(500L);
value5.setCommissionMoney(new BigDecimal(1000));
value5.setPrice(new BigDecimal(10000));
value5.setSupplierType(2);
list.add(value1);
list.add(value2);
list.add(value4);
list.add(value5);
return list;
}
}
2.汉字转拼音
package com.micecs.erp.util.thirdpart;
import java.util.Random;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import net.sourceforge.pinyin4j.PinyinHelper;
import net.sourceforge.pinyin4j.format.HanyuPinyinCaseType;
import net.sourceforge.pinyin4j.format.HanyuPinyinOutputFormat;
import net.sourceforge.pinyin4j.format.HanyuPinyinToneType;
import net.sourceforge.pinyin4j.format.exception.BadHanyuPinyinOutputFormatCombination;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
/**
* 汉字转拼音插件
*
* @author liulei lei.liu@htouhui.com
* @version 1.0
*/
public class CharacterUtil {
private static final Logger LOGGER = LoggerFactory.getLogger(CharacterUtil.class);
/***
* 将汉字转成拼音(取首字母或全拼)
* @param chinese
* @param full 是否全拼
* @return
*/
public static String ConvertChinese2Pinyin(String chinese, boolean full) {
/***
* ^[\u2E80-\u9FFF]+$ 匹配所有东亚区的语言
* ^[\u4E00-\u9FFF]+$ 匹配简体和繁体
* ^[\u4E00-\u9FA5]+$ 匹配简体
*/
String regExp = "^[\u4E00-\u9FFF]+$";
StringBuffer sb = new StringBuffer();
if (chinese == null || "".equals(chinese.trim())) {
return "";
}
String pinyin;
for (int i = 0; i < chinese.length(); i++) {
char unit = chinese.charAt(i);
//是汉字,则转拼音
if (match(String.valueOf(unit), regExp)) {
pinyin = convertSingleChinese2Pinyin(unit);
if (full) {
sb.append(pinyin);
} else {
sb.append(pinyin.charAt(0));
}
} else {
sb.append(unit);
}
}
return sb.toString();
}
/***
* 将单个汉字转成拼音
* @param chinese
* @return
*/
private static String convertSingleChinese2Pinyin(char chinese) {
HanyuPinyinOutputFormat outputFormat = new HanyuPinyinOutputFormat();
outputFormat.setToneType(HanyuPinyinToneType.WITHOUT_TONE);
String[] res;
StringBuffer sb = new StringBuffer();
try {
res = PinyinHelper.toHanyuPinyinStringArray(chinese, outputFormat);
//对于多音字,只用第一个拼音
sb.append(res[0]);
} catch (Exception e) {
LOGGER.error("CONVERT SINGLE CHINESE TO PINYIN ERROR", e);
return "";
}
return sb.toString();
}
/***
* @param str 源字符串
* @param regex 正则表达式
* @return 是否匹配
*/
public static boolean match(String str, String regex) {
Pattern pattern = Pattern.compile(regex);
Matcher matcher = pattern.matcher(str);
return matcher.find();
}
/**
* 生成length长度的随机数字和字母
*
* @param length
* @return
*/
public static String GetStringRandom(int length) {
String val = "";
Random random = new Random(1);
//参数length,表示生成几位随机数
int num = 0;
while(num < length){
String charOrNum = random.nextInt(2) % 2 == 0 ? "char" : "num";
//输出字母还是数字
if ("char".equalsIgnoreCase(charOrNum)) {
//输出是大写字母还是小写字母
int temp = random.nextInt(2) % 2 == 0 ? 65 : 97;
val += (char) (random.nextInt(26) + temp);
num++;
}
}
return val;
}
/**
* 判断是否含有汉字
*/
public static boolean isChinese(String chinese) {
char[] arr = chinese.toCharArray();
for (char anArr : arr) {
boolean matches = String.valueOf(anArr).matches("[\u4e00-\u9fa5]");
if (matches) {
return true;
}
}
return false;
}
}
3.日期工具类
package com.ecej.iot.opt.common.utils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.time.*;
import java.time.format.DateTimeFormatter;
import java.time.temporal.ChronoUnit;
import java.time.temporal.TemporalUnit;
import java.util.Calendar;
import java.util.Date;
/**
* 日期工具类
*
* @author liulei, liuleiba@ecej.com
* @version 2.0
*/
public class LocalDateUtils {
private static final Logger logger = LoggerFactory.getLogger(LocalDateUtils.class);
public static final String DATE_TIME_FORMAT = "yyyy-MM-dd HH:mm:ss";
public static final String DATE_FORMAT = "yyyy-MM-dd";
public static final DateTimeFormatter TIME_FORMATTER = DateTimeFormatter.ofPattern("HHmmss");
public static final DateTimeFormatter YEAR_MONTH_FORMATTER = DateTimeFormatter.ofPattern("yyyy-MM");
public static final DateTimeFormatter SHORT_DATE_FORMATTER = DateTimeFormatter.ofPattern("yyMMdd");
public static final DateTimeFormatter DATE_FORMATTER = DateTimeFormatter.ofPattern(DATE_FORMAT);
public static final DateTimeFormatter SHORT_DATETIME_FORMATTER = DateTimeFormatter.ofPattern("yyyyMMddHHmmss");
public static final DateTimeFormatter DATETIME_FORMATTER = DateTimeFormatter.ofPattern(DATE_TIME_FORMAT);
public static final DateTimeFormatter LONG_DATETIME_FORMATTER = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss SSS");
/**
* Date类型转时间字符串
*/
public static String dateConvertToString(Date date, String format) {
LocalDateTime localDateTime = LocalDateTime.ofInstant(date.toInstant(), ZoneId.systemDefault());
DateTimeFormatter dateTimeFormatter = DateTimeFormatter.ofPattern(format);
return dateTimeFormatter.format(localDateTime);
}
/**
* localDateTime转Date
*/
public static Date localDateTime2Date(LocalDateTime localDateTime) {
return Date.from(localDateTime.atZone(ZoneId.systemDefault()).toInstant());
}
/**
* 时间字符串转Date
*/
public static Date stringConvertToDate(String date, String format) throws ParseException {
return new SimpleDateFormat(format).parse(date);
}
/**
* 获得当前日期
*
* @return
*/
public static Date getNow() {
Calendar cal = Calendar.getInstance();
return cal.getTime();
}
/**
* 获取一天的开始时间,2017,7,22 00:00
*
* @param time
* @return
*/
public static LocalDateTime getDayStart(LocalDateTime time) {
return time.withHour(0).withMinute(0).withSecond(0).withNano(0);
}
/**
* 获取某天的开始时间,2017,7,22 00:00
*
* @param date
* @return
*/
public static LocalDateTime getToDayStart(Date date) {
return getDayStart(dateConvertToLocalDateTime(date));
}
/**
* 获取一天的结束时间,2017,7,22 23:59:59.999999999
*
* @param time
* @return
*/
public static LocalDateTime getDayEnd(LocalDateTime time) {
return time.withHour(23).withMinute(59).withSecond(59).withNano(999999999);
}
/**
* 获取某天的结束时间,2017,7,22 23:59:59.999999999
*
* @return
*/
public static LocalDateTime getTodayDayEnd(Date date) {
return getDayEnd(dateConvertToLocalDateTime(date));
}
/**
* 日期加上一个数,根据field不同加不同值,field为ChronoUnit.*
*/
public static LocalDateTime plus(Date date, long number, TemporalUnit field) {
LocalDateTime localDateTime = dateConvertToLocalDateTime(date);
return localDateTime.plus(number, field);
}
/**
* 日期加上一个数,根据field不同加不同值,field为ChronoUnit.*
*/
public static LocalDateTime plus(LocalDateTime time, long number, TemporalUnit field) {
return time.plus(number, field);
}
/**
* 日期减去一个数,根据field不同减不同值,field参数为ChronoUnit.*
*
* @param time
* @param number
* @param field
* @return
*/
public static LocalDateTime minu(LocalDateTime time, long number, TemporalUnit field) {
return time.minus(number, field);
}
/**
* 获取两个日期的差 field参数为ChronoUnit.*
*
* @param startTime
* @param endTime
* @param field 单位(年月日时分秒)
* @return
*/
public static long betweenTwoTime(LocalDateTime startTime, LocalDateTime endTime, ChronoUnit field) {
Period period = Period.between(LocalDate.from(startTime), LocalDate.from(endTime));
if (field == ChronoUnit.YEARS) {
return period.getYears();
}
if (field == ChronoUnit.MONTHS) {
return period.getYears() * 12 + period.getMonths();
}
return field.between(startTime, endTime);
}
/**
* 返回当前的日期
*/
public static LocalDate getCurrentLocalDate() {
return LocalDate.now(ZoneOffset.of("+8"));
}
/**
* 返回当前时间
*/
public static LocalTime getCurrentLocalTime() {
return LocalTime.now(ZoneOffset.of("+8"));
}
/**
* 返回当前日期时间
*/
public static LocalDateTime getCurrentLocalDateTime() {
return LocalDateTime.now(ZoneOffset.of("+8"));
}
/**
* yyyy-MM-dd
*/
public static String getCurrentDateStr() {
return LocalDate.now(ZoneOffset.of("+8")).format(DATE_FORMATTER);
}
/**
* yyMMdd
*/
public static String getCurrentShortDateStr() {
return LocalDate.now(ZoneOffset.of("+8")).format(SHORT_DATE_FORMATTER);
}
public static String getCurrentMonthStr() {
return LocalDate.now(ZoneOffset.of("+8")).format(YEAR_MONTH_FORMATTER);
}
/**
* yyyy-MM-dd HH:mm:ss
*/
public static String getCurrentDateTimeStr() {
return LocalDateTime.now(ZoneOffset.of("+8")).format(DATETIME_FORMATTER);
}
public static String getCurrentLongDateTimeStr() {
return LocalDateTime.now(ZoneOffset.of("+8")).format(LONG_DATETIME_FORMATTER);
}
/**
* yyMMddHHmmss
*/
public static String getCurrentShortDateTimeStr() {
return LocalDateTime.now(ZoneOffset.of("+8")).format(SHORT_DATETIME_FORMATTER);
}
/**
* HHmmss
*/
public static String getCurrentTimeStr() {
return LocalTime.now(ZoneOffset.of("+8")).format(TIME_FORMATTER);
}
public static String getCurrentDateStr(String pattern) {
return LocalDate.now(ZoneOffset.of("+8")).format(DateTimeFormatter.ofPattern(pattern));
}
public static String getCurrentDateTimeStr(String pattern) {
return LocalDateTime.now(ZoneOffset.of("+8")).format(DateTimeFormatter.ofPattern(pattern));
}
public static String getCurrentTimeStr(String pattern) {
return LocalTime.now(ZoneOffset.of("+8")).format(DateTimeFormatter.ofPattern(pattern));
}
public static LocalDate parseLocalDate(String dateStr, String pattern) {
return LocalDate.parse(dateStr, DateTimeFormatter.ofPattern(pattern));
}
public static LocalDateTime parseLocalDateTime(String dateTimeStr, String pattern) {
return LocalDateTime.parse(dateTimeStr, DateTimeFormatter.ofPattern(pattern));
}
public static LocalTime parseLocalTime(String timeStr, String pattern) {
return LocalTime.parse(timeStr, DateTimeFormatter.ofPattern(pattern));
}
public static String formatLocalDate(LocalDate date, String pattern) {
return date.format(DateTimeFormatter.ofPattern(pattern));
}
public static String formatLocalDateTime(LocalDateTime datetime, String pattern) {
return datetime.format(DateTimeFormatter.ofPattern(pattern));
}
public static String formatLocalTime(LocalTime time, String pattern) {
return time.format(DateTimeFormatter.ofPattern(pattern));
}
public static LocalDate parseLocalDate(String dateStr) {
return LocalDate.parse(dateStr, DATE_FORMATTER);
}
public static LocalDateTime parseLocalDateTime(String dateTimeStr) {
return LocalDateTime.parse(dateTimeStr, DATETIME_FORMATTER);
}
public static LocalDateTime parseLongLocalDateTime(String longDateTimeStr) {
return LocalDateTime.parse(longDateTimeStr, LONG_DATETIME_FORMATTER);
}
public static LocalTime parseLocalTime(String timeStr) {
return LocalTime.parse(timeStr, TIME_FORMATTER);
}
public static String formatLocalDate(LocalDate date) {
return date.format(DATE_FORMATTER);
}
public static String formatLocalDateTime(LocalDateTime datetime) {
return datetime.format(DATETIME_FORMATTER);
}
public static String formatLocalTime(LocalTime time) {
return time.format(TIME_FORMATTER);
}
/**
* 日期相隔秒
*/
public static long periodHours(LocalDateTime startDateTime, LocalDateTime endDateTime) {
return Duration.between(startDateTime, endDateTime).get(ChronoUnit.SECONDS);
}
/**
* 日期相隔天数
*/
public static long periodDays(LocalDate startDate, LocalDate endDate) {
return startDate.until(endDate, ChronoUnit.DAYS);
}
/**
* 日期相隔周数
*/
public static long periodWeeks(LocalDate startDate, LocalDate endDate) {
return startDate.until(endDate, ChronoUnit.WEEKS);
}
/**
* 日期相隔月数
*/
public static long periodMonths(LocalDate startDate, LocalDate endDate) {
return startDate.until(endDate, ChronoUnit.MONTHS);
}
/**
* 日期相隔年数
*/
public static long periodYears(LocalDate startDate, LocalDate endDate) {
return startDate.until(endDate, ChronoUnit.YEARS);
}
/**
* 是否当天
*/
public static boolean isToday(LocalDate date) {
return getCurrentLocalDate().equals(date);
}
/**
* 获取当前毫秒数
*/
public static Long toEpochMilli(LocalDateTime dateTime) {
return dateTime.atZone(ZoneId.systemDefault()).toInstant().toEpochMilli();
}
/**
* 判断是否为闰年
*/
public static boolean isLeapYear(LocalDate localDate) {
return localDate.isLeapYear();
}
/**
* 将java.util.Date 转换为java8 的java.time.LocalDateTime,默认时区为东8区
*
* @param date 日期
* @return localDateTime
*/
public static LocalDateTime dateConvertToLocalDateTime(Date date) {
return date.toInstant().atOffset(ZoneOffset.of("+8")).toLocalDateTime();
}
/**
* 将java8 的 java.time.LocalDateTime 转换为 java.util.Date,默认时区为东8区
*
* @param localDateTime
* @return
*/
public static Date localDateTimeConvertToDate(LocalDateTime localDateTime) {
return Date.from(localDateTime.toInstant(ZoneOffset.of("+8")));
}
/**
* 毫秒转LocalDateTime
*
* @param milliseconds
* @return
*/
public static LocalDateTime millisecToDatetime(long milliseconds) {
Instant instant = Instant.ofEpochMilli(milliseconds);
return LocalDateTime.ofInstant(instant, ZoneOffset.of("+8"));
}
/**
* 将LocalDataTime转为毫秒数
*
* @param ldt
* @return
*/
public static long datatimeToTimestamp(LocalDateTime ldt) {
return ldt.toInstant(ZoneOffset.of("+8")).toEpochMilli();
}
/**
* 把long 转换成 日期 再转换成Date类型
*/
public static Date transferLongToDate(Long millSec) {
return new Date(millSec);
}
public static Date getDateBefore(int day) {
Calendar calendar = Calendar.getInstance();
calendar.add(Calendar.DATE, -day);
return calendar.getTime();
}
public static String getDateBeforeByLocalDateTime(int day) {
return dateConvertToLocalDateTime(getDateBefore(day)).format(DATETIME_FORMATTER);
}
public static String getDateBeforeBySimpleDateFormat(int day, String format) {
Calendar calendar = Calendar.getInstance();
SimpleDateFormat sdf = new SimpleDateFormat(format);
calendar.add(Calendar.DATE, -day);
return sdf.format(calendar.getTime());
}
public static String getDateAfterBySimpleDateFormat(int day, String format) {
Calendar calendar = Calendar.getInstance();
SimpleDateFormat sdf = new SimpleDateFormat(format);
calendar.add(Calendar.DATE, day);
return sdf.format(calendar.getTime());
}
/**
* 描述开始-结束的时间差
*
* @param start 开始
* @param end 结束
* @param unit 精确到单位
* @return 描述
*/
public static String getLocalDatePeriodDetail(LocalDateTime start, LocalDateTime end, TemporalUnit unit) {
Duration duration = Duration.between(start, end);
long days = duration.toDays();
long hours = Duration.between(plus(start, days, ChronoUnit.DAYS), end).toHours();
long minutes = Duration.between(plus(plus(start, hours, ChronoUnit.HOURS), days, ChronoUnit.DAYS), end).toMinutes();
long seconds = Duration.between(plus(plus(plus(start, minutes, ChronoUnit.MINUTES), hours, ChronoUnit.HOURS), days, ChronoUnit.DAYS), end).getSeconds();
logger.info("设备超期:{}", String.format("%d天%d时%d分%d秒", days, hours, minutes, seconds));
if (unit instanceof ChronoUnit) {
ChronoUnit f = (ChronoUnit) unit;
switch (f) {
case DAYS:
if (days > 0) {
return String.format("%d天", days);
}
if (hours > 0) {
return String.format("%d小时", hours);
}
if (minutes > 0) {
return String.format("%d分钟", minutes);
}
return String.format("%d秒", seconds);
case HOURS:
return String.format("%d天%d小时", days, hours);
case MINUTES:
return String.format("%d天%d小时%d分钟", days, hours, minutes);
case SECONDS:
return String.format("%d天%d小时%d分钟%d秒", days, hours, minutes, seconds);
default:
return String.format("%d天%d小时%d分钟%d秒", days, hours, minutes, seconds);
}
}
return String.format("%d天%d时%d分%d秒", days, hours, minutes, seconds);
}
public static void main(String[] args) throws ParseException {
SimpleDateFormat simpleDateFormat = new SimpleDateFormat(DATE_TIME_FORMAT);
LocalDateTime biggerDate = dateConvertToLocalDateTime(simpleDateFormat.parse("2020-02-20 00:00:00"));
logger.info(getLocalDatePeriodDetail(LocalDateTime.now(), biggerDate, ChronoUnit.DAYS));
logger.info(getLocalDatePeriodDetail(LocalDateTime.now(), biggerDate, ChronoUnit.HOURS));
logger.info(getLocalDatePeriodDetail(LocalDateTime.now(), biggerDate, ChronoUnit.MINUTES));
logger.info(getLocalDatePeriodDetail(LocalDateTime.now(), biggerDate, ChronoUnit.SECONDS));
logger.info(getLocalDatePeriodDetail(LocalDateTime.now(), biggerDate, ChronoUnit.NANOS));
logger.info("{}", stringConvertToDate("2018-06-01 10:12:05", DATE_FORMAT));
logger.info("23天前的日期{}", getDateBeforeByLocalDateTime(23).substring(0, 10));
logger.info(millisecToDatetime(1563867467000L).format(DATETIME_FORMATTER));
logger.info("格式化时间为数字{}", datatimeToTimestamp(getCurrentLocalDateTime()));
logger.info(getCurrentDateTimeStr("yyyy年MM月dd日 HH:mm:ss"));
logger.info("当前时间{}", getCurrentDateTimeStr());
Date date = getNow();
LocalDateTime localDateTime = dateConvertToLocalDateTime(date);
Long localDateTimeSecond = localDateTime.toEpochSecond(ZoneOffset.of("+8"));
Long dateSecond = date.toInstant().atOffset(ZoneOffset.of("+8")).toEpochSecond();
logger.info("dateSecond:{}", dateSecond);
logger.info("localDateTimeSecond:{}", localDateTimeSecond);
// 增加二十分钟
logger.info(formatLocalDateTime(plus(LocalDateTime.now(), 20, ChronoUnit.MINUTES), "yyyy年MM月dd日 HH:mm"));
// 增加两年
logger.info(formatLocalDateTime(plus(LocalDateTime.now(), 2, ChronoUnit.YEARS), "yyyy年MM月dd日 HH:mm"));
LocalDateTime start = LocalDateTime.of(1993, 10, 13, 11, 11);
LocalDateTime end = LocalDateTime.of(1994, 11, 13, 13, 13);
logger.info("年:{}", betweenTwoTime(start, end, ChronoUnit.YEARS));
logger.info("月:{}", betweenTwoTime(start, end, ChronoUnit.MONTHS));
logger.info("日:{}", betweenTwoTime(start, end, ChronoUnit.DAYS));
logger.info("半日:{}", betweenTwoTime(start, end, ChronoUnit.HALF_DAYS));
logger.info("小时:{}", betweenTwoTime(start, end, ChronoUnit.HOURS));
logger.info("分钟:{}", betweenTwoTime(start, end, ChronoUnit.MINUTES));
logger.info("秒:{}", betweenTwoTime(start, end, ChronoUnit.SECONDS));
logger.info("毫秒:{}", betweenTwoTime(start, end, ChronoUnit.MILLIS));
}
}
4.自定义线程池
package com.zbmoc.databus.util;
import java.util.concurrent.*;
/**
* @author liulei, lei.liu@htouhui.com
* @version 2.0
*/
public class ThreadPoolUtil {
/**
* 工具类,构造方法私有化
*/
private ThreadPoolUtil() {
super();
}
// 线程池核心线程数
private final static Integer CORE_POOL_SIZE = 10;
// 最大线程数
private final static Integer MAX_POOL_SIZE = 50;
// 空闲线程存活时间[秒]
private final static Integer KEEP_ALIVE_TIME = 1 * 60;
// 线程等待队列
private static BlockingQueue<Runnable> queue = new ArrayBlockingQueue<>(20);
// 线程池对象
private static ThreadPoolExecutor threadPool = new ThreadPoolExecutor(CORE_POOL_SIZE, MAX_POOL_SIZE,
KEEP_ALIVE_TIME, TimeUnit.SECONDS, queue, new ThreadPoolExecutor.AbortPolicy());
/**
* 向线程池提交一个任务,返回线程结果
*
* @param callable 带结果的提交线程
* @return Future 执行结果
*/
public static Future<?> submit(Callable<?> callable) {
return threadPool.submit(callable);
}
/**
* 向线程池提交一个任务,不关心处理结果
*
* @param runnable 普通线程
*/
public static void execute(Runnable runnable) {
threadPool.execute(runnable);
}
/**
* 关闭线程池
*/
public static void shutDown(){
threadPool.shutdown();
}
/**
* 获取当前线程池线程数量
*/
public static int getSize() {
return threadPool.getPoolSize();
}
/**
* 获取当前活动的线程数量
*/
public static int getActiveCount() {
return threadPool.getActiveCount();
}
}
5.Spring上下文工具类
Aware
接口是获取上下文的顶级接口,根据需要实现即可!
public class SpringUtils implements ApplicationContextAware {
private static ApplicationContext applicationContext;
@Override
public void setApplicationContext(@NonNull ApplicationContext applicationContext) throws BeansException {
SpringUtils.applicationContext = applicationContext;
}
public static <T> T getBean(Class<T> type) {
try {
return Optional.ofNullable(applicationContext).orElseThrow(() -> new IllegalStateException("non in spring application context.")).getBean(type);
} catch (Exception e) {
return null;
}
}
}