田源
2025-04-03 9b4433fddf5b401edb0aace8a404ac733b122702
Source/BladeX-Tool/blade-core-tool/src/main/java/org/springblade/core/tool/utils/DateUtil.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,634 @@
package org.springblade.core.tool.utils;
import org.springframework.util.Assert;
import java.text.ParseException;
import java.time.*;
import java.time.format.DateTimeFormatter;
import java.time.temporal.Temporal;
import java.time.temporal.TemporalAccessor;
import java.time.temporal.TemporalAmount;
import java.time.temporal.TemporalQuery;
import java.util.Calendar;
import java.util.Date;
import java.util.GregorianCalendar;
import java.util.TimeZone;
/**
 * æ—¥æœŸå·¥å…·ç±»
 *
 * @author L.cm
 */
public class DateUtil {
   public static final String PATTERN_DATETIME = "yyyy-MM-dd HH:mm:ss";
   public static final String PATTERN_DATETIME_MINI = "yyyyMMddHHmmss";
   public static final String PATTERN_DATE = "yyyy-MM-dd";
   public static final String PATTERN_TIME = "HH:mm:ss";
   /**
    * è€ date æ ¼å¼åŒ–
    */
   public static final ConcurrentDateFormat DATETIME_FORMAT = ConcurrentDateFormat.of(PATTERN_DATETIME);
   public static final ConcurrentDateFormat DATETIME_MINI_FORMAT = ConcurrentDateFormat.of(PATTERN_DATETIME_MINI);
   public static final ConcurrentDateFormat DATE_FORMAT = ConcurrentDateFormat.of(PATTERN_DATE);
   public static final ConcurrentDateFormat TIME_FORMAT = ConcurrentDateFormat.of(PATTERN_TIME);
   /**
    * java 8 æ—¶é—´æ ¼å¼åŒ–
    */
   public static final DateTimeFormatter DATETIME_FORMATTER = DateTimeFormatter.ofPattern(DateUtil.PATTERN_DATETIME);
   public static final DateTimeFormatter DATETIME_MINI_FORMATTER = DateTimeFormatter.ofPattern(DateUtil.PATTERN_DATETIME_MINI);
   public static final DateTimeFormatter DATE_FORMATTER = DateTimeFormatter.ofPattern(DateUtil.PATTERN_DATE);
   public static final DateTimeFormatter TIME_FORMATTER = DateTimeFormatter.ofPattern(DateUtil.PATTERN_TIME);
   /**
    * èŽ·å–å½“å‰æ—¥æœŸ
    *
    * @return å½“前日期
    */
   public static Date now() {
      return new Date();
   }
   /**
    * æ·»åŠ å¹´
    *
    * @param date       æ—¶é—´
    * @param yearsToAdd æ·»åŠ çš„å¹´æ•°
    * @return è®¾ç½®åŽçš„æ—¶é—´
    */
   public static Date plusYears(Date date, int yearsToAdd) {
      return DateUtil.set(date, Calendar.YEAR, yearsToAdd);
   }
   /**
    * æ·»åŠ æœˆ
    *
    * @param date        æ—¶é—´
    * @param monthsToAdd æ·»åŠ çš„æœˆæ•°
    * @return è®¾ç½®åŽçš„æ—¶é—´
    */
   public static Date plusMonths(Date date, int monthsToAdd) {
      return DateUtil.set(date, Calendar.MONTH, monthsToAdd);
   }
   /**
    * æ·»åР呍
    *
    * @param date       æ—¶é—´
    * @param weeksToAdd æ·»åŠ çš„å‘¨æ•°
    * @return è®¾ç½®åŽçš„æ—¶é—´
    */
   public static Date plusWeeks(Date date, int weeksToAdd) {
      return DateUtil.plus(date, Period.ofWeeks(weeksToAdd));
   }
   /**
    * æ·»åР天
    *
    * @param date      æ—¶é—´
    * @param daysToAdd æ·»åŠ çš„å¤©æ•°
    * @return è®¾ç½®åŽçš„æ—¶é—´
    */
   public static Date plusDays(Date date, long daysToAdd) {
      return DateUtil.plus(date, Duration.ofDays(daysToAdd));
   }
   /**
    * æ·»åŠ å°æ—¶
    *
    * @param date       æ—¶é—´
    * @param hoursToAdd æ·»åŠ çš„å°æ—¶æ•°
    * @return è®¾ç½®åŽçš„æ—¶é—´
    */
   public static Date plusHours(Date date, long hoursToAdd) {
      return DateUtil.plus(date, Duration.ofHours(hoursToAdd));
   }
   /**
    * æ·»åŠ åˆ†é’Ÿ
    *
    * @param date         æ—¶é—´
    * @param minutesToAdd æ·»åŠ çš„åˆ†é’Ÿæ•°
    * @return è®¾ç½®åŽçš„æ—¶é—´
    */
   public static Date plusMinutes(Date date, long minutesToAdd) {
      return DateUtil.plus(date, Duration.ofMinutes(minutesToAdd));
   }
   /**
    * æ·»åŠ ç§’
    *
    * @param date         æ—¶é—´
    * @param secondsToAdd æ·»åŠ çš„ç§’æ•°
    * @return è®¾ç½®åŽçš„æ—¶é—´
    */
   public static Date plusSeconds(Date date, long secondsToAdd) {
      return DateUtil.plus(date, Duration.ofSeconds(secondsToAdd));
   }
   /**
    * æ·»åŠ æ¯«ç§’
    *
    * @param date        æ—¶é—´
    * @param millisToAdd æ·»åŠ çš„æ¯«ç§’æ•°
    * @return è®¾ç½®åŽçš„æ—¶é—´
    */
   public static Date plusMillis(Date date, long millisToAdd) {
      return DateUtil.plus(date, Duration.ofMillis(millisToAdd));
   }
   /**
    * æ·»åŠ çº³ç§’
    *
    * @param date       æ—¶é—´
    * @param nanosToAdd æ·»åŠ çš„çº³ç§’æ•°
    * @return è®¾ç½®åŽçš„æ—¶é—´
    */
   public static Date plusNanos(Date date, long nanosToAdd) {
      return DateUtil.plus(date, Duration.ofNanos(nanosToAdd));
   }
   /**
    * æ—¥æœŸæ·»åŠ æ—¶é—´é‡
    *
    * @param date   æ—¶é—´
    * @param amount æ—¶é—´é‡
    * @return è®¾ç½®åŽçš„æ—¶é—´
    */
   public static Date plus(Date date, TemporalAmount amount) {
      Instant instant = date.toInstant();
      return Date.from(instant.plus(amount));
   }
   /**
    * å‡å°‘å¹´
    *
    * @param date  æ—¶é—´
    * @param years å‡å°‘的年数
    * @return è®¾ç½®åŽçš„æ—¶é—´
    */
   public static Date minusYears(Date date, int years) {
      return DateUtil.set(date, Calendar.YEAR, -years);
   }
   /**
    * å‡å°‘月
    *
    * @param date   æ—¶é—´
    * @param months å‡å°‘的月数
    * @return è®¾ç½®åŽçš„æ—¶é—´
    */
   public static Date minusMonths(Date date, int months) {
      return DateUtil.set(date, Calendar.MONTH, -months);
   }
   /**
    * å‡å°‘周
    *
    * @param date  æ—¶é—´
    * @param weeks å‡å°‘的周数
    * @return è®¾ç½®åŽçš„æ—¶é—´
    */
   public static Date minusWeeks(Date date, int weeks) {
      return DateUtil.minus(date, Period.ofWeeks(weeks));
   }
   /**
    * å‡å°‘天
    *
    * @param date æ—¶é—´
    * @param days å‡å°‘的天数
    * @return è®¾ç½®åŽçš„æ—¶é—´
    */
   public static Date minusDays(Date date, long days) {
      return DateUtil.minus(date, Duration.ofDays(days));
   }
   /**
    * å‡å°‘小时
    *
    * @param date  æ—¶é—´
    * @param hours å‡å°‘的小时数
    * @return è®¾ç½®åŽçš„æ—¶é—´
    */
   public static Date minusHours(Date date, long hours) {
      return DateUtil.minus(date, Duration.ofHours(hours));
   }
   /**
    * å‡å°‘分钟
    *
    * @param date    æ—¶é—´
    * @param minutes å‡å°‘的分钟数
    * @return è®¾ç½®åŽçš„æ—¶é—´
    */
   public static Date minusMinutes(Date date, long minutes) {
      return DateUtil.minus(date, Duration.ofMinutes(minutes));
   }
   /**
    * å‡å°‘ç§’
    *
    * @param date    æ—¶é—´
    * @param seconds å‡å°‘的秒数
    * @return è®¾ç½®åŽçš„æ—¶é—´
    */
   public static Date minusSeconds(Date date, long seconds) {
      return DateUtil.minus(date, Duration.ofSeconds(seconds));
   }
   /**
    * å‡å°‘毫秒
    *
    * @param date   æ—¶é—´
    * @param millis å‡å°‘的毫秒数
    * @return è®¾ç½®åŽçš„æ—¶é—´
    */
   public static Date minusMillis(Date date, long millis) {
      return DateUtil.minus(date, Duration.ofMillis(millis));
   }
   /**
    * å‡å°‘纳秒
    *
    * @param date  æ—¶é—´
    * @param nanos å‡å°‘的纳秒数
    * @return è®¾ç½®åŽçš„æ—¶é—´
    */
   public static Date minusNanos(Date date, long nanos) {
      return DateUtil.minus(date, Duration.ofNanos(nanos));
   }
   /**
    * æ—¥æœŸå‡å°‘时间量
    *
    * @param date   æ—¶é—´
    * @param amount æ—¶é—´é‡
    * @return è®¾ç½®åŽçš„æ—¶é—´
    */
   public static Date minus(Date date, TemporalAmount amount) {
      Instant instant = date.toInstant();
      return Date.from(instant.minus(amount));
   }
   /**
    * è®¾ç½®æ—¥æœŸå±žæ€§
    *
    * @param date          æ—¶é—´
    * @param calendarField æ›´æ”¹çš„属性
    * @param amount        æ›´æ”¹æ•°ï¼Œ-1表示减少
    * @return è®¾ç½®åŽçš„æ—¶é—´
    */
   private static Date set(Date date, int calendarField, int amount) {
      Assert.notNull(date, "The date must not be null");
      Calendar c = Calendar.getInstance();
      c.setLenient(false);
      c.setTime(date);
      c.add(calendarField, amount);
      return c.getTime();
   }
   /**
    * æ—¥æœŸæ—¶é—´æ ¼å¼åŒ–
    *
    * @param date æ—¶é—´
    * @return æ ¼å¼åŒ–后的时间
    */
   public static String formatDateTime(Date date) {
      return DATETIME_FORMAT.format(date);
   }
   /**
    * æ—¥æœŸæ—¶é—´æ ¼å¼åŒ–
    *
    * @param date æ—¶é—´
    * @return æ ¼å¼åŒ–后的时间
    */
   public static String formatDateTimeMini(Date date) {
      return DATETIME_MINI_FORMAT.format(date);
   }
   /**
    * æ—¥æœŸæ ¼å¼åŒ–
    *
    * @param date æ—¶é—´
    * @return æ ¼å¼åŒ–后的时间
    */
   public static String formatDate(Date date) {
      return DATE_FORMAT.format(date);
   }
   /**
    * æ—¶é—´æ ¼å¼åŒ–
    *
    * @param date æ—¶é—´
    * @return æ ¼å¼åŒ–后的时间
    */
   public static String formatTime(Date date) {
      return TIME_FORMAT.format(date);
   }
   /**
    * æ—¥æœŸæ ¼å¼åŒ–
    *
    * @param date    æ—¶é—´
    * @param pattern è¡¨è¾¾å¼
    * @return æ ¼å¼åŒ–后的时间
    */
   public static String format(Date date, String pattern) {
      return ConcurrentDateFormat.of(pattern).format(date);
   }
   /**
    * java8 æ—¥æœŸæ—¶é—´æ ¼å¼åŒ–
    *
    * @param temporal æ—¶é—´
    * @return æ ¼å¼åŒ–后的时间
    */
   public static String formatDateTime(TemporalAccessor temporal) {
      return DATETIME_FORMATTER.format(temporal);
   }
   /**
    * java8 æ—¥æœŸæ—¶é—´æ ¼å¼åŒ–
    *
    * @param temporal æ—¶é—´
    * @return æ ¼å¼åŒ–后的时间
    */
   public static String formatDateTimeMini(TemporalAccessor temporal) {
      return DATETIME_MINI_FORMATTER.format(temporal);
   }
   /**
    * java8 æ—¥æœŸæ—¶é—´æ ¼å¼åŒ–
    *
    * @param temporal æ—¶é—´
    * @return æ ¼å¼åŒ–后的时间
    */
   public static String formatDate(TemporalAccessor temporal) {
      return DATE_FORMATTER.format(temporal);
   }
   /**
    * java8 æ—¶é—´æ ¼å¼åŒ–
    *
    * @param temporal æ—¶é—´
    * @return æ ¼å¼åŒ–后的时间
    */
   public static String formatTime(TemporalAccessor temporal) {
      return TIME_FORMATTER.format(temporal);
   }
   /**
    * java8 æ—¥æœŸæ ¼å¼åŒ–
    *
    * @param temporal æ—¶é—´
    * @param pattern  è¡¨è¾¾å¼
    * @return æ ¼å¼åŒ–后的时间
    */
   public static String format(TemporalAccessor temporal, String pattern) {
      return DateTimeFormatter.ofPattern(pattern).format(temporal);
   }
   /**
    * å°†å­—符串转换为时间
    *
    * @param dateStr æ—¶é—´å­—符串
    * @param pattern è¡¨è¾¾å¼
    * @return æ—¶é—´
    */
   public static Date parse(String dateStr, String pattern) {
      ConcurrentDateFormat format = ConcurrentDateFormat.of(pattern);
      try {
         return format.parse(dateStr);
      } catch (ParseException e) {
         throw Exceptions.unchecked(e);
      }
   }
   /**
    * å°†å­—符串转换为时间
    *
    * @param dateStr æ—¶é—´å­—符串
    * @param format  ConcurrentDateFormat
    * @return æ—¶é—´
    */
   public static Date parse(String dateStr, ConcurrentDateFormat format) {
      try {
         return format.parse(dateStr);
      } catch (ParseException e) {
         throw Exceptions.unchecked(e);
      }
   }
   /**
    * å°†å­—符串转换为时间
    *
    * @param dateStr æ—¶é—´å­—符串
    * @param pattern è¡¨è¾¾å¼
    * @return æ—¶é—´
    */
   public static <T> T parse(String dateStr, String pattern, TemporalQuery<T> query) {
      return DateTimeFormatter.ofPattern(pattern).parse(dateStr, query);
   }
   /**
    * æ—¶é—´è½¬ Instant
    *
    * @param dateTime æ—¶é—´
    * @return Instant
    */
   public static Instant toInstant(LocalDateTime dateTime) {
      return dateTime.atZone(ZoneId.systemDefault()).toInstant();
   }
   /**
    * Instant è½¬ æ—¶é—´
    *
    * @param instant Instant
    * @return Instant
    */
   public static LocalDateTime toDateTime(Instant instant) {
      return LocalDateTime.ofInstant(instant, ZoneId.systemDefault());
   }
   /**
    * è½¬æ¢æˆ date
    *
    * @param dateTime LocalDateTime
    * @return Date
    */
   public static Date toDate(LocalDateTime dateTime) {
      return Date.from(DateUtil.toInstant(dateTime));
   }
   /**
    * è½¬æ¢æˆ date
    *
    * @param localDate LocalDate
    * @return Date
    */
   public static Date toDate(final LocalDate localDate) {
      return Date.from(localDate.atStartOfDay(ZoneId.systemDefault()).toInstant());
   }
   /**
    * Converts local date time to Calendar.
    */
   public static Calendar toCalendar(final LocalDateTime localDateTime) {
      return GregorianCalendar.from(ZonedDateTime.of(localDateTime, ZoneId.systemDefault()));
   }
   /**
    * localDateTime è½¬æ¢æˆæ¯«ç§’æ•°
    *
    * @param localDateTime LocalDateTime
    * @return long
    */
   public static long toMilliseconds(final LocalDateTime localDateTime) {
      return localDateTime.atZone(ZoneId.systemDefault()).toInstant().toEpochMilli();
   }
   /**
    * localDate è½¬æ¢æˆæ¯«ç§’æ•°
    *
    * @param localDate LocalDate
    * @return long
    */
   public static long toMilliseconds(LocalDate localDate) {
      return toMilliseconds(localDate.atStartOfDay());
   }
   /**
    * è½¬æ¢æˆjava8 æ—¶é—´
    *
    * @param calendar æ—¥åކ
    * @return LocalDateTime
    */
   public static LocalDateTime fromCalendar(final Calendar calendar) {
      TimeZone tz = calendar.getTimeZone();
      ZoneId zid = tz == null ? ZoneId.systemDefault() : tz.toZoneId();
      return LocalDateTime.ofInstant(calendar.toInstant(), zid);
   }
   /**
    * è½¬æ¢æˆjava8 æ—¶é—´
    *
    * @param instant Instant
    * @return LocalDateTime
    */
   public static LocalDateTime fromInstant(final Instant instant) {
      return LocalDateTime.ofInstant(instant, ZoneId.systemDefault());
   }
   /**
    * è½¬æ¢æˆjava8 æ—¶é—´
    *
    * @param date Date
    * @return LocalDateTime
    */
   public static LocalDateTime fromDate(final Date date) {
      return LocalDateTime.ofInstant(date.toInstant(), ZoneId.systemDefault());
   }
   /**
    * è½¬æ¢æˆjava8 æ—¶é—´
    *
    * @param milliseconds æ¯«ç§’æ•°
    * @return LocalDateTime
    */
   public static LocalDateTime fromMilliseconds(final long milliseconds) {
      return LocalDateTime.ofInstant(Instant.ofEpochMilli(milliseconds), ZoneId.systemDefault());
   }
   /**
    * æ¯”较2个时间差,跨度比较小
    *
    * @param startInclusive å¼€å§‹æ—¶é—´
    * @param endExclusive   ç»“束时间
    * @return æ—¶é—´é—´éš”
    */
   public static Duration between(Temporal startInclusive, Temporal endExclusive) {
      return Duration.between(startInclusive, endExclusive);
   }
   /**
    * æ¯”较2个时间差,跨度比较大,年月日为单位
    *
    * @param startDate å¼€å§‹æ—¶é—´
    * @param endDate   ç»“束时间
    * @return æ—¶é—´é—´éš”
    */
   public static Period between(LocalDate startDate, LocalDate endDate) {
      return Period.between(startDate, endDate);
   }
   /**
    * æ¯”较2个 æ—¶é—´å·®
    *
    * @param startDate å¼€å§‹æ—¶é—´
    * @param endDate   ç»“束时间
    * @return æ—¶é—´é—´éš”
    */
   public static Duration between(Date startDate, Date endDate) {
      return Duration.between(startDate.toInstant(), endDate.toInstant());
   }
   /**
    * å°†ç§’数转换为日时分秒
    *
    * @param second ç§’æ•°
    * @return æ—¶é—´
    */
   public static String secondToTime(Long second) {
      // åˆ¤æ–­æ˜¯å¦ä¸ºç©º
      if (second == null || second == 0L) {
         return StringPool.EMPTY;
      }
      //转换天数
      long days = second / 86400;
      //剩余秒数
      second = second % 86400;
      //转换小时
      long hours = second / 3600;
      //剩余秒数
      second = second % 3600;
      //转换分钟
      long minutes = second / 60;
      //剩余秒数
      second = second % 60;
      if (days > 0) {
         return StringUtil.format("{}天{}小时{}分{}秒", days, hours, minutes, second);
      } else {
         return StringUtil.format("{}小时{}分{}秒", hours, minutes, second);
      }
   }
   /**
    * èŽ·å–ä»Šå¤©çš„æ—¥æœŸ
    *
    * @return æ—¶é—´
    */
   public static String today() {
      return format(new Date(), "yyyyMMdd");
   }
   /**
    * èŽ·å–ä»Šå¤©çš„æ—¶é—´
    *
    * @return æ—¶é—´
    */
   public static String time() {
      return format(new Date(), PATTERN_DATETIME_MINI);
   }
   /**
    * èŽ·å–ä»Šå¤©çš„å°æ—¶æ•°
    *
    * @return æ—¶é—´
    */
   public static Integer hour() {
      return NumberUtil.toInt(format(new Date(), "HH"));
   }
}