¶Ô±ÈÐÂÎļþ |
| | |
| | | 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")); |
| | | } |
| | | |
| | | } |