package nckd.pur.scp.common; import kd.bos.dataentity.entity.DynamicObject; import kd.bos.dataentity.utils.ObjectUtils; import kd.bos.entity.EntityMetadataCache; import kd.bos.exception.ErrorCode; import kd.bos.exception.KDBizException; import kd.bos.exception.KDException; import kd.bos.orm.query.QFilter; import kd.bos.servicehelper.BusinessDataServiceHelper; import kd.bos.util.StringUtils; import java.text.ParseException; import java.text.SimpleDateFormat; import java.time.*; import java.time.format.DateTimeFormatter; import java.time.temporal.ChronoUnit; import java.time.temporal.TemporalAdjusters; import java.util.Calendar; import java.util.Date; import java.util.Set; /** * 日期工具类 * * @author xyc * @date 2021/8/4 */ public final class DateUtil { public static final String DATE_FORMAT_YYYY_MM_DD = "yyyy-MM-dd"; public static final String DATE_TIME_FORMAT_YYYY_MM_DD_HH_MI_SS = "yyyy-MM-dd HH:mm:ss"; public static final String DATE_TIME_FORMAT_YYYY_MM_DD_HH_MI_SS_SSS = "yyyyMMddHHmmssSSS"; public static final String DATE_FORMAT_YYYYMM = "yyyyMM"; public static final String DATE_FORMAT_YYYYMMDD = "yyyyMMdd"; public static final ZoneId UTC_PLUS_8 = ZoneId.systemDefault(); private DateUtil() { } public static boolean isCurrentDateInRange(Date startDate, Date endDate) { Date currentDate = new Date(); return isDateInRange(currentDate, startDate, endDate); } public static boolean isDateInRange(Date targetDate, Date startDate, Date endDate) { return !targetDate.before(startDate) && !targetDate.after(endDate); } /** * 日期转字符串 * * @param date 指定日期 * @param pattern 格式 * @return 返回String格式 ( yyyy-MM-dd HH:mm:ss ) */ public static String date2str(Date date, String pattern) { if (null == date) { return null; } SimpleDateFormat format = null; if (StringUtils.isNotEmpty(pattern)) { format = new SimpleDateFormat(pattern); } else { format = new SimpleDateFormat(DATE_TIME_FORMAT_YYYY_MM_DD_HH_MI_SS); } return format.format(date); } /** * 获取当前时间字符串 * * @param pattern 格式 * @return String */ public static String getCurrentDateTimeStr(String pattern) { return date2str(new Date(), pattern); } /** * 字符串转日期 * * @param str 指定日期 * @param pattern 格式 * @return date */ public static Date string2date(String str, String pattern) { SimpleDateFormat format = null; if (StringUtils.isNotEmpty(pattern)) { format = new SimpleDateFormat(pattern); } else { format = new SimpleDateFormat(DATE_TIME_FORMAT_YYYY_MM_DD_HH_MI_SS); } Date date = null; if (!StringUtils.isEmpty(str)) { try { date = format.parse(str); } catch (ParseException e) { throw new KDException(new ErrorCode("time convert error", "日期%s转换异常"), str); } } return date; } /** * 将指定日期的时分秒格式那天的 00:00:00 的时间 * * @param date 指定日期 * @return date */ public static Date getDateStartTime(Date date) { if (null == date) { return null; } LocalDate localDate = date.toInstant().atZone(UTC_PLUS_8).toLocalDate(); LocalDateTime localDateTime = localDate.atStartOfDay(); return localDateTime2date(localDateTime); } /** * 将指定日期的时分秒格式那天的 23:59:59 的时间 * * @param date 指定日期 * @return date */ public static Date getDateEndTime(Date date) { LocalDate localDate = date.toInstant().atZone(UTC_PLUS_8).toLocalDate(); LocalDateTime localDateTime = localDate.atTime(23, 59, 59); return localDateTime2date(localDateTime); } /** * 获取指定日期当月最后一天的时间 * * @param date 指定日期 * @return 最后一天的时间 (时分秒:23:59:59) */ public static Date getTimeEndOfMonth(Date date) { LocalDate localDate = date.toInstant().atZone(UTC_PLUS_8).toLocalDate(); LocalDateTime localDateTime = localDate.atTime(23, 59, 59).with(TemporalAdjusters.lastDayOfMonth()); return localDateTime2date(localDateTime); } /** * 月结束日期 * * @param date 指定日期 * @return date */ public static Date getDateEndOfMonth(Date date) { LocalDate localDate = date.toInstant().atZone(UTC_PLUS_8).toLocalDate(); localDate = localDate.withDayOfMonth(localDate.lengthOfMonth()); return Date.from(localDate.atStartOfDay().atZone(UTC_PLUS_8).toInstant()); } /** * 获取指定日期当月第一天的时间 * * @param date 指定日期 * @return 第一天的时间 (时分秒:00:00:00) */ public static Date getDateStartOfMonth(Date date) { LocalDate localDate = date.toInstant().atZone(UTC_PLUS_8).toLocalDate(); LocalDateTime localDateTime = localDate.atStartOfDay().with(TemporalAdjusters.firstDayOfMonth()); return localDateTime2date(localDateTime); } /** * 周开始日期 * * @param date 指定日期 * @param isChinaWeek 是否按中国的习惯(一个星期的第一天是星期一) * @return Date */ public static Date getDateStartOfWeek(Date date, boolean isChinaWeek) { LocalDate localDate = date.toInstant().atZone(UTC_PLUS_8).toLocalDate(); int days = localDate.getDayOfWeek().getValue() % 7; if (isChinaWeek) { days = days - 1; } localDate = localDate.minusDays(days); return Date.from(localDate.atStartOfDay().atZone(UTC_PLUS_8).toInstant()); } /** * 周结束日期 * * @param date 指定日期 * @param isChinaWeek 是否按中国的习惯(一个星期的第一天是星期一) * @return Date */ public static Date getDateEndOfWeek(Date date, boolean isChinaWeek) { LocalDate localDate = date.toInstant().atZone(UTC_PLUS_8).toLocalDate(); int days = localDate.getDayOfWeek().getValue() % 7; if (isChinaWeek) { days = days - 1; } localDate = localDate.plusDays(7 - 1 - days); return Date.from(localDate.atStartOfDay().atZone(UTC_PLUS_8).toInstant()); } /** * 获取指定日期当年第一天的时间 * * @param date 指定日期 * @return date */ public static Date getDateStartOfYear(Date date) { LocalDate localDate = date.toInstant().atZone(UTC_PLUS_8).toLocalDate(); localDate = localDate.withMonth(1).withDayOfMonth(1); return Date.from(localDate.atStartOfDay().atZone(UTC_PLUS_8).toInstant()); } /** * 获取指定日期当年最后一天的时间 * * @param date 指定日期 * @return date */ public static Date getDateEndOfYear(Date date) { LocalDate localDate = date.toInstant().atZone(UTC_PLUS_8).toLocalDate(); localDate = localDate.withMonth(12); localDate = localDate.withDayOfMonth(localDate.lengthOfMonth()); return Date.from(localDate.atStartOfDay().atZone(UTC_PLUS_8).toInstant()); } /** * 获取年龄 * * @param birthDate * @param currentDate * @return */ public static int getAge(Date birthDate, Date currentDate) { if (ObjectUtils.isEmpty(birthDate)) { throw new KDBizException("生日不能为空"); } Date date = currentDate; if (ObjectUtils.isEmpty(date)) { date = new Date(); } LocalDate birthLocalDate = date2localDate(birthDate); LocalDate currentLocalDate = date2localDate(date); return (int) birthLocalDate.until(currentLocalDate, ChronoUnit.DAYS); } /** * 获取俩个日期间天数,如果入参为空时返回0 * * @param firstDate 开始时间 * @param secDate 结束时间 * @return 返回俩个日期间天数的绝对值 */ public static int daysBetweenIfBlankReturnZero(Date firstDate, Date secDate) { if (firstDate == null || secDate == null) { return 0; } return daysBetween(firstDate, secDate); } /** * 获取俩个日期间天数 ( 正整数 ) * * @param firstDate 开始时间 * @param secDate 结束时间 * @return 返回俩个日期间天数的绝对值 */ public static int daysBetween(Date firstDate, Date secDate) { LocalDate localDate1 = date2localDate(firstDate); LocalDate localDate2 = date2localDate(secDate); return localDate2.isAfter(localDate1) ? (int) localDate1.until(localDate2, ChronoUnit.DAYS) : (int) localDate2.until(localDate1, ChronoUnit.DAYS); } /** * 获得指定时间加减月数后的日期 * * @param date 指定日期 * @param month 月数,可正可负 * @return 计算后的日期 */ public static Date addMonth(Date date, int month) { LocalDateTime localDateTime = date2localDateTime(date); return localDateTime2date(localDateTime.plusMonths(month)); } /** * 获得指定时间加减星期后的日期 * * @param date 指定日期 * @param week 星期,可正可负 * @return 计算后的日期 */ public static Date addWeek(Date date, int week) { LocalDateTime localDateTime = date2localDateTime(date); return localDateTime2date(localDateTime.plusWeeks(week)); } /** * 获得指定时间第二天的日期 * * @param date 指定时间 * @return 计算后的日期 */ public static Date getNextDay(Date date) { LocalDateTime localDateTime = date2localDateTime(date); return localDateTime2date(localDateTime.plusDays(1L)); } /** * 获得指定时间加减天数后的日期 * * @param date 指定日期 * @param days 天数,可正可负 * @return 计算后的日期 */ public static Date addDay(Date date, int days) { LocalDateTime localDateTime = date2localDateTime(date); return localDateTime2date(localDateTime.plusDays(days)); } /** * 获得指定时间加减小时后的时间 * * @param date 指定日期 * @param hours 小时数,可正可负 * @return 计算后的日期 */ public static Date addHour(Date date, int hours) { LocalDateTime localDateTime = date2localDateTime(date); return localDateTime2date(localDateTime.plusHours(hours)); } /** * 获得指定时间加减小时后的时间 * @param date 指定日期 * @param seconds 秒,可正可负 * @return 计算后的日期 */ public static Date addSecond(Date date, int seconds) { LocalDateTime localDateTime = date2localDateTime(date); return localDateTime2date(localDateTime.plusSeconds(seconds)); } public static String localDateTime2str(LocalDateTime localDateTime, String pattern) { return localDateTime.format(DateTimeFormatter.ofPattern(pattern)); } public static Date localDateTime2date(LocalDateTime localDateTime) { return Date.from(localDateTime.atZone(UTC_PLUS_8).toInstant()); } public static LocalDateTime date2localDateTime(Date date) { return date.toInstant().atZone(UTC_PLUS_8).toLocalDateTime(); } public static LocalDate date2localDate(Date date) { return date.toInstant().atZone(UTC_PLUS_8).toLocalDate(); } /** * 获取某个时间月份的天数 * * @param date 时间 * @return 返回月份的总天数 */ public static int getDaysOfMonth(Date date) { Calendar calendar = Calendar.getInstance(); calendar.setTime(date); return calendar.getActualMaximum(Calendar.DAY_OF_MONTH); } /** * 获取某年某月的天数 * * @param year 年份 * @param month 月份 * @return 返回月份的总天数 */ public static int getDaysOfMonth(int year, int month) { Calendar calendar = Calendar.getInstance(); calendar.set(Calendar.MONTH, month - 1); calendar.set(Calendar.YEAR, year); return calendar.getActualMaximum(Calendar.DAY_OF_MONTH); } public static boolean isSameDay(Date date1, Date date2) { LocalDate localDate1 = date2localDate(date1); LocalDate localDate2 = date2localDate(date2); return localDate1.equals(localDate2); } /** *
描述 : 调整日期时间
*备注 : hours 整数为几个小时后,负数几个小时前
* * @param date * @param hours * @return java.util.Date */ public static Date adjustDateTime(Date date, int hours) { LocalDateTime localDateTime = date.toInstant().atZone(ZoneId.systemDefault()).toLocalDateTime(); if (hours > 0) { localDateTime = localDateTime.plusHours(hours); } else { localDateTime = localDateTime.minusHours(Math.abs(hours)); } return Date.from(localDateTime.atZone(ZoneId.systemDefault()).toInstant()); } /** * @return * @Title 想要获取的日期与传入日期的差值 比如想要获取传入日期前四天的日期 day=-4即可 * @Description * @author hang */ public static Date getSomeDay(Date date, int day) { Calendar calendar = Calendar.getInstance(); calendar.setTime(date); calendar.add(Calendar.DATE, day); return getStartOfDay(calendar.getTime()); } /** * @return * @Title 想要获取几个月前后的日期与传入日期的差值 比如想要获取传入日期前四天的日期 * @Description * @author hang */ public static Date getMonthDiffDay(Date date, int day) { Calendar calendar = Calendar.getInstance(); calendar.setTime(date); calendar.add(Calendar.MONTH, day); return getStartOfDay(calendar.getTime()); } /** * @return * @Title 想要获取几个月前后的日期与传入日期的差值 比如想要获取传入日期前四天的日期 * @Description * @author hang */ public static Date getYearDiffDay(Date date, int day) { Calendar calendar = Calendar.getInstance(); calendar.setTime(date); calendar.add(Calendar.YEAR, day); return getStartOfDay(calendar.getTime()); } /** * @param date * @return * @description: 获得当天最小时间 * @author: jiang * @date: 2021年06月21日 */ public static Date getStartOfDay(Date date) { if( date != null ){ LocalDateTime localDateTime = LocalDateTime.ofInstant(Instant.ofEpochMilli(date.getTime()), ZoneId.systemDefault()); LocalDateTime startOfDay = localDateTime.with(LocalTime.MIN); return Date.from(startOfDay.atZone(ZoneId.systemDefault()).toInstant()); } return null; } /** * @param date * @return * @description: 获得当天最大时间 * @author: Jeff * @date: 2021年06月21日 */ public static Date getEndOfDay(Date date) { LocalDateTime localDateTime = LocalDateTime.ofInstant(Instant.ofEpochMilli(date.getTime()), ZoneId.systemDefault()); LocalDateTime endOfDay = localDateTime.with(LocalTime.MAX); return Date.from(endOfDay.atZone(ZoneId.systemDefault()).toInstant()); } /** * @return * @Title 计算两个日期的天数 * @Description * @author hang */ public static int getDayDiffer(Date startDate, Date endDate) { try { SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd"); long startDateTime = dateFormat.parse(dateFormat.format(startDate)).getTime(); long endDateTime = dateFormat.parse(dateFormat.format(endDate)).getTime(); return (int) ((endDateTime - startDateTime) / (1000 * 3600 * 24)); } catch (ParseException e) { return 0; } } public static Date getMonthFirstDay(Date thisDay, int diff) throws ParseException { //时间字符串转 LocalDate 类型 LocalDate today = thisDay.toInstant().atZone(ZoneId.systemDefault()).toLocalDate(); //当前月份+(-diff) today = today.minusMonths(diff); today = today.with(TemporalAdjusters.firstDayOfMonth()); SimpleDateFormat simple = new SimpleDateFormat("yyyy-MM-dd 00:00:00"); ZonedDateTime zonedDateTime = today.atStartOfDay(ZoneId.systemDefault()); String newday = simple.format(Date.from(zonedDateTime.toInstant())); Date date = simple.parse(newday); return date; } /** * 获取上个月指定第几天的日期(包括跨年) * * @param isEndDay 是否是最后一天 true默认上个月最后一天的日期,dayOfMonth随便传什么,false指定上个月某一天的日期 * @param dayOfMonth 指定要获取的上个月的日期 * @return 获取上个月最后一天的日期(包括跨年) */ public static Date getLastDayOfLastMonth(boolean isEndDay, int dayOfMonth) { // 获取当前日期 LocalDate currentDate = LocalDate.now(); // 获取上个月的年份和月份 int lastMonthYear; int lastMonth; if (currentDate.getMonthValue() == 1) { // 如果当前月份是1月,则上个月的年份为去年,月份为12 lastMonthYear = currentDate.getYear() - 1; lastMonth = 12; } else { // 否则上个月的年份和月份分别为当前年份和当前月份减1 lastMonthYear = currentDate.getYear(); lastMonth = currentDate.getMonthValue() - 1; } // 构造上个月的YearMonth对象 YearMonth lastYearMonth = YearMonth.of(lastMonthYear, lastMonth); LocalDate lastDayOfLastMonth; if (isEndDay) { // 获取上个月的最后一天 lastDayOfLastMonth = lastYearMonth.atEndOfMonth(); } else { lastDayOfLastMonth = lastYearMonth.atDay(dayOfMonth); } return java.sql.Date.valueOf(lastDayOfLastMonth); } /** * 获取指定日期上个月指定第几天的日期(包括跨年) * * @param isEndDay 是否是最后一天 true默认上个月最后一天的日期,dayOfMonth随便传什么,false指定上个月某一天的日期 * @param dayOfMonth 获取指定日期的上个月的日期 * @param date 指定日期 * @return 获取上个月最后一天的日期(包括跨年) */ public static Date getLastDayOfLastMonth(boolean isEndDay, int dayOfMonth, Date date) { LocalDate currentDate = date.toInstant().atZone(UTC_PLUS_8).toLocalDate(); // 获取上个月的年份和月份 int lastMonthYear; int lastMonth; if (currentDate.getMonthValue() == 1) { // 如果当前月份是1月,则上个月的年份为去年,月份为12 lastMonthYear = currentDate.getYear() - 1; lastMonth = 12; } else { // 否则上个月的年份和月份分别为当前年份和当前月份减1 lastMonthYear = currentDate.getYear(); lastMonth = currentDate.getMonthValue() - 1; } // 构造上个月的YearMonth对象 YearMonth lastYearMonth = YearMonth.of(lastMonthYear, lastMonth); LocalDate lastDayOfLastMonth; if (isEndDay) { // 获取上个月的最后一天 lastDayOfLastMonth = lastYearMonth.atEndOfMonth(); } else { lastDayOfLastMonth = lastYearMonth.atDay(dayOfMonth); } return java.sql.Date.valueOf(lastDayOfLastMonth); } /** * 获取当月某天 * * @param day * @return */ public static Date getDayOfMonth(int day) { // 获取当前日期 LocalDate currentDate = LocalDate.now(); // 设置日期为当月的第15天 LocalDate fifteenthDayOfMonth = LocalDate.of(currentDate.getYear(), currentDate.getMonth(), day); return java.sql.Date.valueOf(fifteenthDayOfMonth); } /** * 上个月月份 * * @return 上个月月份 */ public static int getLastMonth() { // 获取当前日期 LocalDate currentDate = LocalDate.now(); // 获取上个月的日期 LocalDate lastMonthDate = currentDate.minusMonths(1); // 获取上个月的月份 int lastMonth = lastMonthDate.getMonthValue(); return lastMonth; } /** * 判断当天是否是多少号 * * @param mark 号 * @return 判断当天是否是多少号 */ public static Boolean isMark(int mark) { Calendar calendar = Calendar.getInstance(); // 获取日期的日 int dayOfMonth = calendar.get(Calendar.DAY_OF_MONTH); // 判断当天是否是多少号 return dayOfMonth == mark; } /** * 指定日期月份第一天 * * @param date 指定日期 * @return 指定日期月份第一天 */ public static Date getFirstDayOfMonth(Date date) { Calendar calendar = Calendar.getInstance(); 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); calendar.set(Calendar.MILLISECOND, 0); return calendar.getTime(); } /** * 指定日期月份最后一天 * * @param date 指定日期 * @return 指定日期月份最后一天 */ public static Date getLastDayOfMonth(Date date) { Calendar calendar = Calendar.getInstance(); calendar.setTime(date); calendar.set(Calendar.DAY_OF_MONTH, calendar.getActualMaximum(Calendar.DAY_OF_MONTH)); calendar.set(Calendar.HOUR_OF_DAY, 23); calendar.set(Calendar.MINUTE, 59); calendar.set(Calendar.SECOND, 59); calendar.set(Calendar.MILLISECOND, 999); return calendar.getTime(); } /** * @param yearMonth 年月 2024-01 * @return 获取月份天数 */ public static int getDaysInMonth(String yearMonth) { YearMonth ym = YearMonth.parse(yearMonth); Month month = ym.getMonth(); if (month == Month.FEBRUARY && ym.isLeapYear()) { return 29; } else { return month.maxLength(); } } public static DynamicObject getPeriodByDate(Date date) { QFilter filter = new QFilter("begindate", "<=", date).and("enddate", ">=", date); return BusinessDataServiceHelper.loadSingle("bd_period", filter.toArray()); } public static String convertTimestamp(long timestamp) { // 转换为秒 long totalSeconds = timestamp; // 计算小时 long hours = totalSeconds / 3600; // 计算分钟 long minutes = (totalSeconds % 3600) / 60; // 计算秒 long seconds = totalSeconds % 60; return String.format("%02d:%02d:%02d", hours, minutes, seconds); } /** * 取最大值 * @param d1 d1 * @param d2 d2 * @return 最大值 */ public static Date max(Date d1, Date d2) { if (d1 == null) { return d2; } if (d2 == null) { return d1; } if (d1.after(d2)) { return d1; }else { return d2; } } /** * 取最小值 * @param d1 d1 * @param d2 d2 * @return 最小值 */ public static Date min(Date d1, Date d2) { if (d1 == null) { return d2; } if (d2 == null) { return d1; } if (d1.before(d2)) { return d1; }else { return d2; } } }