mirror of
https://codeup.aliyun.com/67c68d4e484ca2f0a13ac3c1/ydc/jsowell-charger-web.git
synced 2026-04-20 02:55:04 +08:00
1185 lines
39 KiB
Java
1185 lines
39 KiB
Java
package com.jsowell.common.util;
|
||
|
||
import com.google.common.collect.Lists;
|
||
import lombok.AllArgsConstructor;
|
||
import lombok.Data;
|
||
import lombok.NoArgsConstructor;
|
||
import org.apache.commons.collections4.CollectionUtils;
|
||
import org.apache.commons.lang3.time.DateFormatUtils;
|
||
import org.slf4j.Logger;
|
||
import org.slf4j.LoggerFactory;
|
||
|
||
import java.lang.management.ManagementFactory;
|
||
import java.text.DateFormat;
|
||
import java.text.ParseException;
|
||
import java.text.SimpleDateFormat;
|
||
import java.time.*;
|
||
import java.time.format.DateTimeFormatter;
|
||
import java.time.temporal.ChronoUnit;
|
||
import java.util.*;
|
||
|
||
/**
|
||
* 时间工具类
|
||
*
|
||
* @author jsowell
|
||
*/
|
||
public class DateUtils extends org.apache.commons.lang3.time.DateUtils {
|
||
static Logger log = LoggerFactory.getLogger(DateUtils.class);
|
||
|
||
public static String YYYY = "yyyy";
|
||
|
||
public static String YYYY_MM = "yyyy-MM";
|
||
|
||
public static String YYYY_MM_DD = "yyyy-MM-dd";
|
||
|
||
public static String YYYYMMDD = "yyyyMMdd";
|
||
|
||
public static String YYMMDD = "yyMMdd";
|
||
|
||
public static String YYYYMMDDHHMMSS = "yyyyMMddHHmmss";
|
||
|
||
public static String YYYYMMDDHHMM = "yyyyMMddHHmm";
|
||
|
||
public static String YYMMDDHHMMSS = "yyMMddHHmmss";
|
||
|
||
public static String YYYY_MM_DD_HH_MM_SS = "yyyy-MM-dd HH:mm:ss";
|
||
|
||
public static String HH_MM = "HH:mm";
|
||
|
||
public static String RFC3339 = "yyyy-MM-dd'T'HH:mm:ssXXX";
|
||
|
||
private static String[] parsePatterns = {
|
||
"yyyy-MM-dd", "yyyy-MM-dd HH:mm:ss", "yyyy-MM-dd HH:mm", "yyyy-MM",
|
||
"yyyy/MM/dd", "yyyy/MM/dd HH:mm:ss", "yyyy/MM/dd HH:mm", "yyyy/MM",
|
||
"yyyy.MM.dd", "yyyy.MM.dd HH:mm:ss", "yyyy.MM.dd HH:mm", "yyyy.MM"};
|
||
|
||
/**
|
||
* 获取当前Date型日期
|
||
*
|
||
* @return Date() 当前日期
|
||
*/
|
||
public static Date getNowDate() {
|
||
return new Date();
|
||
}
|
||
|
||
/**
|
||
* 获取当前日期, 默认格式为yyyy-MM-dd
|
||
*
|
||
* @return String
|
||
*/
|
||
public static String getDate() {
|
||
return dateTimeNow(YYYY_MM_DD);
|
||
}
|
||
|
||
/**
|
||
* 获取昨天日期LocalDate
|
||
* @return
|
||
*/
|
||
public static LocalDate getYesterday() {
|
||
return LocalDate.now().plusDays(-1);
|
||
}
|
||
|
||
/**
|
||
* 获取昨天日期String
|
||
* @return
|
||
*/
|
||
public static String getYesterdayStr() {
|
||
LocalDate yesterday = getYesterday();
|
||
return yesterday.toString();
|
||
}
|
||
|
||
/**
|
||
* 获取当前日期, 默认格式为yyyy-MM-dd HH:mm:ss
|
||
*
|
||
* @return String
|
||
*/
|
||
public static String getDateTime() {
|
||
return dateTimeNow(YYYY_MM_DD_HH_MM_SS);
|
||
}
|
||
|
||
/**
|
||
* 获取当前日期, 默认格式为yyyyMMddHHmmss
|
||
*
|
||
* @return String
|
||
*/
|
||
public static String dateTimeNow() {
|
||
return dateTimeNow(YYYYMMDDHHMMSS);
|
||
}
|
||
|
||
public static String dateTimeNow(final String format) {
|
||
return parseDateToStr(format, new Date());
|
||
}
|
||
|
||
public static String dateTime(final Date date) {
|
||
return parseDateToStr(YYYY_MM_DD, date);
|
||
}
|
||
|
||
public static String parseDateToStr(final String format, final Date date) {
|
||
return new SimpleDateFormat(format).format(date);
|
||
}
|
||
|
||
|
||
public static String timeStampToRfc3339(long timeStamp) {
|
||
Date date = new Date(timeStamp);
|
||
SimpleDateFormat simpleDateFormat = new SimpleDateFormat(RFC3339);
|
||
String formatDate = simpleDateFormat.format(date);
|
||
return formatDate;
|
||
}
|
||
|
||
public static LocalDateTime toLocalDateTime(String str, String format) {
|
||
if (StringUtils.isBlank(str)) {
|
||
return null;
|
||
}
|
||
if (StringUtils.isBlank(format)) {
|
||
format = YYYY_MM_DD_HH_MM_SS;
|
||
}
|
||
DateTimeFormatter df = DateTimeFormatter.ofPattern(format);
|
||
return LocalDateTime.parse(str, df);
|
||
}
|
||
|
||
public static Date dateTime(final String format, final String ts) {
|
||
try {
|
||
return new SimpleDateFormat(format).parse(ts);
|
||
} catch (ParseException e) {
|
||
throw new RuntimeException(e);
|
||
}
|
||
}
|
||
|
||
/**
|
||
* 日期路径 即年/月/日 如2018/08/08
|
||
*/
|
||
public static String datePath() {
|
||
Date now = new Date();
|
||
return DateFormatUtils.format(now, "yyyy/MM/dd");
|
||
}
|
||
|
||
/**
|
||
* 日期路径 即年/月/日 如20180808
|
||
*/
|
||
public static String dateTime() {
|
||
Date now = new Date();
|
||
return DateFormatUtils.format(now, "yyyyMMdd");
|
||
}
|
||
|
||
/**
|
||
* 日期型字符串转化为日期 格式
|
||
*/
|
||
public static Date parseDate(Object str) {
|
||
if (str == null) {
|
||
return null;
|
||
}
|
||
try {
|
||
return parseDate(str.toString(), parsePatterns);
|
||
} catch (ParseException e) {
|
||
return null;
|
||
}
|
||
}
|
||
|
||
/**
|
||
* 获取服务器启动时间
|
||
*/
|
||
public static Date getServerStartDate() {
|
||
long time = ManagementFactory.getRuntimeMXBean().getStartTime();
|
||
return new Date(time);
|
||
}
|
||
|
||
/**
|
||
* 计算相差天数(不会显示负值)
|
||
*/
|
||
public static int differentDaysByMillisecond(Date beginDate, Date endDate) {
|
||
return Math.abs((int) ((endDate.getTime() - beginDate.getTime()) / (1000 * 3600 * 24)));
|
||
}
|
||
|
||
/**
|
||
* 计算相差天数 (会显示负值)
|
||
*
|
||
* @param endDate
|
||
* @param nowDate
|
||
* @return
|
||
*/
|
||
public static String getPoorDays(Date endDate, Date nowDate) {
|
||
long nd = 1000 * 24 * 60 * 60;
|
||
long diff = endDate.getTime() - nowDate.getTime();
|
||
long day = diff / nd;
|
||
StringBuilder sb = new StringBuilder();
|
||
if (day != 0) {
|
||
sb.append(day);
|
||
}
|
||
return sb.toString();
|
||
}
|
||
|
||
/**
|
||
* 计算两个时间差
|
||
*/
|
||
public static String getDatePoor(Date endDate, Date nowDate) {
|
||
long nd = 1000 * 24 * 60 * 60;
|
||
long nh = 1000 * 60 * 60;
|
||
long nm = 1000 * 60;
|
||
long ns = 1000;
|
||
// 获得两个时间的毫秒时间差异
|
||
long diff = endDate.getTime() - nowDate.getTime();
|
||
// 计算差多少天
|
||
long day = diff / nd;
|
||
// 计算差多少小时
|
||
long hour = diff % nd / nh;
|
||
// 计算差多少分钟
|
||
long min = diff % nd % nh / nm;
|
||
// 计算差多少秒//输出结果
|
||
long sec = diff % nd % nh % nm / ns;
|
||
|
||
StringBuilder sb = new StringBuilder();
|
||
if (day != 0) {
|
||
sb.append(day).append("天");
|
||
}
|
||
if (hour != 0) {
|
||
sb.append(hour).append("小时");
|
||
}
|
||
if (min != 0) {
|
||
sb.append(min).append("分");
|
||
}
|
||
if (sec != 0) {
|
||
sb.append(sec).append("秒");
|
||
}
|
||
return sb.toString();
|
||
}
|
||
|
||
/**
|
||
* 计算从给定日期字符串到当前时间一共过去了多少分钟。
|
||
*
|
||
* @param dateString 给定的日期字符串,格式为 "yyyy-MM-dd HH:mm:ss"
|
||
* @return 过去的分钟数
|
||
*/
|
||
public static long minutesSince(String dateString) {
|
||
// 定义日期时间格式
|
||
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
|
||
|
||
// 解析给定的日期字符串
|
||
LocalDateTime givenDateTime = LocalDateTime.parse(dateString, formatter);
|
||
|
||
// 获取当前时间
|
||
LocalDateTime now = LocalDateTime.now();
|
||
|
||
// 计算两者之间的时间差
|
||
Duration duration = Duration.between(givenDateTime, now);
|
||
|
||
// 将时间差转换为分钟
|
||
long minutes = duration.toMinutes();
|
||
|
||
return minutes;
|
||
}
|
||
|
||
/**
|
||
* LocalDateTime转Date
|
||
*
|
||
* @param localDateTime
|
||
* @return
|
||
*/
|
||
public static Date localDateTime2Date(LocalDateTime localDateTime) {
|
||
if (localDateTime == null) {
|
||
return null;
|
||
}
|
||
ZoneId zone = ZoneId.systemDefault();
|
||
Instant instant = localDateTime.atZone(zone).toInstant();
|
||
return Date.from(instant);
|
||
}
|
||
|
||
public static Date localDate2Date(LocalDate localDate) {
|
||
if (localDate == null) {
|
||
return null;
|
||
}
|
||
LocalDateTime localDateTime = LocalDateTime.of(localDate, LocalTime.of(0, 0, 0));
|
||
return localDateTime2Date(localDateTime);
|
||
}
|
||
|
||
/**
|
||
* 字符串转localDate
|
||
* @param dateStr 格式"yyyy-MM-dd"
|
||
* @return
|
||
*/
|
||
public static LocalDate dateStr2LocalDate(String dateStr) {
|
||
DateTimeFormatter fmt = DateTimeFormatter.ofPattern("yyyy-MM-dd");
|
||
return LocalDate.parse(dateStr, fmt);
|
||
}
|
||
|
||
/**
|
||
* localDate转dateStr 直接 .toString()
|
||
* @param localDate
|
||
* @return 格式"yyyy-MM-dd"
|
||
*/
|
||
// public static String localDate2DateStr(LocalDate localDate) {
|
||
// DateTimeFormatter df = DateTimeFormatter.ofPattern("yyyy-MM-dd");
|
||
// return localDate.format(df);
|
||
// }
|
||
|
||
/**
|
||
* Date转LocalDateTime
|
||
*/
|
||
public static LocalDateTime date2LocalDateTime(Date date) {
|
||
if (date == null) {
|
||
return null;
|
||
}
|
||
return date.toInstant().atZone(ZoneId.systemDefault()).toLocalDateTime();
|
||
}
|
||
|
||
/**
|
||
* 获取云快充协议所需时间段
|
||
* 0: 00~0: 30 时段费率号
|
||
* 0: 30~1: 00 时段费率号
|
||
* ……
|
||
* 23: 00~23: 30 时段费率号
|
||
* 23: 30~0: 00 时段费率号
|
||
*/
|
||
public static List<String> getPeriodOfTime() {
|
||
int intervalMinutes = 30;
|
||
// 结果集
|
||
List<String> resultList = Lists.newArrayList();
|
||
LocalTime startTime = LocalTime.of(0, 0);
|
||
|
||
LocalTime tempStartDateTime = startTime;
|
||
LocalTime tempEndDateTime = null;
|
||
while (true) {
|
||
// 获取加intervalMinutes分钟后的时间
|
||
tempEndDateTime = tempStartDateTime.plusMinutes(intervalMinutes);
|
||
resultList.add(tempStartDateTime.format(DateTimeFormatter.ofPattern("HH:mm:ss")) +
|
||
"-" + tempEndDateTime.format(DateTimeFormatter.ofPattern("HH:mm:ss")));
|
||
// 下次的开始时间,为上次的结束时间
|
||
tempStartDateTime = tempEndDateTime;
|
||
// 当tempStartDateTime等于startTime时,停止
|
||
if (tempStartDateTime.compareTo(startTime) == 0) {
|
||
break;
|
||
}
|
||
}
|
||
// 特殊处理
|
||
resultList = resultList.subList(0, resultList.size() - 1);
|
||
// 每天的最后半小时
|
||
resultList.add("23:30:00-23:59:59");
|
||
return resultList;
|
||
}
|
||
|
||
/**
|
||
* 时分秒转LocalTime
|
||
* 可以是 10:10:23 或者 10:10
|
||
*
|
||
* @param time
|
||
* @return
|
||
*/
|
||
public static LocalTime getLocalTime(String time) {
|
||
if (StringUtils.equals("24:00", time)) {
|
||
// System.out.println("time为24:00, 转换为23:59");
|
||
time = "23:59";
|
||
}
|
||
List<String> list = Lists.newArrayList(time.split(":"));
|
||
if (CollectionUtils.isNotEmpty(list)) {
|
||
if (list.size() == 2) {
|
||
return LocalTime.of(Integer.parseInt(list.get(0)), Integer.parseInt(list.get(1)));
|
||
} else if (list.size() == 3) {
|
||
return LocalTime.of(Integer.parseInt(list.get(0)), Integer.parseInt(list.get(1)), Integer.parseInt(list.get(2)));
|
||
}
|
||
}
|
||
return null;
|
||
}
|
||
|
||
public enum IntervalType {
|
||
DAY,
|
||
HOUR,
|
||
MINUTE,
|
||
SECOND,
|
||
;
|
||
}
|
||
|
||
/**
|
||
* 时间切割
|
||
*
|
||
* @param startTime 被切割的开始时间
|
||
* @param endTime 被切割的结束时间
|
||
* @param intervalType
|
||
* @param interval >0
|
||
* @return
|
||
*/
|
||
public static List<DateSplit> splitDate(Date startTime, Date endTime, IntervalType intervalType, int interval) {
|
||
if (interval < 0) {
|
||
return null;
|
||
}
|
||
if (endTime.getTime() <= startTime.getTime()) {
|
||
return null;
|
||
}
|
||
|
||
if (intervalType == IntervalType.DAY) {
|
||
return splitByDay(startTime, endTime, interval);
|
||
}
|
||
if (intervalType == IntervalType.HOUR) {
|
||
return splitByHour(startTime, endTime, interval);
|
||
}
|
||
if (intervalType == IntervalType.MINUTE) {
|
||
return splitByMinute(startTime, endTime, interval);
|
||
}
|
||
if (intervalType == IntervalType.SECOND) {
|
||
return splitBySecond(startTime, endTime, interval);
|
||
}
|
||
return null;
|
||
}
|
||
|
||
/**
|
||
* 按照小时切割时间区间
|
||
*/
|
||
public static List<DateSplit> splitByHour(Date startTime, Date endTime, int intervalHours) {
|
||
if (endTime.getTime() <= startTime.getTime()) {
|
||
return null;
|
||
}
|
||
|
||
List<DateSplit> dateSplits = new ArrayList<>(256);
|
||
|
||
DateSplit param = new DateSplit();
|
||
param.setStartDateTime(startTime);
|
||
param.setEndDateTime(endTime);
|
||
param.setEndDateTime(addHour(startTime, intervalHours));
|
||
while (true) {
|
||
param.setStartDateTime(startTime);
|
||
Date tempEndTime = addHour(startTime, intervalHours);
|
||
if (tempEndTime.getTime() >= endTime.getTime()) {
|
||
tempEndTime = endTime;
|
||
}
|
||
param.setEndDateTime(tempEndTime);
|
||
|
||
dateSplits.add(new DateSplit(param.getStartDateTime(), param.getEndDateTime()));
|
||
|
||
startTime = addHour(startTime, intervalHours);
|
||
if (startTime.getTime() >= endTime.getTime()) {
|
||
break;
|
||
}
|
||
if (param.getEndDateTime().getTime() >= endTime.getTime()) {
|
||
break;
|
||
}
|
||
}
|
||
return dateSplits;
|
||
}
|
||
|
||
/**
|
||
* 按照秒切割时间区间
|
||
* getRealTimeDetectionData
|
||
*/
|
||
public static List<DateSplit> splitBySecond(Date startTime, Date endTime, int intervalSeconds) {
|
||
if (endTime.getTime() <= startTime.getTime()) {
|
||
return null;
|
||
}
|
||
List<DateSplit> dateSplits = new ArrayList<>(256);
|
||
|
||
DateSplit param = new DateSplit();
|
||
param.setStartDateTime(startTime);
|
||
param.setEndDateTime(endTime);
|
||
param.setEndDateTime(addSecond(startTime, intervalSeconds));
|
||
while (true) {
|
||
param.setStartDateTime(startTime);
|
||
Date tempEndTime = addSecond(startTime, intervalSeconds);
|
||
if (tempEndTime.getTime() >= endTime.getTime()) {
|
||
tempEndTime = endTime;
|
||
}
|
||
param.setEndDateTime(tempEndTime);
|
||
|
||
dateSplits.add(new DateSplit(param.getStartDateTime(), param.getEndDateTime()));
|
||
|
||
startTime = addSecond(startTime, intervalSeconds);
|
||
if (startTime.getTime() >= endTime.getTime()) {
|
||
break;
|
||
}
|
||
if (param.getEndDateTime().getTime() >= endTime.getTime()) {
|
||
break;
|
||
}
|
||
}
|
||
return dateSplits;
|
||
}
|
||
|
||
/**
|
||
* 按照天切割时间区间
|
||
*/
|
||
public static List<DateSplit> splitByDay(Date startTime, Date endTime, int intervalDays) {
|
||
if (endTime.getTime() <= startTime.getTime()) {
|
||
return null;
|
||
}
|
||
List<DateSplit> dateSplits = new ArrayList<>(256);
|
||
|
||
DateSplit param = new DateSplit();
|
||
param.setStartDateTime(startTime);
|
||
param.setEndDateTime(endTime);
|
||
param.setEndDateTime(addDay(startTime, intervalDays));
|
||
while (true) {
|
||
param.setStartDateTime(startTime);
|
||
Date tempEndTime = addDay(startTime, intervalDays);
|
||
if (tempEndTime.getTime() >= endTime.getTime()) {
|
||
tempEndTime = endTime;
|
||
}
|
||
param.setEndDateTime(tempEndTime);
|
||
|
||
dateSplits.add(new DateSplit(param.getStartDateTime(), param.getEndDateTime()));
|
||
|
||
startTime = addDay(startTime, intervalDays);
|
||
if (startTime.getTime() >= endTime.getTime()) {
|
||
break;
|
||
}
|
||
if (param.getEndDateTime().getTime() >= endTime.getTime()) {
|
||
break;
|
||
}
|
||
}
|
||
return dateSplits;
|
||
}
|
||
|
||
|
||
/**
|
||
* 按照分钟切割时间区间
|
||
*
|
||
* @param startTime
|
||
* @param endTime
|
||
* @param intervalMinutes
|
||
* @return
|
||
*/
|
||
public static List<DateSplit> splitByMinute(Date startTime, Date endTime, int intervalMinutes) {
|
||
if (endTime.getTime() <= startTime.getTime()) {
|
||
return null;
|
||
}
|
||
List<DateSplit> dateSplits = new ArrayList<>(256);
|
||
|
||
DateSplit param = new DateSplit();
|
||
param.setStartDateTime(startTime);
|
||
param.setEndDateTime(endTime);
|
||
param.setEndDateTime(addMinute(startTime, intervalMinutes));
|
||
while (true) {
|
||
param.setStartDateTime(startTime);
|
||
Date tempEndTime = addMinute(startTime, intervalMinutes);
|
||
if (tempEndTime.getTime() >= endTime.getTime()) {
|
||
tempEndTime = endTime;
|
||
}
|
||
param.setEndDateTime(tempEndTime);
|
||
|
||
dateSplits.add(new DateSplit(param.getStartDateTime(), param.getEndDateTime()));
|
||
|
||
startTime = addMinute(startTime, intervalMinutes);
|
||
if (startTime.getTime() >= endTime.getTime()) {
|
||
break;
|
||
}
|
||
if (param.getEndDateTime().getTime() >= endTime.getTime()) {
|
||
break;
|
||
}
|
||
}
|
||
return dateSplits;
|
||
}
|
||
|
||
private static Date addDay(Date date, int days) {
|
||
return add(date, Calendar.DAY_OF_MONTH, days);
|
||
}
|
||
|
||
private static Date addHour(Date date, int hours) {
|
||
return add(date, Calendar.HOUR_OF_DAY, hours);
|
||
}
|
||
|
||
public static Date addMinute(Date date, int minute) {
|
||
return add(date, Calendar.MINUTE, minute);
|
||
}
|
||
|
||
private static Date addSecond(Date date, int second) {
|
||
return add(date, Calendar.SECOND, second);
|
||
}
|
||
|
||
private static Date add(final Date date, final int calendarField, final int amount) {
|
||
final Calendar c = Calendar.getInstance();
|
||
c.setTime(date);
|
||
c.add(calendarField, amount);
|
||
return c.getTime();
|
||
}
|
||
|
||
public static String formatDateTime(Date date) {
|
||
if (date == null) {
|
||
return "";
|
||
}
|
||
SimpleDateFormat simpleDateFormat = new SimpleDateFormat(YYYY_MM_DD_HH_MM_SS);
|
||
return simpleDateFormat.format(date);
|
||
}
|
||
|
||
public static String formatDateTime(LocalDateTime localDateTime) {
|
||
if (localDateTime == null) {
|
||
return "";
|
||
}
|
||
Date date = Date.from(localDateTime.atZone(ZoneId.systemDefault()).toInstant());
|
||
return formatDateTime(date);
|
||
}
|
||
|
||
public static String formatDateTime(LocalTime localTime) {
|
||
if (localTime == null) {
|
||
return "";
|
||
}
|
||
return localTime.toString();
|
||
}
|
||
|
||
@Data
|
||
@AllArgsConstructor
|
||
@NoArgsConstructor
|
||
public static class DateSplit {
|
||
private Date startDateTime;
|
||
private Date endDateTime;
|
||
|
||
public String getStartDateTimeStr() {
|
||
return formatDateTime(startDateTime);
|
||
}
|
||
|
||
public String getEndDateTimeStr() {
|
||
return formatDateTime(endDateTime);
|
||
}
|
||
}
|
||
|
||
/**
|
||
* CP56Time2a 转 日期字符串
|
||
* 0x3b交易记录 会使用这个方法,解析开始时间 结束时间 交易时间
|
||
* @param bytes
|
||
* @return
|
||
*/
|
||
// public static String CP56Time2aToDateStr(byte[] bytes) {
|
||
// Date date = CP56Time2aToDate(bytes);
|
||
// if (date == null) {
|
||
// return null;
|
||
// }
|
||
// return DateUtils.formatDateTime(date);
|
||
// }
|
||
// public static String toDateString(byte[] bytes) {
|
||
// return Cp56Time2aUtil.toDateString(bytes);
|
||
// }
|
||
|
||
/**
|
||
* cp56time2a 格式转date格式
|
||
*/
|
||
// public static Date CP56Time2aToDate(byte[] bytes) {
|
||
// if (bytes == null || bytes.length != 7) {
|
||
// return null;
|
||
// }
|
||
// int ms = BytesUtil.bytesToIntLittle(BytesUtil.copyBytes(bytes, 0, 2));
|
||
// int min = BytesUtil.bytesToIntLittle(BytesUtil.copyBytes(bytes, 2, 1));
|
||
// int hour = BytesUtil.bytesToIntLittle(BytesUtil.copyBytes(bytes, 3, 1));
|
||
// int day = BytesUtil.bytesToIntLittle(BytesUtil.copyBytes(bytes, 4, 1));
|
||
// int month = BytesUtil.bytesToIntLittle(BytesUtil.copyBytes(bytes, 5, 1));
|
||
// int year = BytesUtil.bytesToIntLittle(BytesUtil.copyBytes(bytes, 6, 1));
|
||
// if (month == 0 || day == 0 || year == 0) {
|
||
// return null;
|
||
// }
|
||
// LocalDateTime localDateTime = LocalDateTime.of(year + 2000, month, day, hour, min, ms / 1000);
|
||
// Date date = DateUtils.localDateTime2Date(localDateTime);
|
||
// return date;
|
||
// }
|
||
|
||
// public static Date CP56Time2aToDate(byte[] bytes) {
|
||
// return Cp56Time2aUtil.toDate(bytes);
|
||
// }
|
||
|
||
/**
|
||
* 时间转16进制字符串
|
||
* Date转成CP56Time2a
|
||
* 发送对时请求,会用到这个方法
|
||
*/
|
||
// public static String encodeCP56Time2a(Date date) {
|
||
// // Calendar calendar = Calendar.getInstance();
|
||
// // calendar.setTime(date);
|
||
// // StringBuilder builder = new StringBuilder();
|
||
// // String milliSecond = String.format("%04X", (calendar.get(Calendar.SECOND) * 1000) + calendar.get(Calendar.MILLISECOND));
|
||
// // builder.append(milliSecond.substring(2, 4));
|
||
// // builder.append(milliSecond.substring(0, 2));
|
||
// // builder.append(String.format("%02X", calendar.get(Calendar.MINUTE) & 0x3F));
|
||
// // builder.append(String.format("%02X", calendar.get(Calendar.HOUR_OF_DAY) & 0x1F));
|
||
// // int week = calendar.get(Calendar.DAY_OF_WEEK);
|
||
// // if (week == Calendar.SUNDAY)
|
||
// // week = 7;
|
||
// // else week--;
|
||
// // builder.append(String.format("%02X", (week << 5) + (calendar.get(Calendar.DAY_OF_MONTH) & 0x1F)));
|
||
// // builder.append(String.format("%02X", calendar.get(Calendar.MONTH) + 1));
|
||
// // builder.append(String.format("%02X", calendar.get(Calendar.YEAR) - 2000));
|
||
// // return builder.toString();
|
||
//
|
||
// byte[] result = new byte[7];
|
||
// final Calendar aTime = Calendar.getInstance();
|
||
// aTime.setTime(date);
|
||
// final int milliseconds = aTime.get(Calendar.MILLISECOND);
|
||
// result[0] = (byte) (milliseconds % 256);
|
||
// result[1] = (byte) (milliseconds / 256);
|
||
// result[2] = (byte) aTime.get(Calendar.MINUTE);
|
||
// result[3] = (byte) aTime.get(Calendar.HOUR_OF_DAY);
|
||
// result[4] = (byte) aTime.get(Calendar.DAY_OF_MONTH);
|
||
// result[5] = (byte) (aTime.get(Calendar.MONTH) + 1);
|
||
// result[6] = (byte) (aTime.get(Calendar.YEAR) % 100);
|
||
// System.out.println("Year->" + aTime.get(Calendar.YEAR));
|
||
// return BytesUtil.binary(result, 16);
|
||
// }
|
||
// public static String date2HexStr(Date date) {
|
||
// return Cp56Time2aUtil.date2HexStr(date);
|
||
// }
|
||
/**
|
||
* 获取两个时间的间隔时间
|
||
*
|
||
* @return 间隔时间 单位:分钟
|
||
*/
|
||
public static long intervalTime(String begin, String end) {
|
||
return intervalTime(parseDate(begin), parseDate(end));
|
||
}
|
||
|
||
/**
|
||
* 获取两个时间的间隔时间
|
||
*
|
||
* @return 间隔时间 单位:分钟
|
||
*/
|
||
public static long intervalTime(Date begin, Date end) {
|
||
return intervalTime(date2LocalDateTime(begin), date2LocalDateTime(end));
|
||
}
|
||
|
||
/**
|
||
* 获取两个时间的间隔时间
|
||
*
|
||
* @return 间隔时间 单位:分钟
|
||
*/
|
||
public static long intervalTime(LocalDateTime begin, LocalDateTime end) {
|
||
return ChronoUnit.MINUTES.between(begin, end);
|
||
}
|
||
|
||
/**
|
||
* 判断2个时间段是否有重叠(交集)
|
||
*
|
||
* @param startDate1 时间段1开始时间戳
|
||
* @param endDate1 时间段1结束时间戳
|
||
* @param startDate2 时间段2开始时间戳
|
||
* @param endDate2 时间段2结束时间戳
|
||
* @param isStrict 是否严格重叠,true 严格,没有任何相交或相等;false 不严格,可以首尾相等,比如2021/5/29-2021/5/31和2021/5/31-2021/6/1,不重叠。
|
||
* @return 返回是否重叠
|
||
*/
|
||
public static boolean isOverlap(long startDate1, long endDate1, long startDate2, long endDate2, boolean isStrict) {
|
||
if (isStrict) {
|
||
if (!(endDate1 < startDate2 || startDate1 > endDate2)) {
|
||
return true;
|
||
}
|
||
} else {
|
||
if (!(endDate1 <= startDate2 || startDate1 >= endDate2)) {
|
||
return true;
|
||
}
|
||
}
|
||
return false;
|
||
}
|
||
|
||
/**
|
||
* @param time1 17:02:00 - 17:02:00
|
||
* @param time2 00:00-06:30
|
||
* @return
|
||
*/
|
||
public static boolean checkTime(String time1, String time2) {
|
||
String[] split = time1.split("-");
|
||
LocalTime startTime1 = DateUtils.getLocalTime(split[0]);
|
||
LocalTime endTime1 = DateUtils.getLocalTime(split[1]);
|
||
String[] split2 = time2.split("-");
|
||
LocalTime startTime2 = DateUtils.getLocalTime(split2[0]);
|
||
LocalTime endTime2 = DateUtils.getLocalTime(split2[1]);
|
||
return DateUtils.isOverlap(startTime1, endTime1, startTime2, endTime2, false);
|
||
}
|
||
|
||
/**
|
||
* 判断时间段是否重叠
|
||
*
|
||
* @param startDate1
|
||
* @param endDate1
|
||
* @param startDate2
|
||
* @param endDate2
|
||
* @param isStrict
|
||
* @return
|
||
*/
|
||
public static boolean isOverlap(LocalTime startDate1, LocalTime endDate1, LocalTime startDate2, LocalTime endDate2, boolean isStrict) {
|
||
if (startDate1 == null || endDate1 == null || startDate2 == null || endDate2 == null) {
|
||
log.warn("判断时间段是否重叠缺少参数,返回false");
|
||
return false;
|
||
}
|
||
boolean result = false;
|
||
if (isStrict) {
|
||
if (!(endDate1.isBefore(startDate2) || startDate1.isAfter(endDate2))) {
|
||
result = true;
|
||
}
|
||
} else {
|
||
if (!((endDate1.isBefore(startDate2) || endDate1.equals(startDate2)) || (startDate1.isAfter(endDate2) || startDate1.equals(endDate2)))) {
|
||
result = true;
|
||
}
|
||
}
|
||
// log.info("时间段1={}, 时间段2={}, 结果:{}", startDate1 + "-" + endDate1, startDate2 + "-" + endDate2, result);
|
||
return result;
|
||
}
|
||
|
||
/**
|
||
* 判断2个时间段是否有重叠(交集)
|
||
*
|
||
* @param startDate1 时间段1开始时间
|
||
* @param endDate1 时间段1结束时间
|
||
* @param startDate2 时间段2开始时间
|
||
* @param endDate2 时间段2结束时间
|
||
* @param isStrict 是否严格重叠,true 严格,没有任何相交或相等;false 不严格,可以首尾相等,比如2021-05-29到2021-05-31和2021-05-31到2021-06-01,不重叠。
|
||
* @return 返回是否重叠
|
||
*/
|
||
public static boolean isOverlap(Date startDate1, Date endDate1, Date startDate2, Date endDate2, boolean isStrict) {
|
||
Objects.requireNonNull(startDate1, "startDate1");
|
||
Objects.requireNonNull(endDate1, "endDate1");
|
||
Objects.requireNonNull(startDate2, "startDate2");
|
||
Objects.requireNonNull(endDate2, "endDate2");
|
||
return isOverlap(startDate1.getTime(), endDate1.getTime(), startDate2.getTime(), endDate2.getTime(), isStrict);
|
||
}
|
||
|
||
/**
|
||
* 秒 转 天时分秒
|
||
* 时分秒HoursMinutesSeconds
|
||
*
|
||
* @param mss 秒数
|
||
* @return xx天xx小时xx分钟xx秒
|
||
*/
|
||
public static String formatHoursMinutesSeconds(long mss) {
|
||
String DateTimes = null;
|
||
long days = mss / (60 * 60 * 24);
|
||
long hours = (mss % (60 * 60 * 24)) / (60 * 60);
|
||
long minutes = (mss % (60 * 60)) / 60;
|
||
long seconds = mss % 60;
|
||
if (days > 0) {
|
||
DateTimes = days + "天" + hours + "小时" + minutes + "分钟"
|
||
+ seconds + "秒";
|
||
} else if (hours > 0) {
|
||
DateTimes = hours + "小时" + minutes + "分钟"
|
||
+ seconds + "秒";
|
||
} else if (minutes > 0) {
|
||
DateTimes = minutes + "分钟"
|
||
+ seconds + "秒";
|
||
} else {
|
||
DateTimes = seconds + "秒";
|
||
}
|
||
|
||
return DateTimes;
|
||
}
|
||
|
||
/**
|
||
* 分钟转 x时x分
|
||
* @param minutes
|
||
* @return
|
||
*/
|
||
public static String convertMinutesToTime(int minutes) {
|
||
if (minutes < 0) {
|
||
return null;
|
||
}
|
||
int hours = minutes / 60;
|
||
int remainingMinutes = minutes % 60;
|
||
if (hours < 1) {
|
||
return String.format("%d分钟", remainingMinutes);
|
||
}else {
|
||
return String.format("%d小时%d分钟", hours, remainingMinutes);
|
||
}
|
||
}
|
||
|
||
public static void main(String[] args) {
|
||
System.out.println(isInDiscountPeriod("20:00", "08:00", "00:35:58")); // true
|
||
System.out.println(isInDiscountPeriod("00:00", "00:00", "19:59:59")); // true
|
||
System.out.println(isInDiscountPeriod("20:00", "20:00", "08:00:00")); // true
|
||
System.out.println(isInDiscountPeriod("20:00", "08:00", "08:00:00")); // false
|
||
}
|
||
|
||
/**
|
||
* 当前时间是否在时间指定范围内<br>
|
||
*
|
||
* @param time 被检查的时间
|
||
* @param beginTime 起始时间
|
||
* @param endTime 结束时间
|
||
* @return 是否在范围内
|
||
* @since 3.0.8
|
||
*/
|
||
public static boolean isIn(LocalTime time, LocalTime beginTime, LocalTime endTime) {
|
||
// 判断是否在范围内 包含开始结束时间
|
||
if (time.compareTo(beginTime) == 0 || time.compareTo(endTime) == 0) {
|
||
return true;
|
||
}
|
||
if (beginTime.isBefore(time) && endTime.isAfter(time)) {
|
||
return true;
|
||
}
|
||
return false;
|
||
}
|
||
|
||
/**
|
||
* 根据传入的日期,获取时间区间中所有的日期
|
||
*
|
||
* @param startDate 开始日期
|
||
* @param endDate 结束日期
|
||
* @return java.util.List<java.time.LocalDate>
|
||
* @since 2023-07-20
|
||
*/
|
||
public static List<LocalDate> getAllDatesInTheDateRange(LocalDate startDate, LocalDate endDate) {
|
||
List<LocalDate> localDateList = new ArrayList<>();
|
||
// 开始时间必须小于结束时间
|
||
if (startDate.isAfter(endDate)) {
|
||
return null;
|
||
}
|
||
while (startDate.isBefore(endDate)) {
|
||
localDateList.add(startDate);
|
||
startDate = startDate.plusDays(1);
|
||
}
|
||
localDateList.add(endDate);
|
||
return localDateList;
|
||
}
|
||
|
||
/**
|
||
* 根据传入的日期,获取时间区间中所有的日期
|
||
* @param startDate 开始日期
|
||
* @param endDate 结束日期
|
||
* @return java.util.List<String>
|
||
*/
|
||
public static List<String> getAllDatesInTheDateRange(String startDate, String endDate) {
|
||
// 判断传进来的日期格式
|
||
if (judgeLegalDate(startDate) || judgeLegalDate(endDate)) {
|
||
return new ArrayList<>();
|
||
}
|
||
List<LocalDate> localDateList = getAllDatesInTheDateRange(dateStr2LocalDate(startDate), dateStr2LocalDate(endDate));
|
||
if (CollectionUtils.isEmpty(localDateList)) {
|
||
return new ArrayList<>();
|
||
}
|
||
List<String> resultList = new ArrayList<>();
|
||
localDateList.forEach(localDate -> {
|
||
String dateStr = localDate.toString();
|
||
resultList.add(dateStr);
|
||
});
|
||
return resultList;
|
||
}
|
||
|
||
/**
|
||
* 判断时间格式 格式必须为“YYYY-MM-dd”
|
||
* 2004-2-30 是无效的
|
||
* 2003-2-29 是无效的
|
||
* @param sDate
|
||
* @return
|
||
*/
|
||
private static boolean judgeLegalDate(String sDate) {
|
||
int legalLen = 10;
|
||
if ((sDate == null) || (sDate.length() != legalLen)) {
|
||
return true;
|
||
}
|
||
DateFormat formatter = new SimpleDateFormat("yyyy-MM-dd");
|
||
try {
|
||
Date date = formatter.parse(sDate);
|
||
return !sDate.equals(formatter.format(date));
|
||
} catch (Exception e) {
|
||
return true;
|
||
}
|
||
}
|
||
|
||
|
||
/**
|
||
* 根据年月获取月初第一天日期
|
||
* @param year
|
||
* @param month
|
||
* @return
|
||
*/
|
||
public static String getFirstDay(int year,int month,String format) {
|
||
Calendar cale = Calendar.getInstance();
|
||
|
||
cale.set(Calendar.YEAR, year); //赋值年份
|
||
cale.set(Calendar.MONTH, month - 1);//赋值月份
|
||
int lastDay = cale.getActualMinimum(Calendar.DAY_OF_MONTH);//获取月最大天数
|
||
cale.set(Calendar.DAY_OF_MONTH, lastDay);//设置日历中月份的最大天数
|
||
SimpleDateFormat sdf = new SimpleDateFormat(format);//格式化日期yyyy-MM-dd
|
||
String lastDayOfMonth = sdf.format(cale.getTime());
|
||
return lastDayOfMonth;
|
||
}
|
||
|
||
|
||
/**
|
||
* 根据年月获取月末最后一天日期
|
||
* @param year
|
||
* @param month
|
||
* @return
|
||
*/
|
||
public static String getLastDay(int year,int month,String format) {
|
||
Calendar cale = Calendar.getInstance();
|
||
|
||
cale.set(Calendar.YEAR, year);//赋值年份
|
||
cale.set(Calendar.MONTH, month - 1);//赋值月份
|
||
int lastDay = cale.getActualMaximum(Calendar.DAY_OF_MONTH);//获取月最大天数
|
||
cale.set(Calendar.DAY_OF_MONTH, lastDay);//设置日历中月份的最大天数
|
||
SimpleDateFormat sdf = new SimpleDateFormat(format); //格式化日期yyyy-MM-dd
|
||
String lastDayOfMonth = sdf.format(cale.getTime());
|
||
return lastDayOfMonth;
|
||
}
|
||
|
||
/**
|
||
* 时间戳 转 LocalDateTime
|
||
* @param timestamp 时间戳(单位:毫秒)
|
||
* @return
|
||
*/
|
||
public static LocalDateTime timestampToDatetime(long timestamp){
|
||
Instant instant = Instant.ofEpochMilli(timestamp);
|
||
return LocalDateTime.ofInstant(instant, ZoneId.systemDefault());
|
||
}
|
||
|
||
/**
|
||
* LocalDateTime转时间戳
|
||
* @param localDateTime
|
||
* @return
|
||
*/
|
||
public static long datetimeToTimestamp(LocalDateTime localDateTime){
|
||
return localDateTime.toInstant(ZoneOffset.of("+8")).toEpochMilli();
|
||
}
|
||
|
||
/**
|
||
* date转时间戳
|
||
*/
|
||
public static long dateToTimestamp(Date date){
|
||
LocalDateTime localDateTime = LocalDateTime.ofInstant(date.toInstant(), ZoneId.systemDefault());
|
||
return datetimeToTimestamp(localDateTime);
|
||
}
|
||
|
||
/**
|
||
* date字符串转时间戳
|
||
* @param dateStr
|
||
* @return
|
||
*/
|
||
public static long dateStrToTimestamp(String dateStr) {
|
||
Date date = parseDate(dateStr);
|
||
return dateToTimestamp(date);
|
||
}
|
||
|
||
|
||
/**
|
||
* 将 YYYY-MM-DD HH:mm:ss 转换为 YYYY-MM-DD
|
||
* @param dateTimeString
|
||
* @return
|
||
*/
|
||
public static String convertDateTimeToDate(String dateTimeString) {
|
||
SimpleDateFormat inputFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
|
||
SimpleDateFormat outputFormat = new SimpleDateFormat("yyyy-MM-dd");
|
||
|
||
try {
|
||
Date date = inputFormat.parse(dateTimeString);
|
||
return outputFormat.format(date);
|
||
} catch (ParseException e) {
|
||
// 处理解析异常
|
||
e.printStackTrace();
|
||
return null; // 或者返回一个默认值
|
||
}
|
||
}
|
||
|
||
/**
|
||
* 返回多个Date参数中不为null并且时间最大的Date
|
||
*
|
||
* @param dates 多个Date类型的参数
|
||
* @return 参数列表中不为null且时间最大的Date对象
|
||
*/
|
||
public static Date getMaxDate(Date... dates) {
|
||
Date maxDate = null;
|
||
for (Date date : dates) {
|
||
if (date != null && (maxDate == null || date.after(maxDate))) {
|
||
maxDate = date;
|
||
}
|
||
}
|
||
return maxDate;
|
||
}
|
||
|
||
public static LocalDateTime convertToLocalDateTime(String time, boolean isNextDay) {
|
||
LocalTime localTime = LocalTime.parse(time, DateTimeFormatter.ofPattern("HH:mm:ss"));
|
||
LocalDateTime now = LocalDateTime.now();
|
||
LocalDateTime dateTime = now.with(localTime);
|
||
|
||
if (isNextDay) {
|
||
dateTime = dateTime.plusDays(1);
|
||
}
|
||
|
||
return dateTime;
|
||
}
|
||
|
||
/**
|
||
* 转换预约时间
|
||
* @param startTime
|
||
* @param endTime
|
||
* @return
|
||
*/
|
||
public static LocalDateTime[] convertStartAndEndTime(String startTime, String endTime) {
|
||
LocalTime startLocalTime = LocalTime.parse(startTime, DateTimeFormatter.ofPattern("HH:mm:ss"));
|
||
LocalTime endLocalTime = LocalTime.parse(endTime, DateTimeFormatter.ofPattern("HH:mm:ss"));
|
||
|
||
LocalDateTime now = LocalDateTime.now();
|
||
LocalDateTime startDateTime = now.with(startLocalTime);
|
||
LocalDateTime endDateTime = now.with(endLocalTime);
|
||
|
||
// 如果结束时间比开始时间小或相同,则结束时间为第二天
|
||
if (endLocalTime.isBefore(startLocalTime) || endLocalTime.equals(startLocalTime)) {
|
||
endDateTime = endDateTime.plusDays(1);
|
||
}
|
||
|
||
return new LocalDateTime[]{startDateTime, endDateTime};
|
||
}
|
||
|
||
/**
|
||
* 获取去年这个月第一天的日期
|
||
* @return 去年这个月第一天的日期,格式为 "yyyy-MM-dd"
|
||
*/
|
||
public static String getFirstDayOfLastYearMonth() {
|
||
// 获取当前日期
|
||
LocalDate currentDate = LocalDate.now();
|
||
|
||
// 获取去年这个月的年份
|
||
int lastYear = currentDate.getYear() - 1;
|
||
|
||
// 获取这个月的月份
|
||
int currentMonth = currentDate.getMonthValue();
|
||
|
||
// 获取去年这个月第一天的日期
|
||
LocalDate firstDayOfLastYearMonth = LocalDate.of(lastYear, currentMonth, 1);
|
||
|
||
// 格式化日期为 "yyyy-MM-dd"
|
||
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd");
|
||
return firstDayOfLastYearMonth.format(formatter);
|
||
}
|
||
|
||
/**
|
||
* 获取当前年月最后一天的日期
|
||
* @return 当前年月最后一天的日期,格式为 "yyyy-MM-dd"
|
||
*/
|
||
public static String getLastDayOfCurrentMonth() {
|
||
// 获取当前的年份和月份
|
||
YearMonth currentYearMonth = YearMonth.now();
|
||
|
||
// 获取该年月的最后一天
|
||
LocalDate lastDayOfMonth = currentYearMonth.atEndOfMonth();
|
||
|
||
// 格式化日期为 "yyyy-MM-dd"
|
||
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd");
|
||
return lastDayOfMonth.format(formatter);
|
||
}
|
||
|
||
/**
|
||
* 判断目标时间是否在优惠时间段内
|
||
* @param startStr 开始时间(HH:mm)
|
||
* @param endStr 结束时间(HH:mm)
|
||
* @param targetStr 目标时间(HH:mm:ss)
|
||
* @return 是否在优惠时段
|
||
*/
|
||
public static boolean isInDiscountPeriod(String startStr, String endStr, String targetStr) {
|
||
LocalTime start = LocalTime.parse(startStr);
|
||
LocalTime end = LocalTime.parse(endStr);
|
||
LocalTime target = LocalTime.parse(targetStr);
|
||
return isInDiscountPeriod(start, end, target);
|
||
}
|
||
|
||
/**
|
||
* 判断目标时间是否在优惠时间段内
|
||
* @param start 开始时间(HH:mm)
|
||
* @param end 结束时间(HH:mm)
|
||
* @param target 目标时间(HH:mm:ss)
|
||
* @return 是否在优惠时段
|
||
*/
|
||
public static boolean isInDiscountPeriod(LocalTime start, LocalTime end, LocalTime target) {
|
||
// 任意参数为空返回false
|
||
if (start == null || end == null || target == null) {
|
||
return false;
|
||
}
|
||
// 开始时间等于结束时间即判定为全天
|
||
if (start.equals(end)) {
|
||
return true;
|
||
}
|
||
if (start.isAfter(end)) {
|
||
// 跨天判断逻辑
|
||
return !target.isBefore(start) || target.isBefore(end);
|
||
} else {
|
||
// 普通时段判断逻辑
|
||
return !target.isBefore(start) && target.isBefore(end);
|
||
}
|
||
}
|
||
|
||
}
|