项目由于在数据库设计层面,作了强制要求使用时间戳类型的日期类型,以便于不同国产数据库,mysql数据库之前保持良好的日期格式兼容性(不同的日期格式迁移很痛苦),以及在不同终端展示的日期格式有较好的弹性(后台返回long即可,不考虑转换问题)。同时,也带来了不小的缺点。较典型的就是日期区间查询问题。本工具类的大部分方法都是基于此背景而建。因此看起来怪怪的。
public class DateHelper {/*** 设置日期查询区间** @param wrapper 条件* @param dateFun 条件字段函数* @param startTime 开始日期* @param endTime 结束日期* @param <T> 条件*/public static <T> void setStartEndTime(LambdaQueryWrapper<T> wrapper, SFunction<T, Long> dateFun, Long startTime, Long endTime) {if (null == startTime && null == endTime) {return;}if (null != startTime && null == endTime) {startTime = getStartTimeOfCurrentDay(new Date(startTime)).getTime();endTime = System.currentTimeMillis();} else if (null == startTime) {startTime = 0L;endTime = getEndTimeOfCurrentDay(new Date(endTime)).getTime();} else {startTime = getStartTimeOfCurrentDay(new Date(startTime)).getTime();endTime = getEndTimeOfCurrentDay(new Date(endTime)).getTime();}wrapper.between(dateFun, startTime, endTime);}/*** 设置本年份查询条区** @param wrapper 条件* @param dateFun 年份日期字段函数* @param <T> 条件*/public static <T> void setYearDateWrapper(LambdaQueryWrapper<T> wrapper, SFunction<T, Long> dateFun) {setYearDateWrapper(wrapper, getNowYear(), dateFun);}/*** 设置年份查询条区** @param wrapper 条件* @param year 年* @param dateFun 年份日期字段函数* @param <T> 条件*/public static <T> void setYearDateWrapper(LambdaQueryWrapper<T> wrapper, Integer year, SFunction<T, Long> dateFun) {if (null == year) {return;}Date startDate = getFirstDayOfYearMonth(year, 1);Date endDate = getLastDayOfYearMonth(year, 12);wrapper.between(dateFun, startDate.getTime(), endDate.getTime());}/*** 设置日期状态查询条件** @param lambdaQuery 条件* @param status 状态* @param startFun 开始时间* @param endFun 结束时间* @param <T> 条件*/public static <T> void toSetDateStatus(LambdaQueryWrapper<T> lambdaQuery, Integer status, SFunction<T, Long> startFun, SFunction<T, Long> endFun) {if (null == status) {return;}long now = System.currentTimeMillis();if (status == GlobalConstant.NO_START) {// 未开始-->开始时间大于当前时间lambdaQuery.gt(startFun, now);} else if (status == GlobalConstant.IS_GOING) {// 进行中-->开始时间小于等于当前时间,结束时间大于当前时间lambdaQuery.le(startFun, now);lambdaQuery.gt(endFun, now);} else if (status == GlobalConstant.IS_END) {// 已结束-->结束时间小于等于当前时间lambdaQuery.le(endFun, now);} else {// 已结束-->结束时间小于等于当前时间lambdaQuery.ge(endFun, now);}}/*** 判断目标时间是否在当前时间之后** @param time 目标时间* @return 是否之后*/public static boolean isAfter(Long time) {return isAfter(time, System.currentTimeMillis());}/*** 判断目标时间是否在当前时间之前** @param time 目标时间* @return 是否之前*/public static boolean isBefore(Long time) {return isBefore(time, System.currentTimeMillis());}/*** 判断目标时间是否在某时间之后** @param time 某时间* @param targetTime 目标时间* @return 是否之后*/public static boolean isAfter(Long time, Long targetTime) {if (null == time || null == targetTime) {return false;}long now = System.currentTimeMillis();return time > targetTime;}/*** 判断目标时间是否在某时间之前** @param time 某时间* @param targetTime 目标时间* @return 是否之前*/public static boolean isBefore(Long time, Long targetTime) {if (null == time || null == targetTime) {return false;}long now = System.currentTimeMillis();return time <= targetTime;}/*** 匹配开始-进行中-结束状态中文名称** @param startTime 开始时间* @param endTime 结束时间* @return 状态中文名称*/public static String getStartEndStatusName(Date startTime, Date endTime) {return getStartEndStatusName("", startTime, endTime);}/*** 匹配开始-进行中-结束状态中文名称** @param startTime 开始时间* @param endTime 结束时间* @return 状态中文名称*/public static String getStartEndStatusName(Long startTime, Long endTime) {return getStartEndStatusName("", startTime, endTime);}/*** 匹配开始-进行中-结束状态中文名称** @param namePrefix 状态前缀,如会议未开始,会议已结束* @param startTime 开始时间* @param endTime 结束时间* @return 状态中文名称*/public static String getStartEndStatusName(String namePrefix, Date startTime, Date endTime) {if (ZYStrUtils.isAnyNull(startTime, endTime)) {return namePrefix + "已结束";}return getStartEndStatusName(startTime.getTime(), endTime.getTime());}/*** 匹配开始-进行中-结束状态中文名称** @param namePrefix 状态前缀,如会议未开始,会议已结束* @param startTime 开始时间* @param endTime 结束时间* @return 状态中文名称*/public static String getStartEndStatusName(String namePrefix, Long startTime, Long endTime) {if (ZYStrUtils.isAnyNull(startTime, endTime)) {return namePrefix + "已结束";}long now = System.currentTimeMillis();if (now <= startTime) { // 当前时间小于开始时间return namePrefix + "未开始";} else if (now < endTime) { // 当前时间大于开始时间,小于结束时间return namePrefix + "进行中";} else if (now >= endTime) { // 当前时间大于等于结束时间return namePrefix + "已结束";} else {return namePrefix + "已结束";}}/*** 根据年龄设置时间查询区间** @param startAge 开始年龄* @param endAge 结束年龄* @param setStartTime 开始条件函数* @param setEndTime 结束条件函数*/public static void setStartEndAge(Integer startAge, Integer endAge, Consumer<Long> setStartTime,Consumer<Long> setEndTime) {if (ZYStrUtils.isAllNotNull(startAge, endAge)) {setStartTime.accept(computerStartTime(endAge + 1));setEndTime.accept(computerEndTime(startAge));}}/*** 获取某天的开始date** @param year 年* @param month 月* @param day 天* @return 开始日期*/public static Date getFirstDayOfYearMonth(Integer year, Integer month, Integer day) {return getStartEndDate(year, month, day, true);}/*** 获取某天的开始date** @param year 年* @param month 月* @return 开始日期*/public static Date getFirstDayOfYearMonth(Integer year, Integer month) {return getStartEndDate(year, month, null, true);}/*** 获取某天的结束date** @param year 年* @param month 月* @return 结束日期*/public static Date getLastDayOfYearMonth(Integer year, Integer month) {return getStartEndDate(year, month, null, false);}/*** 获取某天的结束date** @param year 年* @param month 月* @param day 日* @return 结束日期*/public static Date getLastDayOfYearMonth(Integer year, Integer month, Integer day) {return getStartEndDate(year, month, day, false);}/*** 设置开始结束查询条件,前端传一些半区间的空值处理** @param startTime 开始时间* @param endTime 结束时间* @param setStartTime 开始时间设置函数* @param setEndTime 结束时间设置函数*/public static void setQueryTime(Long startTime, Long endTime, Consumer<Long> setStartTime,Consumer<Long> setEndTime) {if (null == startTime && null == endTime) {return;} else if (null != startTime && null == endTime) {startTime = getStartTimeOfCurrentDay(new Date(startTime)).getTime();endTime = System.currentTimeMillis();} else if (null == startTime) {startTime = 0L;endTime = getEndTimeOfCurrentDay(new Date(endTime)).getTime();} else {startTime = getStartTimeOfCurrentDay(new Date(startTime)).getTime();endTime = getEndTimeOfCurrentDay(new Date(endTime)).getTime();}setStartTime.accept(startTime);setEndTime.accept(endTime);}/*** 获取本月第一天毫秒数** @return 最后一天*/public static long getMonthStartDay() {LocalDate date = LocalDate.now();LocalDate with1 = date.with(TemporalAdjusters.firstDayOfMonth());ZonedDateTime atStartOfDay = with1.atStartOfDay(ZoneId.systemDefault());Instant instant = atStartOfDay.toInstant();Date from = Date.from(instant);return from.getTime();}/*** 获取本月最后一天毫秒数** @return 最后一天*/public static long getMonthEndDay() {LocalDate date = LocalDate.now();LocalDate with2 = date.with(TemporalAdjusters.lastDayOfMonth());ZonedDateTime atStartOfDay = with2.atStartOfDay(ZoneId.systemDefault());Instant instant = atStartOfDay.toInstant();Date from = Date.from(instant);long time = from.getTime();long oneDay = (24 * 60 * 60 * 1000) - 1;time += oneDay;return time;}/*** 日期格式化** @param date 日期* @param pattern 表达式* @return 年龄*/public static String formart(Long date, String pattern) {if (null == date) {return "";}return formart(new Date(date), pattern);}/*** 日期格式化** @param date 日期* @param pattern 表达式* @return 年龄*/public static String formart(Date date, String pattern) {if (null == date) {return "";}SimpleDateFormat sdf = new SimpleDateFormat(pattern);try {return sdf.format(date);} catch (Exception e) {return null;}}/*** 根据日期计算年龄** @param birthday 日期* @return 年龄*/public static Integer getAgeByBirth(String birthday) {Date birth = toDate(birthday, "yyyy-MM-dd");return getAgeByBirth(birth);}/*** 根据日期计算年龄** @param birthday 日期* @return 年龄*/public static Integer getAgeByBirth(Long birthday) {if (null != birthday && 0 != birthday) {try {return getAgeByBirth(new Date(birthday));} catch (Exception e) {return null;}}return null;}/*** 根据日期计算年龄** @param birth 日期* @return 年龄*/public static Integer getAgeByBirth(Date birth) {if (null == birth) {return null;}Calendar instance = Calendar.getInstance();int yearNow = instance.get(Calendar.YEAR);int monthNow = instance.get(Calendar.MONTH) + 1;Calendar instanceBirth = Calendar.getInstance();instanceBirth.setTime(birth);int yearBirth = instanceBirth.get(Calendar.YEAR);int monthBirth = instanceBirth.get(Calendar.MONTH) + 1;int age = yearNow - yearBirth;// 判断是否足月if (monthNow > monthBirth) {age = age + 1;}return Math.min(age, 150);}/*** 修改日期元素** @param date 日期* @param hour 时* @param min 分* @param second 秒* @return 日期*/public static Date setTimes(Date date, int hour, int min, int second) {Calendar cal = Calendar.getInstance();cal.setTime(date);cal.add(Calendar.HOUR, hour);cal.add(Calendar.MINUTE, min);cal.add(Calendar.SECOND, second);return cal.getTime();}/*** 修改日期的天** @param date 日期* @param days 天数* @return 日期*/public static Date getDateFromNow(Date date, int days) {Calendar cal = Calendar.getInstance();cal.setTime(date);cal.add(Calendar.DAY_OF_YEAR, days);return cal.getTime();}/*** 年份天转日期** @param days 天数* @return 日期*/public static Date getDateFromNow(int days) {Calendar cal = Calendar.getInstance();cal.add(Calendar.DAY_OF_YEAR, days);return cal.getTime();}/*** 字符转日期,处理下异常** @param date 日期* @param sdf 转换器* @return 日期*/public static Date toDate(String date, SimpleDateFormat sdf) {Date parse;try {parse = sdf.parse(date);} catch (ParseException e) {return null;}return parse;}/*** 通用字符转日期,处理下异常** @param date 日期* @return 日期*/public static Long toDataLong(String date) {Date d = toDate(date);return null != d ? d.getTime() : null;}/*** 通用字符转日期,处理下异常** @param date 日期* @return 日期*/public static Date toDate(String date) {// 13707490327if (ZYStrUtils.isNull(date)) {return null;}Date parse = toDate(date, "yyyy-MM-dd HH:mm:ss");if (null == parse) {parse = toDate(date, "yyyy-MM-dd");}if (null == parse) {parse = toDate(date, "yyyy-MM-dd HH:mm:ss.SSS");}if (null == parse) {parse = toDate(date, "yyyyMMdd");}if (null == parse) {parse = toDate(date, "yyyyMMddHHmmss");}if (null == parse) {parse = toDate(date, "MM/dd/yyyy");}if (null == parse) {parse = toDate(date, "yyyy.MM");}if (null == parse && date.length() == 13) {try {long parseLong = Long.parseLong(date);parse = new Date(parseLong);} catch (NumberFormatException e) {return null;}}return parse;}/*** 字符转日期,处理下异常** @param date 日期* @param patten 表达式* @return 日期*/public static Date toDate(String date, String patten) {// 13707490327SimpleDateFormat sdf = new SimpleDateFormat(patten);Date parse;try {parse = sdf.parse(date);} catch (ParseException e) {return null;}return parse;}/*** 获取本天天的最开始的一刻,某天最小** @return 本天最小日期*/public static long getStartLongTimeOfCurrentDay() {return getStartTimeOfCurrentDay().getTime();}/*** 获取本天天的最开始的一刻,某天最小** @return 本天最小日期*/public static Date getStartTimeOfCurrentDay() {return getStartTimeOfCurrentDay(new Date());}/*** 获取某一天的最开始的一刻,某天最小** @param date 日期* @return 本天最小日期*/public static long getStartLongTimeOfCurrentDay(Date date) {return getStartTimeOfCurrentDay(date).getTime();}/*** 获取某一天的最开始的一刻,某天最小** @param date 日期* @return 本天最小日期*/public static Date getStartTimeOfCurrentDay(Date date) {Calendar calendar = Calendar.getInstance();calendar.setTime(date);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();}/*** 获取今天的最大日期时决戮** @return 今天 最大日期*/public static long getEndLongTimeOfCurrentDay() {return getEndTimeOfCurrentDay().getTime();}/*** 获取今天的最大日期** @return 今天 最大日期*/public static Date getEndTimeOfCurrentDay() {return getEndTimeOfCurrentDay(new Date());}/*** 获取最大日期** @param date 日期* @return 最大的long日期*/public static Long getEndLongTimeOfCurrentDay(Date date) {if (null == date) {return null;}return getEndTimeOfCurrentDay(date).getTime();}/*** 获取某一天的最后一刻,某天最大的时间戮** @param date 日期* @return 本天最大日期*/public static Date getEndTimeOfCurrentDay(Date date) {if (null == date) {return null;}Calendar calendar = Calendar.getInstance();calendar.setTime(date);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();}/*** 获取当前季节** @return 季节*/public static int getQuarter() {return getQuarter(DateTime.now());}/*** 获取日期季节** @param date 日期* @return 季节*/public static Integer getQuarter(Long date) {return null == date ? null : getQuarter(new DateTime(date));}/*** 获取日期季节** @param dateTime 日期* @return 季节*/public static int getQuarter(DateTime dateTime) {int monthOfYear = dateTime.getMonthOfYear();if (monthOfYear <= 3) {return 1;}if (monthOfYear <= 6) {return 2;}if (monthOfYear <= 9) {return 3;}return 4;}/*** 获取当前月** @return 当前月份*/public static int getMonthValue() {LocalDate date = LocalDate.now();return date.getMonthValue();}/*** 获取当前年** @return 当前年份*/public static int getNowYear() {LocalDate date = LocalDate.now();return date.getYear();}/*** 日期转Long,处理下非空** @param dateLong 时间戳* @return 日期*/public static Long toLongDate(String dateLong) {if (ZYStrUtils.isNull(dateLong)) {return null;}Date date = toDate(dateLong);return null != date ? date.getTime() : null;}private static Date getStartEndDate(Integer year, Integer month, Integer day, boolean isGetForStart) {if (null == year || null == month) {return null;}Calendar cal = Calendar.getInstance();// 设置年份cal.set(Calendar.YEAR, year);// 设置月份cal.set(Calendar.MONTH, month - 1);if (null == day) {int dayOfMonth = Calendar.DAY_OF_MONTH;day = isGetForStart ?cal.getActualMinimum(dayOfMonth) : cal.getActualMaximum(dayOfMonth);}cal.set(Calendar.DAY_OF_MONTH, day);cal.set(Calendar.HOUR_OF_DAY, isGetForStart ? 0 : 23);cal.set(Calendar.MINUTE, isGetForStart ? 0 : 59);cal.set(Calendar.SECOND, isGetForStart ? 0 : 59);cal.set(Calendar.MILLISECOND, isGetForStart ? 0 : 999);return cal.getTime();}/*** 根据年龄计算出生年的开始时间** @param endAge 年龄* @return 出生开始时间*/private static Long computerStartTime(Integer endAge) {if (ZYStrUtils.isNull(endAge)) {return Long.MIN_VALUE;}DateTime now = new DateTime();int year = now.getYear();int month = now.getMonthOfYear();int day = now.getDayOfMonth();int endYear = year - endAge;Date date = getFirstDayOfYearMonth(endYear, month, day);return date.getTime();}/*** 根据年龄计算出生年的结束时间** @param startAge 年龄* @return 出生结束时间*/private static Long computerEndTime(Integer startAge) {// 40if (ZYStrUtils.isNull(startAge)) {return System.currentTimeMillis();}DateTime now = new DateTime();int year = now.getYear();int month = now.getMonthOfYear();int day = now.getDayOfMonth();int endYear = year - startAge;Date date = getLastDayOfYearMonth(endYear, month, day);return date.getTime();}
}