package com.engine.salary.util; import cn.hutool.core.util.StrUtil; import com.engine.salary.common.LocalDateRange; import lombok.extern.slf4j.Slf4j; import org.apache.commons.lang3.StringUtils; import org.apache.commons.lang3.math.NumberUtils; import org.apache.commons.lang3.time.FastDateFormat; import org.jetbrains.annotations.NotNull; import weaver.general.BaseBean; import java.text.ParseException; import java.text.SimpleDateFormat; import java.time.*; import java.time.format.DateTimeFormatter; import java.util.Calendar; import java.util.Date; import java.util.Objects; import java.util.regex.Matcher; import java.util.regex.Pattern; /** * @description: 时间工具类 * @author: xiajun * @modified By: xiajun * @date: Created in 10/19/21 4:23 PM * @version:v1.0 */ @Slf4j public class SalaryDateUtil { public static final ZoneId CTT = ZoneId.of(ZoneId.SHORT_IDS.get("CTT")); public static final ZoneOffset SHANGHAI_ZONE_OFF_SET = ZoneOffset.ofHours(8); public static final FastDateFormat DATE_FORMAT = FastDateFormat.getInstance("yyyy-MM-dd"); public static final FastDateFormat DATETIME_FORMAT = FastDateFormat.getInstance("yyyy-MM-dd HH:mm:ss"); public static final DateTimeFormatter YEAR_FORMATTER = DateTimeFormatter.ofPattern("yyyy"); public static final DateTimeFormatter MONTH_FORMATTER = DateTimeFormatter.ofPattern("yyyy-MM"); public static final DateTimeFormatter DATE_FORMATTER = DateTimeFormatter.ofPattern("yyyy-MM-dd"); public static final DateTimeFormatter DATE_TIME_FORMATTER = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"); public static final String MONTH_FORMATTER_PATTERN = "yyyy-MM"; public static final String DATE_FORMATTER_PATTERN = "yyyy-MM-dd"; public static final String DATE_TIME_FORMATTER_PATTERN = "yyyy-MM-dd HH:mm:ss"; /** * yyyy-MM **/ private static final String MONTH_REGEX = "^([1-9]\\d{3})-(([0][1-9])|([1][0-2]))$"; /** * yyyy-MM-dd **/ private static final String DAY_REGEX = "^[1-9]\\d{3}-(0[1-9]|1[0-2])-(0[1-9]|[1-2][0-9]|3[0-1])$"; /** * 含斜杠日期格式 */ private static final String DAY_BAR_REGEX = "^[1-9]\\d{3}/([1-9]|1[0-2])/([1-9]|[1-2][0-9]|3[0-1])$"; public static Long localDate2EpochMilli(LocalDate localDate) { if (localDate == null) { return NumberUtils.LONG_ZERO; } return localDate.atStartOfDay(ZoneId.systemDefault()).toInstant().toEpochMilli(); } public static Long localDateTime2EpochMilli(LocalDateTime localDateTime) { if (localDateTime == null) { return NumberUtils.LONG_ZERO; } return localDateTime.atZone(ZoneId.systemDefault()).toInstant().toEpochMilli(); } public static Long localDateTime2EpochMilli(Date localDateTime) { if (localDateTime == null) { return NumberUtils.LONG_ZERO; } return localDateTime.getTime(); } public static String getFormatYearMonth(LocalDate localDate) { if (localDate == null) { return StringUtils.EMPTY; } try { return localDate.format(MONTH_FORMATTER); } catch (Exception e) { log.warn("格式化月份错误", e); return StringUtils.EMPTY; } } public static String getFormatYearMonth(Date localDate) { if (localDate == null) { return StringUtils.EMPTY; } try { SimpleDateFormat simpleDateFormat = new SimpleDateFormat(MONTH_FORMATTER_PATTERN); return simpleDateFormat.format(localDate); } catch (Exception e) { log.warn("格式化月份错误", e); return StringUtils.EMPTY; } } public static String getFormatLocalDate(LocalDate localDate) { if (localDate == null) { return StringUtils.EMPTY; } try { return localDate.format(DATE_FORMATTER); } catch (Exception e) { log.warn("格式化日期错误", e); return StringUtils.EMPTY; } } public static String getFormatDate(Date localDate) { if (localDate == null) { return StringUtils.EMPTY; } try { SimpleDateFormat simpleDateFormat = new SimpleDateFormat(DATE_FORMATTER_PATTERN); return simpleDateFormat.format(localDate); } catch (Exception e) { log.warn("格式化日期错误", e); return StringUtils.EMPTY; } } public static String getFormatLocalDate(LocalDateTime localDateTime) { if (localDateTime == null) { return StringUtils.EMPTY; } try { return localDateTime.format(DATE_FORMATTER); } catch (Exception e) { log.warn("格式化日期错误", e); return StringUtils.EMPTY; } } public static String getFormatLocalDateTime(LocalDateTime localDateTime) { if (localDateTime == null) { return StringUtils.EMPTY; } try { return localDateTime.format(DATE_TIME_FORMATTER); } catch (Exception e) { log.warn("格式化日期错误", e); return StringUtils.EMPTY; } } public static String getFormatLocalDateTime(Date localDateTime) { if (localDateTime == null) { return StringUtils.EMPTY; } try { SimpleDateFormat simpleDateFormat = new SimpleDateFormat(DATE_TIME_FORMATTER_PATTERN); return simpleDateFormat.format(localDateTime); } catch (Exception e) { log.warn("格式化日期错误", e); return StringUtils.EMPTY; } } public static LocalDateTime dateToLocalDateTime(Date date) { Instant instant = date.toInstant(); ZoneId zone = ZoneId.systemDefault(); return LocalDateTime.ofInstant(instant, zone); } public static LocalDate dateToLocalDate(Date date) { return date.toInstant().atZone(ZoneId.systemDefault()).toLocalDate(); } public static Date localDateToDate(LocalDate localDate) { if (null == localDate) { return null; } ZonedDateTime zonedDateTime = localDate.atStartOfDay(ZoneId.systemDefault()); return Date.from(zonedDateTime.toInstant()); } public static Date localDateTimeToDate(LocalDateTime localDateTime) { if (null == localDateTime) { return null; } return Date.from(localDateTime.atZone(ZoneId.systemDefault()).toInstant()); } public static String getFormatLocalDate(Date date) { if (date == null) { return StringUtils.EMPTY; } LocalDateTime localDateTime = dateToLocalDateTime(date); return getFormatLocalDate(localDateTime); } public static YearMonth localDate2YearMonth(Date localDate) { if (localDate == null) { return null; } Calendar c = Calendar.getInstance(); c.setTime(localDate); int year = c.get(Calendar.YEAR); int month = c.get(Calendar.MONTH) + 1; return YearMonth.of(year, month); } public static YearMonth String2YearMonth(String localDate) { if (checkDay(localDate)) { return null; } return YearMonth.parse(localDate); } public static Integer date2Year(Date localDate) { if (localDate == null) { return null; } Calendar c = Calendar.getInstance(); c.setTime(localDate); int year = c.get(Calendar.YEAR); return year ; } public static LocalDateRange localDate2Range(Date localDate) { if (localDate == null) { return null; } return LocalDateRange.builder() .fromDate(getFirstDayDateOfMonth(localDate)) .endDate(getLastDayOfMonth(localDate)) .build(); } public static LocalDateRange localDate2YearRange(Date localDate) { if (localDate == null) { return null; } return LocalDateRange.builder() .fromDate(getFirstDayDateOfYear(localDate)) .endDate(getLastDayOfYear(localDate)) .build(); } public static Date getFirstDayDateOfMonth(final Date date) { final Calendar cal = Calendar.getInstance(); cal.setTime(date); final int last = cal.getActualMinimum(Calendar.DAY_OF_MONTH); cal.set(Calendar.DAY_OF_MONTH, last); return cal.getTime(); } public static Date getFirstDayDateOfMonthWithMinutesAndSeconds(final Date date) { final Calendar cal = Calendar.getInstance(); cal.setTime(date); final int last = cal.getActualMinimum(Calendar.DAY_OF_MONTH); cal.set(Calendar.DAY_OF_MONTH, last); cal.set(Calendar.HOUR_OF_DAY, 0); cal.set(Calendar.MINUTE, 0); cal.set(Calendar.SECOND, 0); cal.set(Calendar.MILLISECOND, 0); return cal.getTime(); } public static Date getLastDayOfMonth(final Date date) { final Calendar cal = Calendar.getInstance(); cal.setTime(date); final int last = cal.getActualMaximum(Calendar.DAY_OF_MONTH); cal.set(Calendar.DAY_OF_MONTH, last); return cal.getTime(); } public static Date getFirstDayDateOfYear(final Date date) { final Calendar cal = Calendar.getInstance(); cal.setTime(date); final int last = cal.getActualMinimum(Calendar.DAY_OF_YEAR); cal.set(Calendar.DAY_OF_YEAR, last); return cal.getTime(); } public static Date getLastDayOfYear(final Date date) { final Calendar cal = Calendar.getInstance(); cal.setTime(date); final int last = cal.getActualMaximum(Calendar.DAY_OF_YEAR); cal.set(Calendar.DAY_OF_YEAR, last); return cal.getTime(); } public static String getMonthBegin(String specifiedDay) { int year; int month; Pattern pattern = Pattern.compile("\\d+-\\d+"); Matcher matcher = pattern.matcher(specifiedDay); if (StringUtils.isEmpty(specifiedDay) || !matcher.matches()) { return null; } else { year = Integer.parseInt(specifiedDay.split("-")[0]); month = Integer.parseInt(specifiedDay.split("-")[1]); } SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); Calendar calendar = Calendar.getInstance(); calendar.set(Calendar.YEAR, year); calendar.set(Calendar.MONTH, month - 1); calendar.set(Calendar.DAY_OF_MONTH, 1); calendar.set(Calendar.HOUR_OF_DAY, 0); calendar.set(Calendar.MINUTE, 0); calendar.set(Calendar.SECOND, 0); calendar.set(Calendar.MILLISECOND, 0); Date startDate = calendar.getTime(); return sdf.format(startDate); } public static String getYearMonth(int yearNum, int monthNum) { LocalDateTime dateTime = LocalDateTime.now(); int year = dateTime.getYear() + yearNum; int month = dateTime.getMonthValue() + monthNum; SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM"); Calendar calendar = Calendar.getInstance(); calendar.set(Calendar.YEAR, year); calendar.set(Calendar.MONTH, month - 1); calendar.set(Calendar.DAY_OF_MONTH, 1); calendar.set(Calendar.HOUR_OF_DAY, 0); calendar.set(Calendar.MINUTE, 0); calendar.set(Calendar.SECOND, 0); calendar.set(Calendar.MILLISECOND, 0); Date startDate = calendar.getTime(); return sdf.format(startDate); } /** * 检查年月格式 * * @param yearMonth * @return */ public static boolean checkYearMonth(String yearMonth) { return Pattern.matches(MONTH_REGEX, yearMonth); } /** * 检查日期格式 * * @param day * @return */ public static boolean checkDay(String day) { return Pattern.matches(DAY_REGEX, day) || Pattern.matches(DAY_BAR_REGEX, day); } public static Date parse(String date, String pattern) { SimpleDateFormat format = new SimpleDateFormat(pattern); try { return format.parse(date); } catch (ParseException e) { new BaseBean().writeLog(String.format("日期解析异常: %s, %s", date, pattern)); } return null; } /** * LocalDate转YearMonth * * @param localDate * @return */ public static YearMonth toYearMonth(LocalDate localDate) { Objects.requireNonNull(localDate, "localDate"); return YearMonth.of(localDate.getYear(), localDate.getMonthValue()); } /** * YearMonth转Date * 注意dayOfMonth范围:1到31之间,最大值根据月份确定特殊情况,如2月闰年29,非闰年28 * 如果要转换为当月最后一天,可以使用下面方法:toDateEndOfMonth(YearMonth) * * @param yearMonth * @param dayOfMonth * @return */ public static Date toDate(YearMonth yearMonth, int dayOfMonth) { Objects.requireNonNull(yearMonth, "yearMonth"); return localDateToDate(yearMonth.atDay(dayOfMonth)); } /** * YearMonth转Date,转换为当月第一天 * * @param yearMonth * @return */ public static Date toDateStartOfMonth(YearMonth yearMonth) { return toDate(yearMonth, 1); } /** * YearMonth转Date,转换为当月最后一天 * * @param yearMonth * @return */ public static Date toDateEndOfMonth(YearMonth yearMonth) { Objects.requireNonNull(yearMonth, "yearMonth"); return localDateToDate(yearMonth.atEndOfMonth()); } /** * YearMonth转LocalDate * 注意dayOfMonth范围:1到31之间,最大值根据月份确定特殊情况,如2月闰年29,非闰年28 * 如果要转换为当月最后一天,可以使用下面方法:toLocalDateEndOfMonth(YearMonth) * * @param yearMonth * @param dayOfMonth * @return */ public static LocalDate toLocalDate(YearMonth yearMonth, int dayOfMonth) { Objects.requireNonNull(yearMonth, "yearMonth"); return yearMonth.atDay(dayOfMonth); } /** * YearMonth转LocalDate,转换为当月第一天 * * @param yearMonth * @return */ public static LocalDate toLocalDateStartOfMonth(YearMonth yearMonth) { return toLocalDate(yearMonth, 1); } /** * YearMonth转LocalDate,转换为当月最后一天 * * @param yearMonth * @return */ public static LocalDate toLocalDateEndOfMonth(YearMonth yearMonth) { Objects.requireNonNull(yearMonth, "yearMonth"); return yearMonth.atEndOfMonth(); } /** * String转Date * * @param date * @return */ public static Date stringToDateTime(String date) { SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm"); Date parse = null; if (date != null) { try { parse = sdf.parse(date); } catch (ParseException e) { throw new RuntimeException(e); } } return parse; } public static Date stringToDate(String date) { return dateStrToLocalDate(date); } //格式化日期 public static String strToDateLong(String strDate) { Date date = new Date(); try { date = new SimpleDateFormat("yyyyMMddHHmmss").parse(strDate + "000000");//先按照原格式转换为时间 } catch (ParseException e) { e.printStackTrace(); } String str = new SimpleDateFormat("yyyy-MM").format(date);//再将时间转换为对应格式字符串 return str; } public static Date dateStrToLocalYearMonth(String date) { Date localDate = null; try { date = date.substring(0, 7); if (date.contains("/")) { SimpleDateFormat format = new SimpleDateFormat("yyyy/MM"); localDate = format.parse(date); } else if (date.contains("-")) { SimpleDateFormat format = new SimpleDateFormat("yyyy-MM"); localDate = format.parse(date); } } catch (Exception e) { log.error("日期解析异常,{}", date); localDate = null; } return localDate; } public static Date dateStrToLocalDate(String date) { Date localDate = null; try { date = date.substring(0, 10); if (date.contains("/")) { SimpleDateFormat format = new SimpleDateFormat("yyyy/MM/dd"); localDate = format.parse(date); } else if (date.contains("-")) { SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd"); localDate = format.parse(date); } } catch (Exception e) { log.error("日期解析异常,{}", date); localDate = null; } return localDate; } public static Date dateStrToLocalTime(String date) { Date localDate = null; try { if (date.contains("/")) { SimpleDateFormat format = new SimpleDateFormat("yyyy/MM/dd hh:mm:ss"); localDate = format.parse(date); } else if (date.contains("-")) { SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd hh:mm:ss"); localDate = format.parse(date); } } catch (Exception e) { log.error("日期解析异常,{}", date); localDate = null; } return localDate; } @NotNull public static Boolean monthInRange(String billMonth, String startMonth, String endMonth) { billMonth = billMonth + "-01"; Date billMonthDate = SalaryDateUtil.dateStrToLocalDate(billMonth); Boolean inDataRange = true; if (StringUtils.isNotBlank(startMonth)) { startMonth = startMonth + "-01"; Date socialStartDate = SalaryDateUtil.dateStrToLocalDate(startMonth); if (billMonthDate.before(socialStartDate)) { inDataRange = false; } } if (StringUtils.isNotBlank(endMonth)) { endMonth = endMonth + "-01"; Date socialEndDate = SalaryDateUtil.dateStrToLocalDate(endMonth); if (billMonthDate.after(socialEndDate)) { inDataRange = false; } } return inDataRange; } /** * 转换时间对象 * @see SalaryDateUtil#toDate(LocalDateTime, String) * @param dateTime LocalDateTime * @return Date */ public static Date toDate(LocalDateTime dateTime) { return toDate(dateTime, null); } /** * 转换时间对象 * @param dateTime LocalDateTime * @param offset 时区,e.g. +8 * @return Date */ public static Date toDate(LocalDateTime dateTime, String offset) { if (dateTime == null) { return null; } ZoneId zoneOffset = StrUtil.isNotEmpty(offset) ? ZoneOffset.of(offset) : ZoneOffset.systemDefault(); return Date.from(dateTime.atZone(zoneOffset).toInstant()); } public static Date plusMonths(Date date, int i) { LocalDate localDate = SalaryDateUtil.dateToLocalDate(date).plusMonths(i); return SalaryDateUtil.localDateToDate(localDate); } }