package com.vincent.rsf.server.common.utils; import org.apache.tika.utils.StringUtils; import java.text.ParseException; import java.text.SimpleDateFormat; import java.time.*; import java.time.format.DateTimeFormatter; import java.util.*; /** * 日期时间工具类 * * @author Ryan * @createTime 2018-07-19 10:42:00 */ public class DateUtils extends org.apache.commons.lang3.time.DateUtils { public final static String YYYYMMDDHHMMSS_PATTER = "yyyyMMddHHmmss"; public final static String YYYYMMDDHHMMSS_PATTER_HB = "YYYY-MM-dd HH:mm:ss.SSS"; public final static String YYYYMMDDHHMMSS_PATTER_HB1 = "YYYY-MM-dd HH:mm:ss.000"; public static String datetimeFormat = "yyyy-MM-dd HH:mm:ss"; public final static String[] parsePatterns = { "yyyy-MM-dd", "yyyy-MM-dd HH:mm:ss", "yyyy-MM-dd HH:mm", "yyyy-MM-dd", "yyyy-MM", "yyyy/MM/dd", "yyyy/MM/dd HH:mm:ss", "yyyy/MM/dd HH:mm", "yyyy/MM/dd", "yyyy/MM", "yyyy.MM.dd", "yyyy.MM.dd HH:mm:ss", "yyyy.MM.dd HH:mm", "yyyy.MM.dd", "yyyy.MM", "YYYY-MM-dd HH:mm:ss.SSS"}; public static Date now() { return Calendar.getInstance().getTime(); } /** * 仅显示年月日,例如 2021-08-11. */ public static final String DATE_PATTERN = "yyyy-MM-dd"; /** * 一天的结束时间,仅显示时分秒 */ private static final String END_TIME = "23:59:59"; /** * @Description: 返回 yyyy-MM-dd HH:mm:ss */ public static String nowDate() { return getDate(new Date()); } /** * 将日期字符串转换为日期类型 * * @param pattern 日期字符串格式 不传则为 yyyy-MM-dd * @return * @throws ParseException */ public static Date nowDate(String pattern) throws ParseException { if (StringUtils.isBlank(pattern)) { pattern = "yyyy-MM-dd"; } //设置日期格式 SimpleDateFormat df = new SimpleDateFormat(pattern); return df.parse(df.format(new Date())); } /** * 获取指定日期当周星期一的时间 * * @param date * @return */ public static Date getFirstDayOfWeek(Date date) { Calendar calendar = Calendar.getInstance(); calendar.setTime(date); //获取本周第一天 calendar.set(Calendar.WEEK_OF_YEAR, calendar.get(Calendar.WEEK_OF_YEAR)); int dayOfWeek = 0; if (calendar.get(Calendar.DAY_OF_WEEK) == 1) { dayOfWeek = -6; } else { dayOfWeek = 2 - calendar.get(Calendar.DAY_OF_WEEK); } calendar.add(Calendar.DAY_OF_WEEK, dayOfWeek); return calendar.getTime(); } public static Date getFirstDayOfWeekT(Date date) { Calendar calendar = Calendar.getInstance(); calendar.setTime(date); //获取本周第一天 calendar.set(Calendar.WEEK_OF_YEAR, calendar.get(Calendar.WEEK_OF_YEAR)); int dayOfWeek = 0; if (calendar.get(Calendar.DAY_OF_WEEK) == 1) { dayOfWeek = -6; } else { dayOfWeek = 2 - calendar.get(Calendar.DAY_OF_WEEK); } calendar.add(Calendar.DAY_OF_WEEK, dayOfWeek); //设置日期格式 SimpleDateFormat df = new SimpleDateFormat(DATE_PATTERN); try { return df.parse(df.format(calendar.getTime())); } catch (ParseException e) { e.printStackTrace(); } return null; } /** * 获取指定日期当周星期日的时间 * * @param date * @return */ public static Date getLastDayOfWeek(Date date) { Calendar calendar = Calendar.getInstance(); calendar.setFirstDayOfWeek(Calendar.MONDAY); calendar.setTime(date); // Sunday calendar.set(Calendar.DAY_OF_WEEK, calendar.getFirstDayOfWeek() + 6); return calendar.getTime(); } /** * 获取指定日期当月第一天的时间 * * @param date * @return */ public static Date getFirstDayOfMonth(Date date) { Calendar calendar = Calendar.getInstance(); calendar.setTime(date); calendar.add(Calendar.MONTH, 0); calendar.set(Calendar.DAY_OF_MONTH, 1); return calendar.getTime(); } /** * 获取指定日期当月最后一天的时间 * * @param date * @return */ public static Date getLastDayOfMonth(Date date) { Calendar calendar = Calendar.getInstance(); calendar.setTime(date); calendar.add(Calendar.MONTH, 0); calendar.set(Calendar.DAY_OF_MONTH, calendar.getActualMaximum(Calendar.DAY_OF_MONTH)); return calendar.getTime(); } /** * 获取指定日期当年第一天的时间 * * @param date * @return */ public static Date getFirstDayOfYear(Date date) { Calendar calendar = Calendar.getInstance(); calendar.clear(); calendar.set(Calendar.YEAR, date.getYear() + 1900); return calendar.getTime(); } /** * 获取指定日期当年最后一天的时间 * * @param date * @return */ public static Date getLastDayOfYear(Date date) { Calendar calendar = Calendar.getInstance(); calendar.clear(); calendar.set(Calendar.YEAR, date.getYear() + 1900); calendar.roll(Calendar.DAY_OF_YEAR, -1); return calendar.getTime(); } /** * 获取两个日期相隔的天数 * * @param startDate * @param endDate * @return */ public static float getDateDiffOfDays(Date startDate, Date endDate) { long diff = endDate.getTime() - startDate.getTime(); return diff / (24 * 60 * 60 * 1000); } /** * 获取每天工作小时数。例如:早上9点上班,下午6点下班,休息一个小时,工作时间为8 * * @param startTime 开始时间,格式:HHmm。例如早上7点半,使用0730表示 * @param endTime 结束时间,格式:HHmm。例如下午6点半,使用1830表示 * @param restHours 休息时间 * @return */ public static float getWorkHours(String startTime, String endTime, float restHours) { Date m = new Date(); m.setHours(Integer.parseInt(startTime.substring(0, 2)) - 1); m.setMinutes(Integer.parseInt(startTime.substring(2))); Date a = new Date(); a.setHours(Integer.parseInt(endTime.substring(0, 2)) - 1); a.setMinutes(Integer.parseInt(endTime.substring(2))); return (a.getTime() - m.getTime()) / (1000 * 60 * 60 * 1.0f) - restHours; } /** * 将日期字符串转换为日期类型 * * @param dateStr 日期字符串 * @param pattern 日期字符串格式 * @return * @throws ParseException */ public static Date parse(String dateStr, String pattern) throws ParseException { if (StringUtils.isBlank(dateStr)) { return null; } SimpleDateFormat dateFormat = new SimpleDateFormat(pattern); return dateFormat.parse(dateStr); } /** * 日期型字符串转化为日期 格式 * { "yyyy-MM-dd", "yyyy-MM-dd HH:mm:ss", "yyyy-MM-dd HH:mm", * "yyyy/MM/dd", "yyyy/MM/dd HH:mm:ss", "yyyy/MM/dd HH:mm", * "yyyy.MM.dd", "yyyy.MM.dd HH:mm:ss", "yyyy.MM.dd HH:mm" } */ public static Date parse(String str) { if (str == null) { return null; } try { return parseDate(str, parsePatterns); } catch (ParseException e) { return null; } } public static String formatToAnotherPattern(String dateStr, String pattern, String anotherPatter) throws ParseException { SimpleDateFormat dateFormat = new SimpleDateFormat(pattern); Date date = dateFormat.parse(dateStr); dateFormat = new SimpleDateFormat(anotherPatter); return dateFormat.format(date); } /** * 获取日期时间字符串 * * @param date 需要转化的日期时间 * @return String 日期时间字符串,例如 2015-08-11 */ public static String format(Date date) { return format(date, DATE_PATTERN); } public static String format(Date date, String pattern) { if (date == null) { return ""; } SimpleDateFormat dateFormat = new SimpleDateFormat(pattern); return dateFormat.format(date); } public static Date addHours(Date date, int amount) { return add(date, Calendar.HOUR_OF_DAY, amount); } public static Date addDays(Date date, int amount) { return add(date, Calendar.DAY_OF_MONTH, amount); } public static Date addYear(Date date, int amount) { return add(date, Calendar.YEAR, amount); } public static Date addMonth(Date date, int amount) { return add(date, Calendar.MONTH, amount); } private static Date add(Date date, int calendarField, int amount) { Calendar c = Calendar.getInstance(); c.setTime(date); c.add(calendarField, amount); return c.getTime(); } /** * 将毫秒格式化,如果大于60秒,返回 1分xx秒,大于60分钟,返回 1小时xx分xx秒 * * @param ms 毫秒 * @return */ public static String formatTime(long ms) { if (ms < 1000) { //毫秒 return ms + "毫秒"; } else if (ms / 1000 < 60) { // 小于60秒,以秒显示 return ms / 1000 + "秒"; } else if (ms / 1000 / 60 < 60) { // 小于60分,以分显示 return ms / 1000 / 60 + "分" + (ms / 1000 % 60) + "秒"; } else if (ms / 1000 / 60 / 60 < 24) { // 小于24小时 return (ms / 1000 / 60 / 60) + "时" + (ms / 1000 % 60) + "分" + (ms / 1000 / 60 % 60) + "秒"; } else { return (ms / 1000 / 60 / 60 / 24) + "天" + (ms / 1000 / 60 / 60) + "时" + (ms / 1000 % 60) + "分" + (ms / 1000 / 60 % 60) + "秒"; } } public static Date dateToISODate(Date date) { //T代表后面跟着时间,Z代表UTC统一时间 SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSS'Z'"); format.setCalendar(new GregorianCalendar(new SimpleTimeZone(0, "GMT"))); String isoDate = format.format(date); try { return format.parse(isoDate); } catch (ParseException e) { e.printStackTrace(); } return null; } public static Date localDateTime2Date(LocalDateTime localDateTime) { ZoneId zoneId = ZoneId.systemDefault(); //Combines this date-time with a time-zone to create a ZonedDateTime. ZonedDateTime zdt = localDateTime.atZone(zoneId); //Tue Mar 27 14:17:17 CST 2018 return Date.from(zdt.toInstant()); } public static String localDateTimeToString(LocalDateTime localDateTime) { DateTimeFormatter fmt = DateTimeFormatter.ofPattern(datetimeFormat); return fmt.format(localDateTime); } public static LocalDateTime stringToLocalDateTime(String str) { DateTimeFormatter fmt = DateTimeFormatter.ofPattern(datetimeFormat); return LocalDateTime.parse(str, fmt); } public static LocalDateTime stringToLocalDateTime(String str, String fmtStr) { DateTimeFormatter fmt = DateTimeFormatter.ofPattern(fmtStr); return LocalDateTime.parse(str, fmt); } /** * Date转LocalDateTime * * @param date Date * @return LocalDateTime */ public static LocalDateTime dateToLocalDateTime(Date date) { try { Instant instant = date.toInstant(); ZoneId zoneId = ZoneId.systemDefault(); return instant.atZone(zoneId).toLocalDateTime(); } catch (Exception e) { e.printStackTrace(); } return null; } /** * @Description:获取当前日期 yyyy-MM-dd HH:mm:ss * @Author wyt * @Date 2020/8/21 */ public static String getDate(Date date) { SimpleDateFormat sdf = new SimpleDateFormat(datetimeFormat); return sdf.format(date); } public static String getDate(Date date, String format) { SimpleDateFormat sdf = new SimpleDateFormat(format); return sdf.format(date); } /** * @Description: 判断是否是合法日期格式 * @Author wyt * @Date 2021/2/24 */ public static boolean isValidDate(String str, String fmt) { if (StringUtils.isBlank(str)) { return false; } boolean convertSuccess = true; // 指定日期格式为四位年/两位月份/两位日期,注意yyyy/MM/dd区分大小写; SimpleDateFormat format = new SimpleDateFormat(fmt); try { // 设置lenient为false. 否则SimpleDateFormat会比较宽松地验证日期,比如2007/02/29会被接受,并转换成2007/03/01 format.setLenient(false); Date date = format.parse(str); long time = date.getTime(); if (time < 14400) { convertSuccess = false; } } catch (ParseException e) { // e.printStackTrace(); // 如果throw java.text.ParseException或者NullPointerException,就说明格式不对 convertSuccess = false; } return convertSuccess; } /** * 计算两个日期相差的秒数 * * @param startDate * @param endDate * @return */ public static int calLastedTime(Date startDate, Date endDate) { long a = endDate.getTime(); long b = startDate.getTime(); int c = (int) ((a - b) / 1000); return c; } /** * 获取本月的第一天 * * @return Calendar 日历 */ public static Calendar getStartDayOfMonth(Date date) { Calendar calendar = Calendar.getInstance(Locale.CHINA); calendar.setTime(date); calendar.set(Calendar.DAY_OF_MONTH, 1); calendar.set(Calendar.HOUR_OF_DAY, 0); calendar.set(Calendar.MINUTE, 0); calendar.set(Calendar.SECOND, 0); return calendar; } /** * 根据日历返回日期时间字符串 * * @param calendar 日历 * @return String 日期时间字符串 */ public static String getDateTimeStr(Calendar calendar) { StringBuffer buf = new StringBuffer(""); buf.append(calendar.get(Calendar.YEAR)); buf.append("-"); buf.append(calendar.get(Calendar.MONTH) + 1 > 9 ? calendar.get(Calendar.MONTH) + 1 + "" : "0" + (calendar.get(Calendar.MONTH) + 1)); buf.append("-"); buf.append(calendar.get(Calendar.DAY_OF_MONTH) > 9 ? calendar.get(Calendar.DAY_OF_MONTH) + "" : "0" + calendar.get(Calendar.DAY_OF_MONTH)); buf.append(" "); buf.append(calendar.get(Calendar.HOUR_OF_DAY) > 9 ? calendar.get(Calendar.HOUR_OF_DAY) + "" : "0" + calendar.get(Calendar.HOUR_OF_DAY)); buf.append(":"); buf.append(calendar.get(Calendar.MINUTE) > 9 ? calendar.get(Calendar.MINUTE) + "" : "0" + calendar.get(Calendar.MINUTE)); buf.append(":"); buf.append(calendar.get(Calendar.SECOND) > 9 ? calendar.get(Calendar.SECOND) + "" : "0" + calendar.get(Calendar.SECOND)); return buf.toString(); } /** * 获取指定日期当月第一天的日期字符串 * * @param date 指定日期 * @return String 格式:yyyy-MM-dd HH:mm:ss */ public static String getMonthStartTimeStr(Date date) { return getDateTimeStr(getStartDayOfMonth(date)); } /** * 获得指定日期所在日的结束时间字符串 * * @param date 指定日期 * @return String 例如:2021-08-11 23:59:59 */ public static String getDateEndTimeStr(Date date) { String result = format(date, DATE_PATTERN); return result.concat(" ").concat(END_TIME); } /** * 时间戳转日期 * * @param msStr 时间戳 * @return 不为空:yyyy-MM-dd HH:mm:ss格式日期,为空:返回null */ public static String transForDate(String msStr) { if (StringUtils.isBlank(msStr)) { return null; } long msl = Long.parseLong(msStr); SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); return sdf.format(msl); } /** * 判断是否是时间戳 * * @param msStr 时间戳 * @return 不为空,并且是时间戳格式,返回true */ public static boolean isTimeStamp(String msStr) { if (StringUtils.isBlank(msStr)) { return false; } boolean is = false; try { if (transForDate(msStr) != null) { is = true; } } catch (Exception e) { e.printStackTrace(); } return is; } /** * 如果endDate>startDate,返回true,否则返回false * * @param startDate 开始日期字符串 * @param endDate 结束日期字符串 * @return boolean */ public static boolean compareDate(Date startDate, Date endDate) { String startDateStr = format(startDate, DATE_PATTERN); String endDateStr = format(endDate, DATE_PATTERN); return compareDate(startDateStr, endDateStr); } /** * @param thisDate – 当前日期 * @param otherDate – 比较日期 * @Description:把时间格式化到秒级继续比较 yyyy-MM-dd HH:mm:ss * 如果thisDate>otherDate,返回 1, * thisDate=otherDate, 返回 0, * thisDate