572 lines
18 KiB
Java
572 lines
18 KiB
Java
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]{0,1}[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 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());
|
||
}
|
||
}
|
||
|
||
|