Please wait. This can take some minutes ...
Many resources are needed to download a project. Please understand that we have to compensate our server costs. Thank you in advance.
Project price only 1 $
You can buy this project and download/modify it how often you want.
com.gitee.apanlh.util.date.DateUtils Maven / Gradle / Ivy
package com.gitee.apanlh.util.date;
import com.gitee.apanlh.util.base.CollUtils;
import com.gitee.apanlh.util.base.MapUtils;
import com.gitee.apanlh.util.base.StringUtils;
import com.gitee.apanlh.util.date.format.DateTimeFormat;
import com.gitee.apanlh.util.date.parse.DateParser;
import com.gitee.apanlh.util.valid.Assert;
import java.time.Duration;
import java.time.Instant;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.LocalTime;
import java.time.Period;
import java.time.ZoneOffset;
import java.time.format.DateTimeFormatter;
import java.time.temporal.ChronoField;
import java.time.temporal.TemporalAdjusters;
import java.util.List;
import java.util.Map;
/**
* 时间工具类
* 1.工具类命名包含的dateTime则是年月日 时分秒
* 2.工具类命名包含的date则是年月日
* 3.工具类命名包含的time则是时分秒
*
* 数据库映射:
* {@code date -> LocalDate}
* {@code time -> LocalTime}
* {@code timestamp -> LocalDateTime}
*
* @author Pan
*/
public class DateUtils {
/** 标准时间标记 */
private static final char NORM_TAG = '-';
/** 验证最小值 */
private static final int MIN_NUMBER = 48;
/** 验证最大值 */
private static final int MAX_NUMBER = 57;
/** 一整天的毫秒数 */
private static final long MILLIS_OF_ONE_DAY = 86400000L;
/** 进位 */
private static final long CARRY_BIT = 60L;
private static final long CARRY_MILLIS_BIT = 1000L;
/** 天数 */
private static final int SATURDAY = 6;
private static final int SUNDAY = 7;
/** 格林尼治标准时间 北京时间 */
private static final String GMT_BEIJING = "+08:00";
/**
* 构造函数
* @author Pan
*/
private DateUtils() {
// 不允许外部示例
super();
}
/**
* 返回当前时间
* 格式yyyy-MM-dd HH:mm:ss
*
* @author Pan
* @return String yyyy-MM-dd HH:mm:ss
*/
public static String currentTime() {
return LocalDateTime.now().format(DateTimeFormat.getFormat(DateTimeFormat.DATE_TIME_FULL));
}
/**
* 返回当前时间
* 自定义格式
*
* @author Pan
* @param format 自定义格式
* @return String
*/
public static String currentTime(String format) {
return LocalDateTime.now().format(DateTimeFormat.getFormat(format));
}
/**
* 小时转换秒数
*
* @author Pan
* @param specifiedHours 指定分钟时间
* @return long
*/
public static long convertHoursToSeconds(long specifiedHours) {
return specifiedHours * CARRY_BIT * CARRY_BIT;
}
/**
* 分钟转换秒数
*
* @author Pan
* @param specifiedMinute 指定分钟时间
* @return long
*/
public static long convertMinToSeconds(long specifiedMinute) {
return specifiedMinute * CARRY_BIT;
}
/**
* 获取指定小时的毫秒数
*
* @author Pan
* @param specifiedHours 指定分钟时间
* @return long
*/
public static long convertHoursToMillis(long specifiedHours) {
return specifiedHours * CARRY_BIT * CARRY_BIT * CARRY_MILLIS_BIT;
}
/**
* 获取指定分钟的毫秒数
*
* @author Pan
* @param specifiedMinute 指定分钟时间
* @return long
*/
public static long convertMinToMillis(long specifiedMinute) {
return specifiedMinute * CARRY_BIT * CARRY_MILLIS_BIT;
}
/**
* 获取指定秒的毫秒数
*
* @author Pan
* @param specifiedSeconds 指定秒时间
* @return long
*/
public static long convertSecondToMillis(long specifiedSeconds) {
return specifiedSeconds * CARRY_MILLIS_BIT;
}
/**
* 年月日时分秒格式-当前时间和指定的时间比较
* endTime 时间格式为 yyyy-MM-dd HH:mm:ss
* 当前时间大于则返回1或1以上
* 当前时间等于则返回0
* 当前时间小于则返回-1或-1以下。
* 如果超出天数则返回相差的天数或月份或者年(2022-01-11 10:00:00, 2022-01-13 10:00:00)此时小于天数则返回-2
*
* @author Pan
* @param endTime 结束时间
* @return int
*/
public static int dateTimeCompareTo(String endTime) {
LocalDateTime now = LocalDateTime.now();
return LocalDateTime.of(now.getYear(), now.getMonthValue(), now.getDayOfMonth(), now.getHour(), now.getMinute(),now.getSecond())
.compareTo(DateParser.getLocalDateTime(endTime));
}
/**
* 年月日时分秒格式-指定时间区间比较
* startTime和endTime时间格式均为 yyyy-MM-dd HH:mm:ss
* 开始时间大于则返回1或1以上
* 开始时间等于则返回0
* 开始时间小于则返回-1或-1以下。
* 如果超出天数则返回相差的天数或月份或者年(2022-01-11 10:00:00, 2022-01-13 10:00:00)此时小于天数则返回-2
*
* @author Pan
* @param startTime 开始时间
* @param endTime 结束时间
* @return int
*/
public static int dateTimeCompareTo(String startTime, String endTime) {
Assert.isNotEmpty(startTime);
Assert.isNotEmpty(endTime);
return DateParser.getLocalDateTime(startTime).compareTo(DateParser.getLocalDateTime(endTime));
}
/**
* 年月日时分秒格式-指定时间区间比较
* 将时间转换毫秒数进行对比
* 时间格式为 yyyy-MM-dd HH:mm:ss
* 开始时间大于则返回1
* 开始时间等于则返回零(0)
* 开始时间小于则返回-1。
*
* @author Pan
* @param startTime 开始时间
* @param endTime 结束时间
* @return int
*/
public static int dateTimeCompareToByMillis(String startTime, String endTime) {
Assert.isNotEmpty(startTime);
Assert.isNotEmpty(endTime);
ZoneOffset of = ZoneOffset.of(GMT_BEIJING);
long compare = DateParser.getLocalDateTime(startTime).toInstant(of).toEpochMilli();
long compare2 = DateParser.getLocalDateTime(endTime).toInstant(of).toEpochMilli();
if (compare > compare2) {
return 1;
} else if (compare < compare2) {
return -1;
} else {
return 0;
}
}
/**
* 年月日时分秒格式-开始时间与指定结束时间比较
* 将时间转换毫秒数进行对比
* 时间格式为 yyyy-MM-dd HH:mm:ss
* 开始时间大于则返回1
* 开始时间等于则返回零(0)
* 开始时间小于则返回-1。
*
* @author Pan
* @param endTime 结束的指定时间要求时间格式为 yyyy-MM-dd HH:mm:ss
* @return int
*/
public static int dateTimeCompareToByMillis(String endTime) {
long currentTimeMillis = System.currentTimeMillis();
long epochMilli = DateParser.getLocalDateTime(endTime).toInstant(ZoneOffset.of(GMT_BEIJING)).toEpochMilli();
if (currentTimeMillis > epochMilli) {
return 1;
} else if (currentTimeMillis < epochMilli) {
return -1;
} else {
return 0;
}
}
/**
* 年月日时分秒格式-根据当前时间进行偏移
* 单位为天
* 严格要求时间是yyyy-MM-dd HH:mm:ss格式
* 偏移量规则:正数(时间线为之前), 负数(时间线为之后)
*
* @author Pan
* @param offsetDays 偏移量
* @return String yyyy-MM-dd HH:mm:ss
*/
public static String dateTimeOffsetByDay(long offsetDays) {
return LocalDateTime.now().minusDays(offsetDays).format(DateTimeFormat.getFormat(DateTimeFormat.DATE_TIME_FULL));
}
/**
* 年月日时分秒格式-根据指定时间进行偏移
* 单位为天
* 严格要求时间是yyyy-MM-dd HH:mm:ss格式
* 偏移量规则:正数(时间线为之前), 负数(时间线为之后)
*
* @author Pan
* @param time 时间
* @param offsetDays 偏移量
* @return String
*/
public static String dateTimeOffsetByDay(String time, long offsetDays) {
return dateTimeOffsetByDay(time, offsetDays, DateTimeFormat.DATE_FULL);
}
/**
* 年月日时分秒格式-根据指定时间进行偏移
* 单位为天
* 严格要求时间是yyyy-MM-dd HH:mm:ss格式
* 偏移量规则:正数(时间线为之前), 负数(时间线为之后)
* 自定义转换格式
*
* @author Pan
* @param time 时间
* @param offsetDays 偏移量
* @param format 自定义格式
* @return String
*/
public static String dateTimeOffsetByDay(String time, long offsetDays, String format) {
return DateParser.getLocalDateTime(time).minusDays(offsetDays).format(DateTimeFormat.getFormat(format));
}
/**
* 年月日时分秒格式-根据指定时间进行偏移
* 单位为小时
* 严格要求时间格式为yyyy-MM-dd HH:mm:ss
* 偏移量规则:正数(时间线为之前), 负数(时间线为之后)
*
* @author Pan
* @param time 指定时间
* @param offsetHours 偏移量
* @return String
*/
public static String dateTimeOffsetByHours(String time, long offsetHours) {
return dateTimeOffsetByHours(time, offsetHours, DateTimeFormat.DATE_TIME_FULL);
}
/**
* 年月日时分秒格式-设置传递时间的偏移量
* 单位为小时
* 严格要求时间格式为yyyy-MM-dd HH:mm:ss
* 偏移量规则:正数(时间线为之前), 负数(时间线为之后)
*
* @author Pan
* @param time 指定时间
* @param offsetHours 偏移量
* @param format 自定义格式
* @return String
*/
public static String dateTimeOffsetByHours(String time, long offsetHours, String format) {
return DateParser.getLocalDateTime(time).minusHours(offsetHours).format(DateTimeFormat.getFormat(format));
}
/**
* 年月日时分秒格式-根据当前时间进行偏移
* 单位为分钟
* 严格要求时间格式为yyyy-MM-dd HH:mm:ss
* 偏移量规则:正数(时间线为之前), 负数(时间线为之后)
*
* @author Pan
* @param offsetMin 偏移量
* @return String 时分秒 HH:ss:mm
*/
public static String dateTimeOffsetByMinutes(long offsetMin) {
return dateTimeOffsetByMinutes(offsetMin, DateTimeFormat.DATE_TIME_FULL);
}
/**
* 年月日时分秒格式-根据当前时间进行偏移
* 单位为分钟
* 严格要求时间格式为yyyy-MM-dd HH:mm:ss
* 偏移量规则:正数(时间线为之前), 负数(时间线为之后)
* 自定义返回格式
*
* @author Pan
* @param offsetMin 偏移量
* @param format 自定义时间格式
* @return String
*/
public static String dateTimeOffsetByMinutes(long offsetMin, String format) {
return LocalDateTime.now().minusMinutes(offsetMin).format(DateTimeFormat.getFormat(format));
}
/**
* 年月日格式-开始时间与指定结束时间比较
* 返回1[起始时间 大于 结束时间]
* 返回0[起始时间 等于 结束时间 ]
* 返回-1[起始时间 小于 结束时间]
*
* @author Pan
* @param endTime 结束时间
* @return int
*/
public static int dateCompareTo(String endTime) {
Assert.isNotEmpty(endTime);
LocalDate start = LocalDate.now();
LocalDate end = DateParser.getLocalDate(endTime);
if (start.isAfter(end)) {
return 1;
} else if (start.isBefore(end)) {
return -1;
} else {
return 0;
}
}
/**
* 年月日格式-指定时间区间
* 返回1[起始时间 大于 结束时间]
* 返回0[起始时间 等于 结束时间 ]
* 返回-1[起始时间 小于 结束时间]
*
* @author Pan
* @param startTime 开始时间
* @param endTime 结束时间
* @return int
*/
public static int dateCompareTo(String startTime, String endTime) {
Assert.isNotEmpty(startTime);
Assert.isNotEmpty(endTime);
LocalDate start = DateParser.getLocalDate(startTime);
LocalDate end = DateParser.getLocalDate(endTime);
if (start.isAfter(end)) {
return 1;
} else if (start.isBefore(end)) {
return -1;
} else {
return 0;
}
}
/**
* 年月日格式-时间日期按范围比较
* 验证是否在某个时间区间内
* 例如:开始时间区间2021-01-15, 结束时间区间2021-01-25, 时间 2022-01-26(返回false)
*
* @author Pan
* @param startRange 指定开始时间区间
* @param endRange 指定结束时间区间
* @param time 指定时间
* @return boolean 为包含时间范围内 false为不在包含时间范围内
*/
public static boolean dateCompareToByRange(String startRange, String endRange, String time) {
LocalDate startRangeDate = DateParser.getLocalDate(startRange);
LocalDate endRangeDate = DateParser.getLocalDate(endRange);
LocalDate timeDate = DateParser.getLocalDate(time);
return !timeDate.isBefore(startRangeDate) && !timeDate.isAfter(endRangeDate);
}
/**
* 年月日格式-根据当前时间进行偏移
* 单位为天
* 严格要求时间是yyyy-MM-dd格式
* 偏移量规则:正数(时间线为之前), 负数(时间线为之后)
*
* @author Pan
* @param offsetDays 偏移量
* @return String
*/
public static String dateOffsetByDay(long offsetDays) {
return LocalDate.now().minusDays(offsetDays).format(DateTimeFormat.getFormat(DateTimeFormat.DATE_FULL));
}
/**
* 年月日格式-偏移指定时间
* 单位为天
* 严格要求时间是yyyy-MM-dd格式
* 偏移量规则:正数(时间线为之前), 负数(时间线为之后)
*
* @author Pan
* @param time 时间
* @param offsetDays 偏移量
* @return String
*/
public static String dateOffsetByDay(String time, long offsetDays) {
return dateOffsetByDay(time, offsetDays, DateTimeFormat.DATE_FULL);
}
/**
* 年月日格式-偏移指定时间
* 单位为天
* 严格要求时间是yyyy-MM-dd格式
* 自定义转换格式
* 偏移量规则:正数(时间线为之前), 负数(时间线为之后)
*
* @author Pan
* @param time 时间
* @param offsetDays 偏移量
* @param format 自定义格式
* @return String
*/
public static String dateOffsetByDay(String time, long offsetDays, String format) {
return DateParser.getLocalDate(time).minusDays(offsetDays).format(DateTimeFormat.getFormat(format));
}
/**
* 年月日-根据当前时间进行偏移
* 单位为月
* 严格要求时间是yyyy-MM-dd格式
* 偏移量规则:正数(时间线为之前), 负数(时间线为之后)
*
* @author Pan
* @param offsetMonth 偏移量
* @return String yyyy-MM-dd
*/
public static String dateOffsetByMonth(long offsetMonth) {
return LocalDate.now().minusMonths(offsetMonth).format(DateTimeFormat.getFormat(DateTimeFormat.DATE_FULL));
}
/**
* 年月日-根据指定时间进行偏移
* 单位为月
* 严格要求时间是yyyy-MM-dd格式
* 偏移量规则:正数(时间线为之前), 负数(时间线为之后)
*
* @author Pan
* @param time 时间
* @param offsetMonth 偏移量
* @return String yyyy-MM-dd
*/
public static String dateOffsetByMonth(String time, long offsetMonth) {
return dateOffsetByMonth(time, offsetMonth, DateTimeFormat.DATE_FULL);
}
/**
* 年月日-根据指定时间进行偏移
* 单位为月
* 严格要求时间是yyyy-MM-dd格式
* 自定义转换格式
* 偏移量规则:正数(时间线为之前), 负数(时间线为之后)
*
* @author Pan
* @param time 指定时间的字符串 格式必须为yyyy-MM-dd
* @param offsetMonth 偏移量
* @param format 自定义转换 年月日格式的时间
* @return String 格式转换后的时间类型
*/
public static String dateOffsetByMonth(String time, long offsetMonth, String format) {
return DateParser.getLocalDate(time).minusMonths(offsetMonth).format(DateTimeFormat.getFormat(format));
}
/**
* 获取月份的相差值
* 整数为 开始时间与结束时间相差的值
* 负数为 结束时间与开始时间相差的值
* 范围 不能超过1年 最大为11月的相差值
*
* @author Pan
* @param startTime 年月日的时间日期类型
* @param endTime 年月日的时间日期类型
* @return int 相差月份
*/
public static int dateBetweenByMonth(LocalDate startTime, LocalDate endTime) {
return Period.between(startTime, endTime).getMonths();
}
/**
* 获取月份的相差值
* 范围不能超过1年,最大为11月的相差值
*
* @author Pan
* @param startTime 开始时间格式必须为 yyyy-MM-dd
* @param endTime 结束时间格式必须为 yyyy-MM-dd
* @return int
*/
public static int dateBetweenByMonth(String startTime, String endTime) {
return dateBetweenByMonth(DateParser.getLocalDate(startTime), DateParser.getLocalDate(endTime));
}
/**
* 负数为 开始时间与结束时间的差值
* 整数为 结束时间与开始时间的差值
*
* @author Pan
* @param startTime 开始时间
* @param endTime 结束时间
* @return long 相差的天数
*/
public static long dateBetweenByDay(String startTime, String endTime) {
return dateBetweenByDay(DateParser.getLocalDate(startTime), DateParser.getLocalDate(endTime));
}
/**
* 负数为 开始时间与结束时间的差值
* 整数为 结束时间与开始时间的差值
*
* @author Pan
* @param startTime 开始时间
* @param endTime 结束时间
* @return long 相差的天数
*/
public static long dateBetweenByDay(LocalDate startTime, LocalDate endTime) {
return startTime.toEpochDay() - endTime.toEpochDay();
}
/**
* 年月日时分秒-时间格式
* 严格要求传递的时间格式是标准时间格式(yyyy-MM-dd HH:mm:ss)
* 自定义时间格式
*
* @author Pan
* @param dateTime 时间字符串
* @param targetFormat 转换格式
* @return String 格式化字符
*/
public static String formatDateTime(String dateTime, String targetFormat) {
return DateParser.getLocalDateTime(dateTime).format(DateTimeFormat.getFormat(targetFormat));
}
/**
* 年月日时分秒-时间格式
* 自定义解析格式
* 自定义时间格式
* 例如:formatDateTime(time, yyyy-MM-dd HH:mm:ss, "yyyy年MM月dd日 HH时mm分ss秒");
*
* @author Pan
* @param dateTime 时间字符串
* @param sourceFormat 传入时间格式
* @param targetFormat 转换格式
* @return String 格式化字符
*/
public static String formatDateTime(String dateTime, String sourceFormat, String targetFormat) {
return DateParser.getLocalDateTime(dateTime, sourceFormat).format(DateTimeFormat.getFormat(targetFormat));
}
/**
* 年月日-时间格式
* 严格要求传递的时间格式是标准时间格式(yyyy-MM-dd)
* 自定义时间格式
* 例如:formatDateTime(time, yyyy-MM-dd HH:mm:ss, "yyyy年MM月dd日 HH时mm分ss秒");
*
* @author Pan
* @param dateTime 时间字符串
* @param targetFormat 转换格式
* @return String 格式化字符
*/
public static String formatDate(String dateTime, String targetFormat) {
return DateParser.getLocalDate(dateTime).format(DateTimeFormat.getFormat(targetFormat));
}
/**
* 年月日-时间格式
* 自定义解析格式
* 自定义时间格式
* 例如:formatDate(time, yyyy-MM-dd, "yyyy年MM月dd日");
*
* @author Pan
* @param dateTime 时间字符串
* @param sourceFormat 传入时间格式
* @param targetFormat 转换格式
* @return String 格式化字符
*/
public static String formatDate(String dateTime, String sourceFormat, String targetFormat) {
return DateParser.getLocalDate(dateTime, sourceFormat).format(DateTimeFormat.getFormat(targetFormat));
}
/**
* 时分秒-时间格式
* 严格要求传递的时间格式是标准时间格式(HH:mm:ss)
* formatTime(time, "HH:mm:ss", "HH时mm分ss秒");
*
* @author Pan
* @param dateTime 时间字符串
* @param targetFormat 转换格式
* @return String 格式化字符
*/
public static String formatTime(String dateTime, String targetFormat) {
return DateParser.getLocalTime(dateTime).format(DateTimeFormat.getFormat(targetFormat));
}
/**
* 时分秒-时间格式
* 自定义解析格式
* 自定义时间格式
* 例如:formatTime(time, "HH:mm:ss", "HH时mm分ss秒");
*
* @author Pan
* @param dateTime 时间字符串
* @param sourceFormat 传入时间格式
* @param targetFormat 转换格式
* @return String 格式化字符
*/
public static String formatTime(String dateTime, String sourceFormat, String targetFormat) {
return DateParser.getLocalTime(dateTime, sourceFormat).format(DateTimeFormat.getFormat(targetFormat));
}
/**
* 时分秒格式-对比小时
* 不包含分钟、秒
* 大于则返回一个正值
* 等于则返回零(0)
* 小于则返回负值。
*
* @author Pan
* @param hours 小时
* @return int
*/
public static int timeCompareTo(int hours) {
LocalTime now = LocalTime.now();
return LocalTime.of(now.getHour(), now.getMinute()).compareTo(LocalTime.of(hours, 0));
}
/**
* 时分秒格式-对比小时以及分钟
* 不包含秒
* 大于则返回一个正值
* 等于则返回零(0)
* 小于则返回负值。
*
* @author Pan
* @param hours 小时
* @param minute 分钟
* @return int
*/
public static int timeCompareTo(int hours, int minute) {
LocalTime now = LocalTime.now();
return LocalTime.of(now.getHour(), now.getMinute()).compareTo(LocalTime.of(hours, minute));
}
/**
* 时分秒格式-对比小时
* 包含分钟以及秒
* 大于则返回一个正值
* 等于则返回零(0)
* 小于则返回负值。
*
* @author Pan
* @param hours 小时
* @param minute 分钟
* @param seconds 秒
* @return int
*/
public static int timeCompareTo(int hours, int minute, int seconds) {
LocalTime now = LocalTime.now();
return LocalTime.of(now.getHour(), now.getMinute(), now.getSecond()).compareTo(LocalTime.of(hours, minute, seconds));
}
/**
* 时分秒格式-范围比较
* 验证是否在某个时间区间内
* 例如:开始时间区间09:10:10, 结束时间区间10:00:00, 当前时间 11:01:01(返回false)
*
* @author Pan
* @param startRange 指定开始时间区间
* @param endRange 指定结束时间区间
* @param time 指定时间
* @return boolean 为包含时间范围内 false为不在包含时间范围内
*/
public static boolean timeCompareToByRange(String startRange, String endRange, String time) {
LocalTime startRangeDate = DateParser.getLocalTime(startRange);
LocalTime endRangeDate = DateParser.getLocalTime(endRange);
LocalTime timeDate = DateParser.getLocalTime(time);
return !timeDate.isBefore(startRangeDate) && !timeDate.isAfter(endRangeDate);
}
/**
* 判断当前是否是指定时间范围内(小时)
* 在指定范围内为true
*
* @author Pan
* @param hours 开始时间
* @param compareHours 结束时间
* @return boolean
*/
public static boolean timeCompareToHoursByRange(int hours, int compareHours) {
int hour = LocalTime.now().getHour();
return hour >= hours && hour <= compareHours;
}
/**
* 时分秒格式-根据当前时间偏移量
* 单位为小时
* 严格要求时间格式为HH:mm:ss
* 偏移量规则:正数(时间线为之前), 负数(时间线为之后)
*
* @author Pan
* @param offsetHours 偏移量
* @return String
*/
public static String timeOffsetByHours(long offsetHours) {
return LocalTime.now().minusHours(offsetHours).format(DateTimeFormat.getFormat(DateTimeFormat.TIME_FULL));
}
/**
* 获取当前时间偏移量
* 单位为秒
* 严格要求时间格式为HH:mm:ss
* 偏移量规则:正数(时间线为之前), 负数(时间线为之后)
*
* @author Pan
* @param offsetSecond 偏移量
* @return String
*/
public static String timeOffsetBySeconds(long offsetSecond) {
return LocalTime.now().minusSeconds(offsetSecond).format(DateTimeFormat.getFormat(DateTimeFormat.TIME_FULL));
}
/**
* 获取当前时间近n天 包含今天
* 偏移量如果是正数为时间线之前,负数为时间线之后
* 倒序排序天数
* 格式yyyy-MM-dd
*
* @author Pan
* @param offsetDays 偏移量
* @return List
*/
public static List getRecentDays(long offsetDays) {
return getRecentDays(offsetDays, DateTimeFormat.DATE_FULL);
}
/**
* 获取当前时间近n天 包含今天
* 偏移量如果是正数为时间线之前,负数为时间线之后
* 倒序排序天数
* 支持自定义格式
*
* @author Pan
* @param offsetDays 偏移量
* @param format 自定义格式
* @return List
*/
public static List getRecentDays(long offsetDays, String format) {
List days = CollUtils.newArrayList(offsetDays < 0 ? (int) offsetDays - ((int) offsetDays * 2) : (int) offsetDays);
if (offsetDays == 0L) {
days.add(currentTime(DateTimeFormat.DATE_FULL));
return days;
}
LocalDateTime now = LocalDateTime.now();
if (offsetDays < 0) {
for (long i = offsetDays; i <= 0; i++) {
days.add(now.minusDays(i).format(DateTimeFormat.getFormat(format)));
}
} else {
for (long i = 0; i <= offsetDays; i++) {
days.add(now.minusDays(i).format(DateTimeFormat.getFormat(format)));
}
}
return days;
}
/**
* 获取当前时间到明天0点0分0秒区间的毫秒数
*
* @author Pan
* @return long 毫秒数
*/
public static long getTomorrowMidnightMillis() {
LocalDateTime now = LocalDateTime.now();
return MILLIS_OF_ONE_DAY - (
convertHoursToMillis(now.getHour()) +
convertMinToMillis(now.getMinute()) +
convertSecondToMillis(now.getSecond()) +
now.get(ChronoField.MILLI_OF_SECOND)
);
}
/**
* 获取目前时间到本月最后一天 23点59分59秒的区间毫秒数
*
* @author Pan
* @return long 毫秒数
*/
public static long getLastDayOfMonthToMillis() {
LocalDateTime now = LocalDateTime.now();
Duration between = Duration.between(
now,
LocalDateTime.of(now.getYear(), now.getMonthValue(), now.getMonth().maxLength(), 23, 59, 59)
);
return between.toMillis();
}
/**
* 获取当前季度的第一个月为几月
*
* @author Pan
* @return int 当前季度的第一个月份
*/
public static int getFirstMonthOfQuarter() {
return LocalDate.now().getMonth().firstMonthOfQuarter().getValue();
}
/**
* 获取当前年
*
* @author Pan
* @return int
*/
public static int getCurrentYear() {
return LocalDate.now().getYear();
}
/**
* 获取当前所在天数
*
* @author Pan
* @return int
*/
public static int getCurrentDay() {
return LocalDate.now().getDayOfMonth();
}
/**
* 获取当前日期的指定时间
*
* @author Pan
* @param hour 小时
* @param minute 分钟
* @param second 秒
* @return String yyyy-MM-dd HH:mm:ss
*/
public static String getCurrentDaySpecifiedTime(int hour, int minute, int second) {
LocalDateTime now = LocalDateTime.now();
return LocalDateTime.of(now.getYear(), now.getMonthValue(), now.getDayOfMonth(), hour, minute, second).format(DateTimeFormat.getFormat(DateTimeFormat.DATE_TIME_FULL));
}
/**
* 获取当前月份
*
* @author Pan
* @return int
*/
public static int getCurrentMonth() {
return LocalDate.now().getMonthValue();
}
/**
* 获取当前月份第一天
*
* @author Pan
* @return String yyyy-MM-dd HH:mm:ss
*/
public static String getCurrentMonthFirstDay() {
return getCurrentMonthFirstDay(0, 0, 0);
}
/**
* 获取当前月份第一天的指定时间
*
* @author Pan
* @param hour 小时
* @param minute 分钟
* @param second 秒
* @return String yyyy-MM-dd HH:mm:ss
*/
public static String getCurrentMonthFirstDay(int hour, int minute, int second) {
return getCurrentMonthFirstDay(hour, minute, second, DateTimeFormat.DATE_TIME_FULL);
}
/**
* 获取当前月份第一天的指定时间
*
* 返回自定义格式
* @author Pan
* @param hour 小时
* @param minute 分钟
* @param second 秒
* @param format 自定义格式
* @return String
*/
public static String getCurrentMonthFirstDay(int hour, int minute, int second, String format) {
LocalDateTime now = LocalDateTime.now();
return LocalDateTime.of(now.getYear(), now.getMonthValue(), 1, hour, minute, second)
.format(DateTimeFormat.getFormat(format));
}
/**
* 获取本月的最后一天
*
* @author Pan
* @return String yyyy-MM-dd HH:mm:ss
*/
public static String getCurrentMonthLastDay() {
return getCurrentMonthLastDay(0, 0, 0);
}
/**
* 获取本月的最后一天
* 自定义返回HH:mm:ss部分
*
* @author Pan
* @param hour 小时
* @param minute 分钟
* @param second 秒
* @return String yyyy-MM-dd
*/
public static String getCurrentMonthLastDay(int hour, int minute, int second) {
return getCurrentMonthLastDay(hour, minute, second, DateTimeFormat.DATE_TIME_FULL);
}
/**
* 获取本月的最后一天
* 自定义返回HH:mm:ss部分
* 自定义返回格式
*
* @param hour 小时
* @param minute 分钟
* @param second 秒
* @param format 自定义返回格式
* @return String 自定义返回格式
*/
public static String getCurrentMonthLastDay(int hour, int minute, int second, String format) {
LocalDate with = LocalDate.now().with(TemporalAdjusters.lastDayOfMonth());
LocalDateTime localDatetime = LocalDateTime.of(
with.getYear(),
with.getMonthValue(),
with.getDayOfMonth(),
hour,
minute,
second
);
return localDatetime.format(DateTimeFormat.getFormat(format));
}
/**
* 获取返回到目前为止的最大月份
*
* @author Pan
* @return List
*/
public static List getCurrentMonthList() {
int monthValue = LocalDate.now().getMonthValue();
List list = CollUtils.newArrayList(monthValue);
for (int i = monthValue ; i >= 1 ; i --) {
list.add(i);
}
return list;
}
/**
* 获取当前月份是第几季度
*
* @author Pan
* @return int 当前是第几季度
*/
public static int getCurrentQuarter() {
int month = LocalDate.now().getMonth().getValue();
int firstMonth = 3;
int quarter = 1;
for (;;) {
if (month <= firstMonth) {
return quarter;
}
quarter = quarter + 1;
firstMonth = firstMonth + 3;
}
}
/**
* 获取当前截止的季度
* 返回包含当前季度到初始季度
*
* @author Pan
* @return List
*/
public static List getCurrentQuarterList() {
List list = CollUtils.newArrayList();
for (int i = getCurrentQuarter() ; i >= 1; i--) {
list.add(i);
}
return list;
}
/**
* 获取目前所在星期的第几天
*
* @author Pan
* @return int
*/
public static int getCurrentDayOfWeek() {
return LocalDate.now().getDayOfWeek().getValue();
}
/**
* 获取当前小时
*
* @author Pan
* @return int
*/
public static int getCurrentHour() {
return LocalTime.now().getHour();
}
/**
* 获取当前小时的起始以及结束时间
* 例如:2021-06-01 10:00:00~2021-06-01 10:59:59
*
* @author Pan
* @return String yyyy-MM-dd HH:mm:ss时间格式
*/
public static String getCurrentHourRange() {
return getCurrentHourRange(0, DateTimeFormat.DATE_TIME_FULL);
}
/**
* 获取当前小时的起始以及结束时间
* 支持自定义时间范围
* 例如:2021-06-01 10:00:00~2021-06-01 10:59:59
*
* @author Pan
* @param offsetHours offsetHours 小时整数:在时间线之前为负数,时间线之后为正数
* @return String yyyy-MM-dd HH:mm:ss时间格式
*/
public static String getCurrentHourRange(long offsetHours) {
return getCurrentHourRange(offsetHours, DateTimeFormat.DATE_TIME_FULL);
}
/**
* 获取当前小时的起始以及结束时间
* 支持自定义时间范围
* 支持自定义时间格式
* 例如:10:00:00~10:59:59, 2021-06-30 10:00:00~2021-06-30 10:59:59
* 返回格式不限
*
* @author Pan
* @param format 解析格式
* @param offsetHours 小时偏移量 偏移量规则:正数(时间线为之前), 负数(时间线为之后)
* @return String 自定义时间格式
*/
public static String getCurrentHourRange(long offsetHours, String format) {
LocalDateTime now = LocalDateTime.now();
int year = now.getYear();
int month = now.getMonth().getValue();
int day = now.getDayOfMonth();
int hour = now.getHour();
if (offsetHours != 0) {
LocalDateTime minusHours = now.minusHours(offsetHours);
hour = minusHours.getHour();
year = minusHours.getYear();
month = minusHours.getMonthValue();
day = minusHours.getDayOfMonth();
}
DateTimeFormatter dtf = DateTimeFormat.getFormat(format);
return StringUtils.format("{}~{}",
LocalDateTime.of(year, month, day, hour, 0, 0).format(dtf),
LocalDateTime.of(year, month, day, hour, 59, 59).format(dtf)
);
}
/**
* 根据秒获取当天的毫秒数
*
* @author Pan
* @return long
*/
public static long getCurrentMillisOfSeconds() {
return LocalDateTime.now().get(ChronoField.MILLI_OF_SECOND);
}
/**
* 获取当天毫秒数
* 根据当天0点起算到现在的毫秒数
*
* @author Pan
* @return long
*/
public static long getCurrentMillisOfDay() {
return LocalDateTime.now().getLong(ChronoField.MILLI_OF_DAY);
}
/**
*
* 获取上个月份的当前天数
* 如果单月当前天数超出上月最大天数时将返回上月最大天数
* 返回格式为 yyyy-MM-dd
*
* @author Pan
* @return String
*/
public static String getPreviousMonth() {
return LocalDate.now().minusMonths(1).format(DateTimeFormat.getFormat(DateTimeFormat.DATE_FULL));
}
/**
* 获取上个月份的第一天
* 返回格式为 yyyy-MM-dd
*
* @author Pan
* @return String
*/
public static String getPreviousMonthFirstDay() {
LocalDate minusMonths = LocalDate.now().minusMonths(1);
int offset = minusMonths.getDayOfMonth() - 1;
return minusMonths.minusDays(offset)
.format(DateTimeFormat.getFormat(DateTimeFormat.DATE_FULL));
}
/**
* 获取指定月份的第一天
* 返回格式为 yyyy-MM-dd
*
* @author Pan
* @param offset 整数为 前几个月 负数为 后几个月
* @return String
*/
public static String getPreviousMonthFirstDay(int offset) {
LocalDate minusMonths = LocalDate.now().minusMonths(offset);
int lastOffset = minusMonths.getDayOfMonth() - 1;
return minusMonths.minusDays(lastOffset)
.format(DateTimeFormat.getFormat(DateTimeFormat.DATE_FULL));
}
/**
* 获取下一个月的字符串值
* 返回字符串
*
* @author Pan
* @param val 整数为下一个月 负数为上一个月
* @return String 返回时间格式为 yyyy-MM-dd
*/
public static String getNextMonth(int val) {
return LocalDate.now()
.plusMonths(val)
.format(DateTimeFormat.getFormat(DateTimeFormat.DATE_FULL));
}
/**
* 获取下一个月的字符串值
* 支持自定义格式
*
* @author Pan
* @param val 整数为下一个月 负数为上一个月
* @param formatter 自定义格式 只能是年月日 或年月 月日 日等 不能超过年月日范围
* @return String 返回年月日的 任意格式
*/
public static String getNextMonth(int val, String formatter) {
return LocalDate.now().plusMonths(val).format(DateTimeFormat.getFormat(formatter));
}
/**
* 获取指定时间的下一个月份
*
* @author Pan
* @param time 指定时间
* @param sourcesFormatter 指定时间的 时间格式
* @param value 整数为下一个月 负数为上一个月
* @return String 标准时间格式 yyyy-MM-dd
*/
public static String getNextMonth(String time, String sourcesFormatter, int value) {
return LocalDate.parse(time, DateTimeFormatter.ofPattern(sourcesFormatter)).plusMonths(value).format(DateTimeFormat.getFormat(DateTimeFormat.DATE_FULL));
}
/**
* 获取指定时间的下一个月份
* 自定义年月日日期格式
*
* @author Pan
* @param time 指定时间
* @param sourcesFormatter 指定时间的 时间格式
* @param val 整数为下一个月 负数为上一个月
* @param formatter 自定义格式 只能是年月日 或年月 月日 日等 不能超过年月日范围
* @return String
*/
public static String getNextMonth(String time, String sourcesFormatter, int val, String formatter) {
return DateParser.getLocalDate(time, sourcesFormatter).plusMonths(val).format(DateTimeFormat.getFormat(formatter));
}
/**
* 判断当前时间毫秒数是否超过指定毫秒
*
* @author Pan
* @param offsetMin 指定分钟
* @param millis 传递毫秒数
* @return boolean
*/
public static boolean nowExpiredMillisInMinutes(long offsetMin, long millis) {
Instant givenTime = Instant.ofEpochMilli(millis);
Instant currentTime = Instant.now();
Duration duration = Duration.between(givenTime, currentTime);
Duration threeMinutes = Duration.ofMinutes(offsetMin);
return duration.compareTo(threeMinutes) > 0;
}
/**
* 在给定时间集合中找出缺失的时间
* 时间格式为yyyy-MM-dd(年月日格式即可)
*
* @author Pan
* @param list 集合
* @param format 自定义格式字符
* @return List
*/
public static List dateFindMissingByDays(List list, String format) {
DateTimeFormatter dateTimeFormatter = DateTimeFormat.getFormat(format);
// 如果传递空则返回当月到现在缺失的时间
if (CollUtils.isEmpty(list)) {
// 当前日期起的缺失时间
List nowMissingDays = CollUtils.newArrayList();
LocalDate now = LocalDate.now();
for (int i = 1; i <= now.getDayOfMonth(); i++) {
nowMissingDays.add(LocalDate.of(now.getYear(), now.getMonthValue(), i).format(dateTimeFormatter));
}
return nowMissingDays;
}
// 验证时间类型
LocalDate localDate = DateParser.getLocalDate(list.get(0), format);
Assert.isNotNull(localDate);
// 添加最后一天
LocalDate with = localDate.with(TemporalAdjusters.lastDayOfMonth());
// 添加当前时间
Map existTimeMap = MapUtils.newHashMap(map -> list.forEach(e -> map.put(e, e)));
// 缺失时间集合
List missingDays = CollUtils.newArrayList(with.getDayOfMonth() - existTimeMap.size());
for (int i = 1; i <= with.getDayOfMonth(); i++) {
String time = LocalDate.of(with.getYear(), with.getMonthValue(), i).format(dateTimeFormatter);
if (existTimeMap.get(time) == null) {
missingDays.add(time);
}
}
return missingDays;
}
// 添加自动补充缺失时间范围(支持 秒,分,小时,天,月,年)
// public static List findMissingMonth(List list, String format) {
// LocalDateTime now = LocalDateTime.now();
// return null;
// }
// 添加自动补充缺失时间范围(支持 秒,分,小时,天,月,年)
// public static List findMissingYears(List list, String format) {
// LocalDateTime now = LocalDateTime.now();
// return null;
// }
/**
* 判断当前时间是否为闰年、平年
* true为闰年
*
* @author Pan
* @return boolean
*/
public static boolean hasLeapYear() {
return LocalDate.now().isLeapYear();
}
/**
* 判断指定年是否为闰年、平年
* true为闰年
*
* @author Pan
* @param year 指定年
* @return boolean
*/
public static boolean hasLeapYear(int year) {
Assert.isFalse(year < 0, "输入年小于0!");
if (year < 5000) {
return ((year & 3) == 0) && ((year % 100) != 0 || (year % 400) == 0);
}
// 对数值很大的年份判断验证
return (year % 3200 == 0) && (year % 172800 == 0);
}
/**
* 判断是否是工作日
* 1-5 为工作日 true
* 6-7 为假期 false
*
* @author Pan
* @return boolean
*/
public static boolean hasWorkDay() {
int dayOfWeek = getCurrentDayOfWeek();
return !(dayOfWeek == SATURDAY || dayOfWeek == SUNDAY);
}
/**
* 将时间替换为标准时间
* 例如:20220101将会替换成2022-01-01
* 格式限制:年月日时分秒,年月日
*
* @author Pan
* @param time 时间
* @return String
*/
public static String replaceLocalDate(String time) {
Assert.isNotEmpty(time);
// 获取时间标识符
int charTag = time.charAt(4);
// 查找下标是否有 时间标识符
if (charTag >= MIN_NUMBER && charTag <= MAX_NUMBER) {
StringBuilder builder = new StringBuilder(time.length() + 6)
.append(time)
.insert(4, NORM_TAG)
.insert(7, NORM_TAG);
time = builder.toString();
}
// 验证是否其他标识符
if (time.indexOf(NORM_TAG) == -1) {
time = StringUtils.replaceChars(time, (char) charTag, NORM_TAG);
}
return time;
}
}