package com.finance.common.utils; import cn.hutool.core.convert.NumberChineseFormatter; import cn.hutool.core.date.DateUtil; import java.lang.management.ManagementFactory; import java.text.ParseException; import java.text.SimpleDateFormat; import java.time.Instant; import java.time.LocalDate; import java.time.LocalDateTime; import java.time.LocalTime; import java.time.ZoneId; import java.time.ZonedDateTime; import java.time.format.DateTimeFormatter; import java.util.Calendar; import java.util.Date; import java.util.HashMap; import java.util.Map; import org.apache.commons.lang3.time.DateFormatUtils; /** * 时间工具类 * * @author ruoyi */ public class DateUtils extends org.apache.commons.lang3.time.DateUtils { public static String YYYY = "yyyy"; public static String YYYY_MM = "yyyy-MM"; public static String YYYY_MM_DD = "yyyy-MM-dd"; public static String YYYYMMDDHHMMSS = "yyyyMMddHHmmss"; public static String YYYY_MM_DD_HH_MM_SS = "yyyy-MM-dd HH:mm:ss"; private static String[] parsePatterns = { "yyyy-MM-dd", "yyyy-MM-dd HH:mm:ss", "yyyy-MM-dd HH:mm", "yyyy-MM", "yyyy/MM/dd", "yyyy/MM/dd HH:mm:ss", "yyyy/MM/dd HH:mm", "yyyy/MM", "yyyy.MM.dd", "yyyy.MM.dd HH:mm:ss", "yyyy.MM.dd HH:mm", "yyyy.MM"}; /** * 获取当前Date型日期 * * @return Date() 当前日期 */ public static Date getNowDate() { return new Date(); } /** * 获取当前日期, 默认格式为yyyy-MM-dd * * @return String */ public static String getDate() { return dateTimeNow(YYYY_MM_DD); } public static final String getTime() { return dateTimeNow(YYYY_MM_DD_HH_MM_SS); } public static final String dateTimeNow() { return dateTimeNow(YYYYMMDDHHMMSS); } public static final String dateTimeNow(final String format) { return parseDateToStr(format, new Date()); } public static final String dateTime(final Date date) { return parseDateToStr(YYYY_MM_DD, date); } public static final String parseDateToStr(final String format, final Date date) { return new SimpleDateFormat(format).format(date); } public static final Date dateTime(final String format, final String ts) { try { return new SimpleDateFormat(format).parse(ts); } catch (ParseException e) { throw new RuntimeException(e); } } /** * 日期路径 即年/月/日 如2018/08/08 */ public static final String datePath() { Date now = new Date(); return DateFormatUtils.format(now, "yyyy/MM/dd"); } /** * 日期路径 即年/月/日 如20180808 */ public static final String dateTime() { Date now = new Date(); return DateFormatUtils.format(now, "yyyyMMdd"); } /** * 日期型字符串转化为日期 格式 */ public static Date parseDate(Object str) { if (str == null) { return null; } try { return parseDate(str.toString(), parsePatterns); } catch (ParseException e) { return null; } } /** * 获取服务器启动时间 */ public static Date getServerStartDate() { long time = ManagementFactory.getRuntimeMXBean().getStartTime(); return new Date(time); } /** * 计算相差天数 */ public static int differentDaysByMillisecond(Date date1, Date date2) { return Math.abs((int) ((date2.getTime() - date1.getTime()) / (1000 * 3600 * 24))); } /** * 计算时间差 * * @param endDate 最后时间 * @param startTime 开始时间 * @return 时间差(天/小时/分钟) */ public static String timeDistance(Date endDate, Date startTime) { long nd = 1000 * 24 * 60 * 60; long nh = 1000 * 60 * 60; long nm = 1000 * 60; // long ns = 1000; // 获得两个时间的毫秒时间差异 long diff = endDate.getTime() - startTime.getTime(); // 计算差多少天 long day = diff / nd; // 计算差多少小时 long hour = diff % nd / nh; // 计算差多少分钟 long min = diff % nd % nh / nm; // 计算差多少秒//输出结果 // long sec = diff % nd % nh % nm / ns; return day + "天" + hour + "小时" + min + "分钟"; } /** * 增加 LocalDateTime ==> Date */ public static Date toDate(LocalDateTime temporalAccessor) { ZonedDateTime zdt = temporalAccessor.atZone(ZoneId.systemDefault()); return Date.from(zdt.toInstant()); } /** * 增加 LocalDate ==> Date */ public static Date toDate(LocalDate temporalAccessor) { LocalDateTime localDateTime = LocalDateTime.of(temporalAccessor, LocalTime.of(0, 0, 0)); ZonedDateTime zdt = localDateTime.atZone(ZoneId.systemDefault()); return Date.from(zdt.toInstant()); } /** * 指定日期所在周的周一和周日时间 * * @return 结果集 */ public static Map getWeekDate(Date date) { Map map = new HashMap<>(2); Calendar cal = Calendar.getInstance(); cal.setTime(date); // 设置一个星期的第一天,按中国的习惯一个星期的第一天是星期一 cal.setFirstDayOfWeek(Calendar.MONDAY); // 获得当前日期是一个星期的第几天 int dayWeek = cal.get(Calendar.DAY_OF_WEEK); if (dayWeek == 1) { dayWeek = 8; } // 根据日历的规则,给当前日期减去星期几与一个星期第一天的差值 cal.add(Calendar.DATE, cal.getFirstDayOfWeek() - dayWeek); Date mondayDate = cal.getTime(); cal.add(Calendar.DATE, 4 + cal.getFirstDayOfWeek()); Date sundayDate = cal.getTime(); map.put("first", mondayDate); map.put("last", sundayDate); return map; } /** * 指定日期所在月的第一天/最后一天时间 * * @return 结果集 */ public static Map getMonthDate(Date date) { Map map = new HashMap<>(2); Calendar cal = Calendar.getInstance(); // 设置指定日期 cal.setTime(date); // 获取当月第一天日期 int first = cal.getActualMinimum(Calendar.DAY_OF_MONTH); cal.set(Calendar.DAY_OF_MONTH, first); Date firstDay = cal.getTime(); map.put("first", firstDay); // 获取当月最后一天日期 int last = cal.getActualMaximum(Calendar.DAY_OF_MONTH); cal.set(Calendar.DAY_OF_MONTH, last); Date lastDay = cal.getTime(); map.put("last", lastDay); return map; } /** * 获取日期逻辑中所在的季度数 * * @param date 当前日期 * @return 第几季度 */ public static int getQuarterOfYear(Date date) { Calendar calendar = Calendar.getInstance(); calendar.setTime(date); return calendar.get(Calendar.MONTH) / 3 + 1; } /** * 指定日期所在季度的第一天/最后一天时间 * * @return 结果集 */ public static Map getQuarterDate(Date date) { Map map = new HashMap<>(2); int quarter = getQuarterOfYear(date); int year = dateToLocalDateTime(date).getYear(); int startMonth = (quarter - 1) * 3; // 根据月获取开始时间 Calendar cal = Calendar.getInstance(); cal.set(Calendar.YEAR, year); cal.set(Calendar.MONTH, startMonth); cal.set(Calendar.DAY_OF_MONTH, 1); cal.set(Calendar.HOUR, 0); cal.set(Calendar.MINUTE, 0); cal.set(Calendar.SECOND, 0); Date first = cal.getTime(); map.put("first", first); int lastMonth = quarter * 3 - 1; // 根据月获取结束时间 cal = Calendar.getInstance(); cal.set(Calendar.YEAR, year); cal.set(Calendar.MONTH, lastMonth); cal.set(Calendar.DAY_OF_MONTH, cal.getActualMaximum(Calendar.DAY_OF_MONTH)); cal.set(Calendar.HOUR, 0); cal.set(Calendar.MINUTE, 0); cal.set(Calendar.SECOND, 0); Date last = cal.getTime(); map.put("last", last); return map; } /** * 指定日期所在年的第一天/最后一天时间 * * @return 结果集 */ public static Map getYearDate(Date date) { Map map = new HashMap<>(2); Calendar cal = Calendar.getInstance(); // 设置指定日期 cal.setTime(date); // 获取本年第一天日期 int first = cal.getActualMinimum(Calendar.DAY_OF_YEAR); cal.set(Calendar.DAY_OF_YEAR, first); Date firstDay = cal.getTime(); map.put("first", firstDay); // 获取本年最后一天日期 int last = cal.getActualMaximum(Calendar.DAY_OF_YEAR); cal.set(Calendar.DAY_OF_YEAR, last); Date lastDay = cal.getTime(); map.put("last", lastDay); return map; } /** * 获取当天的00:00:00 * * @return */ public static LocalDateTime getDayStart(LocalDateTime time) { return time.with(LocalTime.MIN); } /** * 获取当天的23:59:59 * * @return */ public static LocalDateTime getDayEnd(LocalDateTime time) { return time.with(LocalTime.MAX); } /** * localdatetime转为字符串 * * @param time localdatetime * @return 字符串 */ public static String localDateTimeToString(LocalDateTime time) { DateTimeFormatter df = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"); return df.format(time); } /** * Date转为LocalDateTime * * @param date 日期 * @return LocalDateTime */ public static LocalDateTime dateToLocalDateTime(Date date) { Instant instant = date.toInstant(); ZoneId zoneId = ZoneId.systemDefault(); return instant.atZone(zoneId).toLocalDateTime(); } /** * Date转为LocalDateTime * * @param date 日期 * @return LocalDateTime */ public static LocalDate dateToLocalDate(Date date) { Instant instant = date.toInstant(); ZoneId zoneId = ZoneId.systemDefault(); return instant.atZone(zoneId).toLocalDate(); } /** * localdate转为字符串 * * @param time localdate * @return 字符串 */ public static String localDateToString(LocalDate time) { DateTimeFormatter df = DateTimeFormatter.ofPattern("yyyy-MM-dd"); return df.format(time); } /** * 字符串转为localdate * * @param time localdate * @return 字符串 */ public static LocalDate stringToLocalDate(String time) { return LocalDate.parse(time, DateTimeFormatter.ofPattern("yyyy-MM-dd")); } /** * 获取当前季度字符串 * * @return 当前季度字符串 * @throws Exception 异常 */ public static String getNowQuarter() throws Exception { // 当前所在季度 Date date = new Date(); // char quarterOfYear = String.valueOf(getQuarterOfYear(date)).toCharArray()[0]; int quarterOfYear = DateUtil.quarter(date); String quarterOfYearStr = NumberChineseFormatter.numberCharToChinese((char) quarterOfYear, false); LocalDate now = LocalDate.now(); return String.format("%s年%s季度", now.getYear(), quarterOfYearStr); } /** * 获取上一季度字符串 * * @return 当前季度字符串 * @throws Exception 异常 */ public static String getPreviousQuarter() throws Exception { // 当前日期 LocalDate now = LocalDate.now(); // 当前月份 int currentMonth = now.getMonthValue(); // 计算上季度的月份 int previousQuarterMonth = currentMonth - 3; int previousQuarterYear = now.getYear(); if (previousQuarterMonth <= 0) { previousQuarterMonth += 12; previousQuarterYear -= 1; } // 计算上季度的季度数 int previousQuarter = (previousQuarterMonth - 1) / 3 + 1; // 将季度数转换为汉字 String quarterOfYearStr = NumberChineseFormatter.numberCharToChinese( (char) (previousQuarter + '0'), false); // 返回上季度的年份和季度 return String.format("%s年%s季度", previousQuarterYear, quarterOfYearStr); } public static Date getQuarterDate(String quarter) { // 提取年份和季度信息 int year = Integer.parseInt(quarter.substring(0, 4)); int quarterNumber = NumberChineseFormatter.chineseToNumber(quarter.substring(5, 6)); // 季度数字 // 计算季度初的日期 LocalDate startDate; switch (quarterNumber) { case 1: startDate = LocalDate.of(year, 1, 1); break; case 2: startDate = LocalDate.of(year, 4, 1); break; case 3: startDate = LocalDate.of(year, 7, 1); break; case 4: startDate = LocalDate.of(year, 10, 1); break; default: throw new IllegalArgumentException("Invalid quarter number: " + quarterNumber); } return DateUtils.toDate(startDate); } public static Date getQuarterDateEnd(String quarter) { // 提取年份和季度信息 int year = Integer.parseInt(quarter.substring(0, 4)); int quarterNumber = NumberChineseFormatter.chineseToNumber(quarter.substring(5, 6)); // 季度数字 // 计算季度初的日期 LocalDate startDate; switch (quarterNumber) { case 1: startDate = LocalDate.of(year, 3, 1); break; case 2: startDate = LocalDate.of(year, 6, 1); break; case 3: startDate = LocalDate.of(year, 9, 1); break; case 4: startDate = LocalDate.of(year, 12, 1); break; default: throw new IllegalArgumentException("Invalid quarter number: " + quarterNumber); } return DateUtils.toDate(startDate); } // 测试 getNowQuarter public static void main(String[] args) throws Exception { SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); String nowQuarter = getNowQuarter(); System.out.println(nowQuarter); System.out.println(NumberChineseFormatter.chineseToNumber("一")); System.out.println(simpleDateFormat.format(getQuarterDateEnd("2024年一季度"))); String month = DateUtil.format(getQuarterDateEnd("2024年一季度"), "MM"); System.out.println(Double.parseDouble(month)); System.out.println(simpleDateFormat.format(getQuarterDate("2024年二季度"))); System.out.println(simpleDateFormat.format(getQuarterDate("2024年四季度"))); System.out.println(simpleDateFormat.format(getQuarterDate("2024年四季度"))); System.out.println( DateUtil.format(getQuarterDateEnd(getPreviousQuarter()), "yyyy-MM-dd HH:mm:ss")); System.out.println( DateUtil.format(getQuarterDate(getPreviousQuarter()), "yyyy-MM-dd HH:mm:ss")); System.out.println(getLastYearQuarter("2024年四季度")); } public static String getLastYearQuarter(String previousQuarter) { // 提取年份和季度信息 String year = previousQuarter.substring(0, 4); SimpleDateFormat sdf = new SimpleDateFormat("yyyy"); try { // 今年 Date date = sdf.parse(year); // 根据date获取去年的日期 Calendar calendar = Calendar.getInstance(); calendar.setTime(date); calendar.add(Calendar.YEAR, -1); Date lastYear = calendar.getTime(); return String.format("%s年%s", sdf.format(lastYear), previousQuarter.substring(5)); } catch (ParseException e) { throw new RuntimeException(e); } } }