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 getPeriodOfTime() { int intervalMinutes = 30; // 结果集 List 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 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 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 splitByHour(Date startTime, Date endTime, int intervalHours) { if (endTime.getTime() <= startTime.getTime()) { return null; } List 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 splitBySecond(Date startTime, Date endTime, int intervalSeconds) { if (endTime.getTime() <= startTime.getTime()) { return null; } List 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 splitByDay(Date startTime, Date endTime, int intervalDays) { if (endTime.getTime() <= startTime.getTime()) { return null; } List 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 splitByMinute(Date startTime, Date endTime, int intervalMinutes) { if (endTime.getTime() <= startTime.getTime()) { return null; } List 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 } /** * 当前时间是否在时间指定范围内
* * @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 * @since 2023-07-20 */ public static List getAllDatesInTheDateRange(LocalDate startDate, LocalDate endDate) { List 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 */ public static List getAllDatesInTheDateRange(String startDate, String endDate) { // 判断传进来的日期格式 if (judgeLegalDate(startDate) || judgeLegalDate(endDate)) { return new ArrayList<>(); } List localDateList = getAllDatesInTheDateRange(dateStr2LocalDate(startDate), dateStr2LocalDate(endDate)); if (CollectionUtils.isEmpty(localDateList)) { return new ArrayList<>(); } List 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); } } }