|
|
package com.engine.jucailinkq.common.util;
|
|
|
|
|
|
import org.apache.commons.lang3.StringUtils;
|
|
|
import weaver.general.TimeUtil;
|
|
|
|
|
|
import java.text.ParseException;
|
|
|
import java.text.SimpleDateFormat;
|
|
|
import java.time.*;
|
|
|
import java.time.format.DateTimeFormatter;
|
|
|
import java.time.temporal.ChronoUnit;
|
|
|
import java.util.ArrayList;
|
|
|
import java.util.Calendar;
|
|
|
import java.util.Date;
|
|
|
import java.util.List;
|
|
|
import java.util.regex.Matcher;
|
|
|
import java.util.regex.Pattern;
|
|
|
|
|
|
public class DateUtil {
|
|
|
public static DateTimeFormatter yyyyMMdd = DateTimeFormatter.ofPattern("yyyy-MM-dd");
|
|
|
public static DateTimeFormatter yyyyMMddHHmmss = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
|
|
|
public static DateTimeFormatter yyyyMMddHHmm = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm");
|
|
|
public static DateTimeFormatter yyyyMM = DateTimeFormatter.ofPattern("yyyy-MM");
|
|
|
public static DateTimeFormatter yyyy = DateTimeFormatter.ofPattern("yyyy");
|
|
|
|
|
|
/**
|
|
|
* 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 DATE_PATTERN = "^\\d{4}-\\d{2}-\\d{2}$";
|
|
|
|
|
|
public static String beforeMonth(String time,int month){
|
|
|
LocalDateTime localDateTime = DateUtil.getTime(time);
|
|
|
return localDateTime.minusMonths(month).format(yyyyMMdd);
|
|
|
}
|
|
|
|
|
|
public static String beforeMonth(String time){
|
|
|
LocalDateTime localDateTime = DateUtil.getTime(time);
|
|
|
return localDateTime.minusMonths(1).format(yyyyMM);
|
|
|
}
|
|
|
|
|
|
public static String lastMonth(String time){
|
|
|
LocalDateTime localDateTime = DateUtil.getTime(time);
|
|
|
|
|
|
return localDateTime.plusMonths(1).format(yyyyMM);
|
|
|
}
|
|
|
public static String lastMonth(String time,DateTimeFormatter dateTimeFormatter){
|
|
|
LocalDateTime localDateTime = DateUtil.getTime(time);
|
|
|
|
|
|
return localDateTime.plusMonths(1).format(dateTimeFormatter);
|
|
|
}
|
|
|
public static String nextMonth(String time,int month,DateTimeFormatter dateTimeFormatter){
|
|
|
LocalDateTime localDateTime = DateUtil.getTime(time);
|
|
|
|
|
|
return localDateTime.plusMonths(month).format(dateTimeFormatter);
|
|
|
}
|
|
|
public static String nextYear(String time,int year,DateTimeFormatter dateTimeFormatter){
|
|
|
LocalDateTime localDateTime = DateUtil.getTime(time);
|
|
|
|
|
|
return localDateTime.plusYears(year).format(dateTimeFormatter);
|
|
|
}
|
|
|
public static String beforeYear(String time,int year,DateTimeFormatter dateTimeFormatter){
|
|
|
LocalDateTime localDateTime = DateUtil.getTime(time);
|
|
|
|
|
|
return localDateTime.minusYears(year).format(dateTimeFormatter);
|
|
|
}
|
|
|
|
|
|
|
|
|
public static String beforeDay(String time,long day){
|
|
|
LocalDateTime localDateTime = DateUtil.getTime(time);
|
|
|
return localDateTime.minusDays(day).format(yyyyMMdd);
|
|
|
}
|
|
|
public static String AfterDay(String time,long day){
|
|
|
LocalDateTime localDateTime = DateUtil.getTime(time);
|
|
|
|
|
|
return localDateTime.plusDays(day).format(yyyyMMdd);
|
|
|
}
|
|
|
|
|
|
public static String beforeMinutes(String time,long minutes){
|
|
|
LocalDateTime localDateTime = DateUtil.getTime(time);
|
|
|
return localDateTime.minusMinutes(minutes).format(yyyyMMddHHmm);
|
|
|
}
|
|
|
|
|
|
public static String AfterMinutes(String time,long minutes){
|
|
|
LocalDateTime localDateTime = DateUtil.getTime(time);
|
|
|
return localDateTime.plusMinutes(minutes).format(yyyyMMddHHmm);
|
|
|
}
|
|
|
public static String AfterSeconds(String time,long seconds){
|
|
|
LocalDateTime localDateTime = DateUtil.getTime(time);
|
|
|
return localDateTime.plusSeconds(seconds).format(yyyyMMddHHmmss);
|
|
|
}
|
|
|
|
|
|
public static String nowMonth(String time){
|
|
|
LocalDateTime localDateTime = LocalDate.parse(time, yyyyMMdd).atStartOfDay();
|
|
|
return localDateTime.format(yyyyMM);
|
|
|
}
|
|
|
|
|
|
public static String getCurrentMonth(){
|
|
|
return LocalDateTime.now().format(yyyyMM);
|
|
|
}
|
|
|
public static String getCurrentDate(){
|
|
|
return LocalDateTime.now().format(yyyyMMdd);
|
|
|
}
|
|
|
public static String getCurrentTime(){
|
|
|
return LocalDateTime.now().format(yyyyMMddHHmmss);
|
|
|
}
|
|
|
public static String getCurrentTime(String timeType){
|
|
|
DateTimeFormatter formatter = DateTimeFormatter.ofPattern(timeType);
|
|
|
return LocalDateTime.now().format(formatter);
|
|
|
}
|
|
|
|
|
|
//获得往后日期
|
|
|
public static String getCurrentDatePlusDay(int day){
|
|
|
return LocalDateTime.now().plusDays(day).format(yyyyMMdd);
|
|
|
}
|
|
|
//获得往前日期
|
|
|
public static String getCurrentDateMinusDay(int day){
|
|
|
return LocalDateTime.now().minusDays(day).format(yyyyMMdd);
|
|
|
}
|
|
|
|
|
|
|
|
|
public static LocalDateTime getTime(String time){
|
|
|
int length = time.length();
|
|
|
switch (length){
|
|
|
case 9:
|
|
|
String[] times = time.split("-");
|
|
|
|
|
|
if (times[1].length()==1){
|
|
|
times[1] = "0"+times[1];
|
|
|
}else if (times[2].length()==1){
|
|
|
times[2] = "0"+times[2];
|
|
|
}
|
|
|
time = times[0]+"-"+times[1]+"-"+times[2];
|
|
|
return LocalDate.parse(time, yyyyMMdd).atStartOfDay();
|
|
|
case 10:
|
|
|
return LocalDate.parse(time, yyyyMMdd).atStartOfDay();
|
|
|
case 19:
|
|
|
return LocalDateTime.parse(time, yyyyMMddHHmmss);
|
|
|
case 16:
|
|
|
return LocalDateTime.parse(time, yyyyMMddHHmm);
|
|
|
}
|
|
|
return null;
|
|
|
}
|
|
|
|
|
|
|
|
|
/**
|
|
|
* 获得时间与当前相差的小时
|
|
|
* @param startTime 开始时间 yyyy-MM-dd HH:mm:ss
|
|
|
* @return
|
|
|
*/
|
|
|
public static long getBetWeenHours(String startTime){
|
|
|
|
|
|
Duration duration = Duration.between(LocalDateTime.parse(startTime,yyyyMMddHHmmss),LocalDateTime.now());
|
|
|
|
|
|
return duration.toHours();
|
|
|
}
|
|
|
/**
|
|
|
* 获得两个时间相差的年份
|
|
|
* @param startTime 开始时间 yyyy-MM-dd
|
|
|
* @return
|
|
|
*/
|
|
|
public static int getBetWeenYears(String startTime){
|
|
|
Period duration = Period.between(LocalDate.parse(startTime,yyyyMMdd),LocalDateTime.now().toLocalDate());
|
|
|
|
|
|
return duration.getYears();
|
|
|
}
|
|
|
|
|
|
/**
|
|
|
* 获得两个时间相差的年份
|
|
|
* @param startTime 开始时间 yyyy-MM-dd
|
|
|
* @return
|
|
|
*/
|
|
|
public static int getBetWeenYears(String startTime,String endTime){
|
|
|
Period duration = Period.between(LocalDate.parse(startTime,yyyyMMdd),LocalDate.parse(endTime,yyyyMMdd));
|
|
|
return duration.getYears();
|
|
|
}
|
|
|
|
|
|
/**
|
|
|
* 获得两个时间相差的月份
|
|
|
* @param startTime 开始时间 yyyy-MM-dd
|
|
|
* @return
|
|
|
*/
|
|
|
public static int getBetWeenMonths(String startTime,String endTime){
|
|
|
LocalDateTime startDate = DateUtil.getTime(startTime);
|
|
|
LocalDateTime endDate = DateUtil.getTime(endTime);
|
|
|
|
|
|
YearMonth startYearMonth = YearMonth.from(startDate);
|
|
|
YearMonth endYearMonth = YearMonth.from(endDate);
|
|
|
|
|
|
int betweenMonth = (int) ChronoUnit.MONTHS.between(startYearMonth, endYearMonth);
|
|
|
if (startDate.getDayOfMonth()>endDate.getDayOfMonth()){
|
|
|
betweenMonth= betweenMonth-1;
|
|
|
}
|
|
|
return betweenMonth;
|
|
|
}
|
|
|
|
|
|
/**
|
|
|
* 获得两个时间相差的月份
|
|
|
* @param startTime 开始时间 yyyy-MM-dd
|
|
|
* @return
|
|
|
*/
|
|
|
public static int getBetWeenMonthsNeedDayOfMonth(String startTime,String endTime){
|
|
|
LocalDateTime startDate = DateUtil.getTime(startTime);
|
|
|
LocalDateTime endDate = DateUtil.getTime(endTime);
|
|
|
|
|
|
YearMonth startYearMonth = YearMonth.from(startDate);
|
|
|
YearMonth endYearMonth = YearMonth.from(endDate);
|
|
|
|
|
|
int betweenMonth = (int) ChronoUnit.MONTHS.between(startYearMonth, endYearMonth);
|
|
|
if (startDate.getDayOfMonth()>endDate.getDayOfMonth()){
|
|
|
betweenMonth= betweenMonth-1;
|
|
|
}
|
|
|
return betweenMonth;
|
|
|
}
|
|
|
|
|
|
/**
|
|
|
* 获得当前时间相差的天数
|
|
|
* @param startTime 开始时间 yyyy-MM-dd
|
|
|
* @return
|
|
|
*/
|
|
|
public static int getBetWeenDays(String startTime){
|
|
|
LocalDate startDate = LocalDate.parse(startTime);
|
|
|
LocalDate endDate = LocalDateTime.now().toLocalDate();
|
|
|
|
|
|
long daysBetween = ChronoUnit.DAYS.between(startDate, endDate);
|
|
|
return Math.toIntExact(daysBetween);
|
|
|
}
|
|
|
/**
|
|
|
* 获得当前时间相差的天数
|
|
|
* @param startTime 开始时间 yyyy-MM-dd
|
|
|
* @return
|
|
|
*/
|
|
|
public static int getBetWeenDays(String startTime,String endTime){
|
|
|
LocalDate startDate = LocalDate.parse(startTime);
|
|
|
LocalDate endDate = LocalDate.parse(endTime);
|
|
|
|
|
|
long daysBetween = ChronoUnit.DAYS.between(startDate, endDate);
|
|
|
return Math.toIntExact(daysBetween);
|
|
|
}
|
|
|
/**
|
|
|
* 获得当前时间相差的分钟数
|
|
|
* @param startTime 开始时间 yyyy-MM-dd
|
|
|
* @return
|
|
|
*/
|
|
|
public static int getBetWeenMinutes(String startTime,String endTime,DateTimeFormatter formatter){
|
|
|
LocalDateTime startDate = LocalDateTime.parse(startTime,formatter);
|
|
|
LocalDateTime endDate = LocalDateTime.parse(endTime,formatter);
|
|
|
|
|
|
long daysBetween = ChronoUnit.MINUTES.between(startDate, endDate);
|
|
|
return Math.toIntExact(daysBetween);
|
|
|
}
|
|
|
/**
|
|
|
* 获得当前时间相差的分钟数
|
|
|
* @param startTime 开始时间 yyyy-MM-dd
|
|
|
* @return
|
|
|
*/
|
|
|
public static int getBetWeenMinutes(String startTime,String endTime){
|
|
|
LocalDateTime startDate = DateUtil.getTime(startTime);
|
|
|
LocalDateTime endDate = DateUtil.getTime(endTime);
|
|
|
|
|
|
long daysBetween = ChronoUnit.MINUTES.between(startDate, endDate);
|
|
|
return Math.toIntExact(daysBetween);
|
|
|
}
|
|
|
|
|
|
/**
|
|
|
* 获得两个时间相差的小时
|
|
|
* @param startTime 开始时间 yyyy-MM-dd HH:mm:ss
|
|
|
* @param endTime 结束时间 yyyy-MM-dd HH:mm:ss
|
|
|
* @return
|
|
|
*/
|
|
|
public static long getBetWeenHours(String startTime,String endTime){
|
|
|
Duration duration = Duration.between(getTime(startTime),getTime(endTime));
|
|
|
|
|
|
return duration.toHours();
|
|
|
}
|
|
|
|
|
|
/**
|
|
|
* 获得两个时间相差的周
|
|
|
* @param startTime 开始时间
|
|
|
* @param endTime 结束时间
|
|
|
* @return
|
|
|
*/
|
|
|
public static int getBetweenWeeks(String startTime,String endTime){
|
|
|
int days = getBetWeenDays(startTime,endTime);
|
|
|
int dayOfWeek = TimeUtil.getDayOfWeek(startTime);
|
|
|
if (dayOfWeek == 0){
|
|
|
dayOfWeek = 7;
|
|
|
}
|
|
|
days = days-(7-dayOfWeek);
|
|
|
|
|
|
return days/7;
|
|
|
}
|
|
|
|
|
|
|
|
|
/**
|
|
|
* 获得该月份的天数
|
|
|
* @param time
|
|
|
* @return
|
|
|
*/
|
|
|
public static int getDays(String time,int CalendarType){
|
|
|
Calendar calendar = Calendar.getInstance();
|
|
|
calendar.set(Integer.valueOf(time.split("-")[0]), Integer.valueOf(time.split("-")[1]) - 1, 1);
|
|
|
return calendar.getActualMaximum(CalendarType);
|
|
|
}
|
|
|
|
|
|
public static String getTimeStr(int value){
|
|
|
String str = "";
|
|
|
if (value < 10){
|
|
|
str = "0"+value;
|
|
|
}else {
|
|
|
str = String.valueOf(value);
|
|
|
}
|
|
|
return str;
|
|
|
}
|
|
|
|
|
|
/**
|
|
|
* 获得所处季度的
|
|
|
*/
|
|
|
public static String getCurrentQuarter(String date){
|
|
|
String season1 = date.split("-")[0]+"-03-31";
|
|
|
String season2 = date.split("-")[0]+"-06-30";
|
|
|
String season3 = date.split("-")[0]+"-09-30";
|
|
|
String season4 = date.split("-")[0]+"-12-31";
|
|
|
|
|
|
if (DateUtil.getTime(date).compareTo(DateUtil.getTime(season1)) <=0){
|
|
|
return season1;
|
|
|
}else if (DateUtil.getTime(date).compareTo(DateUtil.getTime(season1)) >0 &&
|
|
|
DateUtil.getTime(date).compareTo(DateUtil.getTime(season2)) <=0){
|
|
|
return season2;
|
|
|
}else if (DateUtil.getTime(date).compareTo(DateUtil.getTime(season2)) >0 &&
|
|
|
DateUtil.getTime(date).compareTo(DateUtil.getTime(season3)) <=0){
|
|
|
return season3;
|
|
|
}else{
|
|
|
return season4;
|
|
|
}
|
|
|
}
|
|
|
/**
|
|
|
* 获得所处当前半年
|
|
|
*/
|
|
|
public static String getCurrentHalfYear(String date){
|
|
|
String season1 = date.split("-")[0]+"-06-30";
|
|
|
|
|
|
if (DateUtil.getTime(date).compareTo(DateUtil.getTime(season1)) <=0){
|
|
|
return season1;
|
|
|
}else {
|
|
|
return date.split("-")[0]+"-12-31";
|
|
|
}
|
|
|
}
|
|
|
|
|
|
public static String getFormatLocalDate(Date date) {
|
|
|
if (date == null) {
|
|
|
return StringUtils.EMPTY;
|
|
|
}
|
|
|
LocalDateTime localDateTime = dateToLocalDateTime(date);
|
|
|
return getFormatLocalDate(localDateTime);
|
|
|
}
|
|
|
public static String getFormatLocalDate(LocalDateTime localDateTime) {
|
|
|
if (localDateTime == null) {
|
|
|
return StringUtils.EMPTY;
|
|
|
}
|
|
|
try {
|
|
|
return localDateTime.format(yyyyMMdd);
|
|
|
} catch (Exception e) {
|
|
|
return StringUtils.EMPTY;
|
|
|
}
|
|
|
}
|
|
|
public static LocalDateTime dateToLocalDateTime(Date date) {
|
|
|
Instant instant = date.toInstant();
|
|
|
ZoneId zone = ZoneId.systemDefault();
|
|
|
return LocalDateTime.ofInstant(instant, zone);
|
|
|
}
|
|
|
|
|
|
// 正则表达式用于匹配日期格式yyyy-MM-dd,不验证日期是否合法
|
|
|
public static boolean dateIsValid(String date) {
|
|
|
if (date == null) {
|
|
|
return false;
|
|
|
}
|
|
|
// 编译正则表达式
|
|
|
Pattern pattern = Pattern.compile(DATE_PATTERN);
|
|
|
// 匹配日期字符串
|
|
|
Matcher matcher = pattern.matcher(date);
|
|
|
// 返回是否匹配的结果
|
|
|
return matcher.matches();
|
|
|
}
|
|
|
|
|
|
/**
|
|
|
* 检查年月格式
|
|
|
*
|
|
|
* @param yearMonth
|
|
|
* @return
|
|
|
*/
|
|
|
public static boolean checkYearMonth(String yearMonth) {
|
|
|
return Pattern.matches(MONTH_REGEX, yearMonth);
|
|
|
}
|
|
|
|
|
|
/**
|
|
|
* 获取两个日期间的日期集合
|
|
|
* @param startDateStr
|
|
|
* @param endDateStr
|
|
|
* @return
|
|
|
* @throws ParseException
|
|
|
*/
|
|
|
public static List<String> getDatesBetween(String startDateStr, String endDateStr) throws ParseException {
|
|
|
List<String> dates = new ArrayList<>();
|
|
|
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
|
|
|
Date startDate = sdf.parse(startDateStr);
|
|
|
Date endDate = sdf.parse(endDateStr);
|
|
|
|
|
|
Calendar calendar = Calendar.getInstance();
|
|
|
calendar.setTime(startDate);
|
|
|
|
|
|
while (calendar.getTime().before(endDate) || calendar.getTime().equals(endDate)) {
|
|
|
dates.add(sdf.format(calendar.getTime()));
|
|
|
calendar.add(Calendar.DATE, 1);
|
|
|
}
|
|
|
return dates;
|
|
|
}
|
|
|
|
|
|
/**
|
|
|
* 判断两个时间段是否有重叠部分
|
|
|
*/
|
|
|
public static boolean isOverlapping(String startTime1, String endTime1, String startTime2, String endTime2) {
|
|
|
// 如果结束时间小于另一个的开始时间,则不重叠
|
|
|
if (endTime1.compareTo(startTime2) <= 0) {
|
|
|
return false;
|
|
|
}
|
|
|
// 如果开始时间大于另一个的结束时间,则不重叠
|
|
|
if (startTime1.compareTo(endTime2) >= 0) {
|
|
|
return false;
|
|
|
}
|
|
|
// 否则,两个时间段重叠
|
|
|
return true;
|
|
|
}
|
|
|
|
|
|
/**
|
|
|
* 获取两个时间段重叠分钟数
|
|
|
*/
|
|
|
public static int getOverlappedMinutes(String startTime1, String endTime1, String startTime2, String endTime2) {
|
|
|
if (isOverlapping(startTime1, endTime1, startTime2, endTime2)) {
|
|
|
// 取两个段的最大开始和最小结束时间
|
|
|
String start = startTime1.compareTo(startTime2) >= 0 ? startTime1 : startTime2;
|
|
|
String end = endTime1.compareTo(endTime2) <= 0 ? endTime1 : endTime2;
|
|
|
// 计算重叠的分钟数
|
|
|
return getBetWeenMinutes(start, end);
|
|
|
}
|
|
|
// 如果不重叠,返回0
|
|
|
return 0;
|
|
|
}
|
|
|
|
|
|
/**
|
|
|
* 获取日期在一年中属于第几周
|
|
|
*/
|
|
|
public static int weekRank(String dateStr) throws Exception {
|
|
|
SimpleDateFormat formatter = new SimpleDateFormat("yyyy-MM-dd");
|
|
|
Date date = formatter.parse(dateStr);
|
|
|
Calendar calendar = Calendar.getInstance();
|
|
|
calendar.setTime(date);
|
|
|
calendar.setFirstDayOfWeek(Calendar.MONDAY);//设置星期一为一周开始的第一天
|
|
|
return calendar.get(Calendar.WEEK_OF_YEAR);
|
|
|
}
|
|
|
}
|