package com.cloud.common.utils; import org.apache.commons.lang3.StringUtils; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import java.sql.Timestamp; import java.text.ParseException; import java.text.SimpleDateFormat; import java.time.*; import java.time.format.DateTimeFormatter; import java.time.format.DateTimeParseException; import java.time.temporal.ChronoUnit; import java.time.temporal.TemporalAdjuster; import java.time.temporal.TemporalAdjusters; import java.util.Calendar; import java.util.Date; import java.util.GregorianCalendar; /** * 日期工具类 * @author lp * @date 2018-08-05 */ public class DateUtil { /** * the milli second of a day */ public static final long DAYMILLI = 24 * 60 * 60 * 1000; /** * the milli seconds of an hour */ public static final long HOURMILLI = 60 * 60 * 1000; /** * the milli seconds of a minute */ public static final long MINUTEMILLI = 60 * 1000; /** * the milli seconds of a second */ public static final long SECONDMILLI = 1000; /** * added time */ public static final String TIMETO = " 23:59:59"; /** * flag before */ public static final transient int BEFORE = 1; /** * flag after */ public static final transient int AFTER = 2; /** * flag equal */ public static final transient int EQUAL = 3; /** * date format dd/MMM/yyyy:HH:mm:ss +0900 */ public static final String TIME_PATTERN_LONG = "dd/MMM/yyyy:HH:mm:ss +0900"; /** * date format dd/MM/yyyy:HH:mm:ss +0900 */ public static final String TIME_PATTERN_LONG2 = "dd/MM/yyyy:HH:mm:ss +0900"; /** * date format YYYY-MM-DD HH24:MI:SS */ public static final String DB_TIME_PATTERN = "YYYY-MM-DD HH24:MI:SS"; /** * date format YYYYMMDDHH24MISS */ public static final String DB_TIME_PATTERN_1 = "YYYYMMDDHH24MISS"; /** * date format dd/MM/yy HH:mm:ss */ public static final String TIME_PATTERN_SHORT = "dd/MM/yy HH:mm:ss"; /** * date format dd/MM/yy HH24:mm */ public static final String TIME_PATTERN_SHORT_1 = "yyyy/MM/dd HH:mm"; /** * date format yyyy年MM月dd日 HH:mm:ss */ public static final String TIME_PATTERN_SHORT_2 = "yyyy年MM月dd日 HH:mm:ss"; /** * date format yyyyMMddHHmmss */ public static final String TIME_PATTERN_SESSION = "yyyyMMddHHmmss"; /** * date format yyyyMMddHHmmssSSS */ public static final String TIME_PATTERN_MILLISECOND = "yyyyMMddHHmmssSSS"; /** * date format yyyyMMdd */ public static final String DATE_FMT_0 = "yyyyMMdd"; /** * date format yyyy/MM/dd */ public static final String DATE_FMT_1 = "yyyy/MM/dd"; /** * date format yyyy/MM/dd hh:mm:ss */ public static final String DATE_FMT_2 = "yyyy/MM/dd hh:mm:ss"; /** * date format yyyy-MM-dd */ public static final String DATE_FMT_3 = "yyyy-MM-dd"; /** * date format yyyy年MM月dd日 */ public static final String DATE_FMT_4 = "yyyy年MM月dd日"; /** * date format yyyy-MM-dd HH */ public static final String DATE_FMT_5 = "yyyy-MM-dd HH"; /** * date format yyyy-MM */ public static final String DATE_FMT_6 = "yyyy-MM"; /** * date format MM月dd日 HH:mm */ public static final String DATE_FMT_7 = "MM月dd日 HH:mm"; /** * date format MM月dd日 HH:mm */ public static final String DATE_FMT_8 = "HH:mm:ss"; /** * date format MM月dd日 HH:mm */ public static final String DATE_FMT_9 = "yyyy.MM.dd"; public static final String DATE_FMT_10 = "HH:mm"; public static final String DATE_FMT_11 = "yyyy.MM.dd HH:mm:ss"; /** * date format yyyy年MM月dd日 */ public static final String DATE_FMT_12 = "MM月dd日"; public static final String DATE_FMT_13 = "yyyy年MM月dd日HH时mm分"; public static final String DATE_FMT_14 = "yyyyMM"; public static final String DATE_FMT_15 = "MM-dd HH:mm:ss"; public static final String DATE_FMT_16 = "yyyyMMddHHmm"; public static final String DATE_FMT_17 = "HHmmss"; public static final String DATE_FMT_18 = "yyyy"; /** * date format yyyy-MM-dd HH:mm:ss */ public static final String TIME_PATTERN = "yyyy-MM-dd HH:mm:ss"; private static final Logger logger = LoggerFactory.getLogger(DateUtil.class); /** * 得到当前日期的字符串表示 * * @return */ public static String getCurrentDateStr() { SimpleDateFormat sdf = new SimpleDateFormat(TIME_PATTERN); try { return sdf.format(new Date()); } catch (Exception e) { e.printStackTrace(); } return null; } /** * 等得到当前日期 - 指定格式 * @param format * @return */ public static String getCurrentDateStr(String format){ SimpleDateFormat sdf = new SimpleDateFormat(format); try { return sdf.format(new Date()); } catch (Exception e) { e.printStackTrace(); } return null; } /** * 得到当前指定日期格式 * @param format * @return Date */ public static Date getCurrentDate(String format){ SimpleDateFormat simpleDateFormat = new SimpleDateFormat(format); String sDate = simpleDateFormat.format(new Date()); try { return simpleDateFormat.parse(sDate); } catch (ParseException e) { e.printStackTrace(); } return null; } /** * 得到当前指定日期格式 * @param format * @return Date */ public static Date stringToDate(String date,String format) { SimpleDateFormat simpleDateFormat = new SimpleDateFormat(format); try { return simpleDateFormat.parse(date); } catch (ParseException e) { e.printStackTrace(); } return null; } /** * localDateTime 转 自定义格式string * * @param localDateTime * @param format 例:yyyy-MM-dd hh:mm:ss * @return */ public static String localDateTimeToString(LocalDateTime localDateTime, String format) { try { DateTimeFormatter formatter = DateTimeFormatter.ofPattern(format); return localDateTime.format(formatter); } catch (DateTimeParseException e) { e.printStackTrace(); } return null; } /** * string 转 LocalDateTime * * @param dateStr 例:"2017-08-11 01:00:00" * @param format 例:"yyyy-MM-dd HH:mm:ss" * @return */ public static LocalDateTime stringToLocalDateTime(String dateStr, String format) { try { DateTimeFormatter formatter = DateTimeFormatter.ofPattern(format); return LocalDateTime.parse(dateStr, formatter); } catch (DateTimeParseException e) { e.printStackTrace(); } return null; } /** * localDate 转 自定义格式string * * @param localDate * @param format 例:yyyy-MM-dd hh:mm:ss * @return */ public static String localDateToString(LocalDate localDate, String format) { try { DateTimeFormatter formatter = DateTimeFormatter.ofPattern(format); return localDate.format(formatter); } catch (DateTimeParseException e) { e.printStackTrace(); } return null; } /** * string 转 LocalDate * * @param dateStr 例:"2017-08-11 01:00:00" * @param format 例:"yyyy-MM-dd HH:mm:ss" * @return */ public static LocalDate stringToLocalDate(String dateStr, String format) { try { DateTimeFormatter formatter = DateTimeFormatter.ofPattern(format); return LocalDate.parse(dateStr, formatter); } catch (DateTimeParseException e) { e.printStackTrace(); } return null; } /** * 根据时间获取当月有多少天数 * * @param date * @return */ public static int getActualMaximum(Date date) { return dateToLocalDateTime(date).getMonth().length(dateToLocalDate(date).isLeapYear()); } /** * 根据日期获得星期 * * @param date * @return 1:星期一;2:星期二;3:星期三;4:星期四;5:星期五;6:星期六;7:星期日; */ public static int getWeekOfDate(Date date) { return dateToLocalDateTime(date).getDayOfWeek().getValue(); } /** * 计算两个日期LocalDate相差的天数,不考虑日期前后,返回结果>=0 * * @param before * @param after * @return */ public static int getAbsDateDiffDay(LocalDate before, LocalDate after) { return Math.abs(Period.between(before, after).getDays()); } /** * 计算两个时间LocalDateTime相差的天数,不考虑日期前后,返回结果>=0 * * @param before * @param after * @return */ public static int getAbsTimeDiffDay(LocalDateTime before, LocalDateTime after) { return Math.abs(Period.between(before.toLocalDate(), after.toLocalDate()).getDays()); } /** * 根据传入日期返回星期几 * * @param date 日期 * @return 1-7 1:星期天,2:星期一,3:星期二,4:星期三,5:星期四,6:星期五,7:星期六 */ public static int getDayOfWeek(Date date) { Calendar cal = new GregorianCalendar(); cal.setTime(date); return cal.get(Calendar.DAY_OF_WEEK); } /** * 获取指定日期的当月的月份数 * * @param date * @return */ public static int getLastMonth(Date date) { return dateToLocalDateTime(date).getMonth().getValue(); } /** * 特定日期的当月第一天 * * @param date 默认当前日期 * @return */ public static LocalDate newThisMonth(Date date) { if(date ==null){ date =new Date(); } LocalDate localDate = dateToLocalDate(date); return LocalDate.of(localDate.getYear(), localDate.getMonth(), 1); } /** * 特定日期的当月最后一天 * * @param date * @return */ public static LocalDate lastThisMonth(Date date) { if(date ==null){ date =new Date(); } int lastDay = getActualMaximum(date); LocalDate localDate = dateToLocalDate(date); return LocalDate.of(localDate.getYear(), localDate.getMonth(), lastDay); } /** * 获得指定某一天 一周的第一天 * * @param date 默认当前日期 * @return */ public static String newThisWeek(String date) { if (date ==null) { date = getCurrentDateStr(DATE_FMT_3); } LocalDate inputDate = LocalDate.parse(date); TemporalAdjuster firstOfWeek = TemporalAdjusters.ofDateAdjuster(localDate -> localDate.minusDays(localDate.getDayOfWeek().getValue() - DayOfWeek.MONDAY.getValue())); return inputDate.with(firstOfWeek).toString(); } /** * 获得指定某一天 一周的最后一天 * * @param date 默认当前日期 * @return */ public static String lastThisWeek(String date) { if (StringUtils.isBlank(date)) { date = getCurrentDateStr(DATE_FMT_3); } LocalDate inputDate = LocalDate.parse(date); TemporalAdjuster lastOfWeek = TemporalAdjusters.ofDateAdjuster(localDate -> localDate.plusDays(DayOfWeek.SUNDAY.getValue() - localDate.getDayOfWeek().getValue())); return inputDate.with(lastOfWeek).toString(); } /** * 获取当前时间 * * @return LocalDateTime */ public static LocalDateTime getCurrentLocalDateTime() { return LocalDateTime.now(Clock.system(ZoneId.of("Asia/Shanghai"))); } /** * 修改日期时间的时间部分 * * @param date * @param customTime 必须为"hh:mm:ss"这种格式 */ public static LocalDateTime reserveDateCustomTime(Date date, String customTime) { String dateStr = dateToLocalDate(date).toString() + " " + customTime; return stringToLocalDateTime(dateStr, "yyyy-MM-dd HH:mm:ss"); } /** * 修改日期时间的时间部分 * * @param date * @param customTime 必须为"hh:mm:ss"这种格式 */ public static LocalDateTime reserveDateCustomTime(Timestamp date, String customTime) { String dateStr = timestampToLocalDate(date).toString() + " " + customTime; return stringToLocalDateTime(dateStr, "yyyy-MM-dd HH:mm:ss"); } /** * 把日期后的时间归0 变成(yyyy-MM-dd 00:00:00:000) * * @param date * @return LocalDateTime */ public static final LocalDateTime zerolizedTime(Date date) { LocalDateTime localDateTime = dateToLocalDateTime(date); return LocalDateTime.of(localDateTime.getYear(), localDateTime.getMonth(), localDateTime.getDayOfMonth(), 0, 0, 0, 0); } /** * 把时间变成(yyyy-MM-dd 00:00:00:000) * * @param date * @return LocalDateTime */ public static LocalDateTime zerolizedTime(Timestamp date) { LocalDateTime localDateTime = timestampToLocalDateTime(date); return LocalDateTime.of(localDateTime.getYear(), localDateTime.getMonth(), localDateTime.getDayOfMonth(), 0, 0, 0, 0); } /** * 把日期的时间变成(yyyy-MM-dd 23:59:59:999) * * @param date * @return LocalDateTime */ public static LocalDateTime getEndTime(Date date) { LocalDateTime localDateTime = dateToLocalDateTime(date); return LocalDateTime.of(localDateTime.getYear(), localDateTime.getMonth(), localDateTime.getDayOfMonth(), 23, 59, 59, 999 * 1000000); } /** * 把时间变成(yyyy-MM-dd 23:59:59:999) * * @param date * @return LocalDateTime */ public static LocalDateTime getEndTime(Timestamp date) { LocalDateTime localDateTime = timestampToLocalDateTime(date); return LocalDateTime.of(localDateTime.getYear(), localDateTime.getMonth(), localDateTime.getDayOfMonth(), 23, 59, 59, 999 * 1000000); } /** * 计算特定时间到 当天 23.59.59.999 的秒数 * * @return */ public static int calculateToEndTime(Date date) { LocalDateTime localDateTime = dateToLocalDateTime(date); LocalDateTime end = getEndTime(date); return (int) (end.toEpochSecond(ZoneOffset.UTC) - localDateTime.toEpochSecond(ZoneOffset.UTC)); } /** * 增加或减少年/月/周/天/小时/分/秒数 * * @param localDateTime 例:ChronoUnit.DAYS * @param chronoUnit * @param num * @return LocalDateTime */ public static LocalDateTime addTime(LocalDateTime localDateTime, ChronoUnit chronoUnit, int num) { return localDateTime.plus(num, chronoUnit); } /** * 增加或减少年/月/周/天/小时/分/秒数 * * @param chronoUnit 例:ChronoUnit.DAYS * @param num * @return LocalDateTime */ public static LocalDateTime addTime(Date date, ChronoUnit chronoUnit, int num) { long nanoOfSecond = (date.getTime() % 1000) * 1000000; LocalDateTime localDateTime = LocalDateTime.ofEpochSecond(date.getTime() / 1000, (int) nanoOfSecond, ZoneOffset.of("+8")); return localDateTime.plus(num, chronoUnit); } /** * 增加或减少年/月/周/天/小时/分/秒数 * * @param chronoUnit 例:ChronoUnit.DAYS * @param num * @return LocalDateTime */ public static LocalDateTime addTime(Timestamp date, ChronoUnit chronoUnit, int num) { long nanoOfSecond = (date.getTime() % 1000) * 1000000; LocalDateTime localDateTime = LocalDateTime.ofEpochSecond(date.getTime() / 1000, (int) nanoOfSecond, ZoneOffset.of("+8")); return localDateTime.plus(num, chronoUnit); } /** * Date 转 LocalDateTime * * @param date * @return LocalDateTime */ public static LocalDateTime dateToLocalDateTime(Date date) { long nanoOfSecond = (date.getTime() % 1000) * 1000000; LocalDateTime localDateTime = LocalDateTime.ofEpochSecond(date.getTime() / 1000, (int) nanoOfSecond, ZoneOffset.of("+8")); return localDateTime; } /** * Timestamp 转 LocalDateTime * * @param date * @return LocalDateTime */ public static LocalDateTime timestampToLocalDateTime(Timestamp date) { LocalDateTime localDateTime = LocalDateTime.ofEpochSecond(date.getTime() / 1000, date.getNanos(), ZoneOffset.of("+8")); return localDateTime; } /** * Date 转 LocalDateTime * * @param date * @return LocalDate */ public static LocalDate dateToLocalDate(Date date) { return dateToLocalDateTime(date).toLocalDate(); } /** * timestamp 转 LocalDateTime * * @param date * @return LocalDate */ public static LocalDate timestampToLocalDate(Timestamp date) { return timestampToLocalDateTime(date).toLocalDate(); } /** * 比较两个LocalDateTime是否同一天 * * @param begin * @param end * @return */ public static boolean isTheSameDay(LocalDateTime begin, LocalDateTime end) { return begin.toLocalDate().equals(end.toLocalDate()); } /** * 比较两个时间LocalDateTime大小 * * @param time1 * @param time2 * @return 1:第一个比第二个大;0:第一个与第二个相同;-1:第一个比第二个小 */ public static int compareTwoTime(LocalDateTime time1, LocalDateTime time2) { if (time1.isAfter(time2)) { return 1; } else if (time1.isBefore(time2)) { return -1; } else { return 0; } } /** * 比较time1,time2两个时间相差的秒数,如果time1<=time2,返回0 * * @param time1 * @param time2 */ public static long getTwoTimeDiffSecond(Timestamp time1, Timestamp time2) { long diff = timestampToLocalDateTime(time1).toEpochSecond(ZoneOffset.UTC) - timestampToLocalDateTime(time2).toEpochSecond(ZoneOffset.UTC); if (diff > 0) { return diff; } else { return 0; } } /** * 比较time1,time2两个时间相差的分钟数,如果time1<=time2,返回0 * * @param time1 * @param time2 */ public static long getTwoTimeDiffMin(Timestamp time1, Timestamp time2) { long diff = getTwoTimeDiffSecond(time1, time2) / 60; if (diff > 0) { return diff; } else { return 0; } } /** * 比较time1,time2两个时间相差的小时数,如果time1<=time2,返回0 * * @param time1 * @param time2 */ public static long getTwoTimeDiffHour(Timestamp time1, Timestamp time2) { long diff = getTwoTimeDiffSecond(time1, time2) / 3600; if (diff > 0) { return diff; } else { return 0; } } /** * 判断当前时间是否在时间范围内 * * @param startTime * @param endTime * @return */ public static boolean isTimeInRange(Date startTime, Date endTime) throws Exception { LocalDateTime now = getCurrentLocalDateTime(); LocalDateTime start = dateToLocalDateTime(startTime); LocalDateTime end = dateToLocalDateTime(endTime); return (start.isBefore(now) && end.isAfter(now)) || start.isEqual(now) || end.isEqual(now); } public static boolean isValidDate(String str) { boolean convertSuccess=true; // 指定日期格式为四位年/两位月份/两位日期,注意yyyy/MM/dd区分大小写; SimpleDateFormat format = new SimpleDateFormat(TIME_PATTERN); try { // 设置lenient为false. 否则SimpleDateFormat会比较宽松地验证日期,比如2007/02/29会被接受,并转换成2007/03/01 format.setLenient(false); format.parse(str); } catch (ParseException e) { e.printStackTrace(); convertSuccess=false; } return convertSuccess; } public static void main(String[] args) { System.out.println(DateUtil.getCurrentDateStr()); System.out.println(DateUtil.newThisMonth(null) + "--------" +DateUtil.newThisWeek(null)); System.out.println(DateUtil.lastThisMonth(null) + "--------" +DateUtil.lastThisMonth(null)); } }