前言
在 Java 开发中,日期和时间的处理是一个常见问题。日期时间工具类是 Hutool 的核心包之一,提供针对 JDK 中 Date、Calendar 对象的封装,封装对象如下:
| 封装对象 | 说明 |
|---|---|
| DateUtil | 针对日期时间操作提供一系列静态方法 |
| DateTime | 提供类似于Joda-Time中日期时间对象的封装,继承自Date类,并提供更加丰富的对象方法 |
| FastDateFormat | 提供线程安全的针对Date对象的格式化和日期字符串解析支持 |
| DateBetween | 计算两个时间间隔的类 |
| TimeInterval | 一个简单的计时器类,常用于计算某段代码的执行时间,提供各种单位的花费时长计算 |
| DatePattern | 提供常用的日期格式化模式,包括String类型和FastDateFormat两种类型 |
| Quarter | 季度枚举 |
| Month | 月份枚举 |
| Week | 周枚举 |
| DateUnit | 时间枚举,要表示某个时间单位对应的毫秒数,常用于计算时间差 |
一、概述
1.1 工具简介
LocalDateTimeUtil 是 Hutool 针对 Java 8 原生 java.time API 的优雅封装,旨在简化 LocalDateTime、LocalDate 等新时间 API 提供的封装工具类。它本身不重新实现时间逻辑,而是对原生 API 进行简化,解决了原生操作繁琐、边界处理复杂的问题,让代码更简洁、易读。该工具类从 Hutool 5.4.x 版本开始提供,涵盖了日常开发中绝大多数时间处理场景。
import cn.hutool.core.date.LocalDateTimeUtil;
1.2 引入依赖
在使用 Hutool 工具之前,我们需要将 Hutool 添加到项目的依赖中。如果使用 Maven 构建项目,可以在 pom.xml 文件中添加以下依赖:
<!-- https://mvnrepository.com/artifact/cn.hutool/hutool-all -->
<dependency>
<groupId>cn.hutool</groupId>
<artifactId>hutool-all</artifactId>
<!-- 请检查最新版本,可以根据实际需要进行调整 -->
<version>5.8.40</version>
</dependency>
Hutool-all 是一个 Hutool 的集成打包产品,由于考虑到“懒人”用户及分不清各个模块作用的用户,“无脑”引入 hutool-all 模块是快速开始和深入应用的最佳方式。
二、常用方法及使用示例
2.1 获取日期时间
| 方法 | 简要说明 |
|---|---|
| LocalDateTime now() | 获取默认时区的当前时间 |
| Week dayOfWeek(LocalDate localDate) | 获取指定日期对应的星期值 |
| int weekOfYear(TemporalAccessor date) | 获得指定日期是所在年份的第几周 |
| long toEpochMilli(TemporalAccessor temporalAccessor) | 转为毫秒时间戳 |
// 获取当前 LocalDateTime
LocalDateTime localDateTime = LocalDateTimeUtil.now();
int week = LocalDateTimeUtil.weekOfYear(localDateTime);
System.out.println("指定日期 " + localDateTime + " 是所在年份的第 " + week + " 周");
// 转为时间戳(毫秒)
long milli = LocalDateTimeUtil.toEpochMilli(localDateTime);
System.out.println("指定日期 " + localDateTime + " 对应的时间戳(毫秒)为:" + milli);
2.2 日期时间转换
| 方法 | 简要说明 |
|---|---|
| of | 使用默认时区,将 Date、Instant 等转为 LocalDateTime |
| LocalDate ofDate(TemporalAccessor temporalAccessor) | |
| LocalDateTime ofUTC(Instant instant) LocalDateTime ofUTC(long epochMilli) | 时间戳转LocalDateTime,使用UTC时区 |
// 1. 毫秒时间戳转LocalDateTime(系统默认时区)
long ts = System.currentTimeMillis();
LocalDateTime dtTs = LocalDateTimeUtil.of(ts);
// 2. Date对象转LocalDateTime
Date dateObj = new Date();
LocalDateTime dtFromDate = LocalDateTimeUtil.of(dateObj);
// 3. Instant转LocalDateTime
LocalDateTime dtInstant = LocalDateTimeUtil.of(Instant.now());
// 4. UTC时间戳转LocalDateTime(UTC时区)
LocalDateTime dtUtc = LocalDateTimeUtil.ofUTC(ts);
2.3 日期时间解析
| 方法 | 简要说明 |
|---|---|
| LocalDateTime parse(CharSequence text) | 按 ISO 格式解析,仅支持 yyyy-MM-dd'T'HH:mm:ss 格式 |
| LocalDateTime parse(CharSequence text, DateTimeFormatter formatter) | 格式支持日期时间、日期、时间 |
| LocalDateTime parse(CharSequence text, String format) | 使用指定模式,如 yyyy-MM-dd HH:mm:ss |
| LocalDate parseDate(CharSequence text) | 按 ISO 日期格式解析,仅支持 ``yyyy-MM-dd 格式 |
| LocalDate parseDate(CharSequence text, DateTimeFormatter formatter) | 指定格式化器,时间部分会被丢弃 |
| LocalDate parseDate(CharSequence text, String format) | 指定日期模式 |
✅ parse 与 parseDate 对 null、空白字符串做了保护,返回 null。
// 解析ISO时间格式
LocalDateTime localDateTime = LocalDateTimeUtil.parse("2026-10-31T14:30:00");
System.out.println("解析为 LocalDateTime: " + localDateTime);
// 解析自定义格式时间格式
localDateTime = LocalDateTimeUtil.parse("2026-10-31", DatePattern.NORM_DATE_PATTERN);
System.out.println("解析日期时间字符串 LocalDateTime: " + localDateTime);
LocalDate localDate = LocalDateTimeUtil.parseDate("2026-10-31");
System.out.println("解析为 LocalDate: " + localDate);
localDate = LocalDateTimeUtil.parseDate("2026-10-31 14:30:00", DatePattern.NORM_DATETIME_FORMATTER);
System.out.println("解析带时间的字符串为 LocalDate: " + localDate);
// 解析日期时间为LocalDate,时间部分舍弃格式
localDate = LocalDateTimeUtil.parseDate("2026-10-31T14:30:00", DateTimeFormatter.ISO_LOCAL_DATE_TIME);
System.out.println("解析带时间时区的字符串为 LocalDate: " + localDate);
2.4 日期时间格式化
用于将时间对象输出为指定格式的字符串,常用方法如下表所示:
| 方法 | 简要说明 |
|---|---|
| format | 格式化为指定字符串 |
| String formatNormal(LocalDate date) | 格式化日期时间为 yyyy-MM-dd 格式 |
| String formatNormal(LocalDateTime time) | 格式化日期时间为 yyyy-MM-dd HH:mm:ss 格式 |
LocalDateTime localDateTime = LocalDateTime.now();
System.out.println("当前时间: " + localDateTime);
String format = LocalDateTimeUtil.format(localDateTime, DatePattern.NORM_DATETIME_PATTERN);
System.out.println("格式化时间: " + format);
String str = LocalDateTimeUtil.format(localDateTime, "yyyy年MM月dd日");
System.out.println("自定义格式化时间: " + str);
2.4 时间偏移
| 方法 | 简要说明 |
|---|---|
| offset(LocalDateTime time,long number,TemporalUnit field) | 对指定时间进行偏移,偏移会修改传入的对象。 offset 为正数表示增加,负数表示减少 |
LocalDateTime localDateTime = LocalDateTimeUtil.now();
System.out.println("当前时间:" + localDateTime);
LocalDateTime offset = LocalDateTimeUtil.offset(localDateTime, 1, ChronoUnit.DAYS);
System.out.println("增加一天:" + offset);
offset = LocalDateTimeUtil.offset(localDateTime, -2, ChronoUnit.HOURS);
System.out.println("减少2小时:" + offset);
offset = LocalDateTimeUtil.offset(localDateTime, 30, ChronoUnit.MINUTES);
System.out.println("增加30分钟:" + offset);
2.5 时间差计算
计算两个时间点之间的间隔,如下表所示:
| 方法 | 简要说明 |
|---|---|
| Duration between(LocalDateTime start, LocalDateTime end) | 返回 Duration 对象,可以取天、时、分、秒 |
| long between(LocalDateTime start, LocalDateTime end, ChronoUnit unit) | 直接获取指定单位差值 |
| betweenPeriod(LocalDate start,LocalDate end) | 用于计算日期间隔(年、月、日) |
✅ 注意:包含 start 但不包含 end,如果end < start,获取结果为负数。
LocalDateTime start = LocalDateTimeUtil.parse("1990-07-26T12:00:00");
LocalDateTime end = LocalDateTimeUtil.now();
Duration between = LocalDateTimeUtil.between(start, end);
System.out.println("相差天数:" + between.toDays());
// 直接获取指定单位差值
long years = LocalDateTimeUtil.between(start, end, ChronoUnit.YEARS);
System.out.println("相差年数:" + years);
long months = LocalDateTimeUtil.between(start, end, ChronoUnit.MONTHS);
System.out.println("相差月数:" + months);
long days = LocalDateTimeUtil.between(start, end, ChronoUnit.DAYS);
System.out.println("相差天数:" + days);
2.5 时间判断与比较
| 方法 | 简要说明 |
|---|---|
| isIn | 判断指定日期是否在指定日期范围内 |
| isOverlap | 检查两个时间段是否有时间重叠,常用于会议室预订等场景 |
| isSameDay | 比较两个日期是否为同一天 |
| isWeekend | 是否为周末(周六或周日) |
@Test
public void isInTest() {
LocalDateTime target = LocalDateTimeUtil.now();
LocalDateTime start = LocalDateTimeUtil.beginOfDay(now);
LocalDateTime end = LocalDateTimeUtil.endOfDay(now);
// 判断 target 是否在 [start, end] 区间
boolean inRange = LocalDateTimeUtil.isIn(target, start, end);
System.out.println(target + " 是否在 " + start + " 至 " + end + " 之间:" + inRange);
}
@Test
public void isOverlapTest() {
}
@Test
public void isSameDayInTest() {
}
@Test
public void isWeekendInTest() {
LocalDateTime localDateTime = LocalDateTimeUtil.now();
boolean weekend = LocalDateTimeUtil.isWeekend(localDateTime);
System.out.println(localDateTime + " 是否是周末:" + weekend);
}
2.6 日期时间边界
快速获取一天的开始或结束时刻,常用于数据库查询范围构造。
| 方法 | 简要说明 |
|---|---|
| beginOfDay | 返回指定天的开始时间(00:00:00) |
| endOfDay | 返回指定天的结束时间(23:59:59.99999)。 truncateMillisecond:是否毫秒归零 |
LocalDateTime localDateTime = LocalDateTimeUtil.now();
LocalDateTime beginOfDay = LocalDateTimeUtil.beginOfDay(localDateTime);
System.out.println("指定时间的开始时间: " + beginOfDay);
LocalDateTime endOfDay = LocalDateTimeUtil.endOfDay(localDateTime);
System.out.println("指定时间的结束时间: " + endOfDay);
LocalDateTime endOfDayTruncate = LocalDateTimeUtil.endOfDay(localDateTime, true);
System.out.println("指定时间的结束时间(毫秒归零): " + endOfDayTruncate);
三、附录
3.1 LocalDateTimeUtil 🆚 DateUtil
| 工具类 | 操作对象 | JDK 版本 | 特点 |
|---|---|---|---|
| LocalDateTimeUtil | LocalDateTime LocalDate | JDK8+ | 不可变、时区可控、推荐新项目 |
| DateUtil | java.util.Date Calendar | JDK1.7+ | 可变对象,老项目兼容 |
✅ 不要混用:DateUtil 处理 Date,LocalDateTimeUtil 处理 java.time 时间。
3.2 业务日期工具封装
基于 Hutool LocalDateTimeUtil 业务日期工具封装,底层全部复用 LocalDateTimeUtil 不重复造轮子,常用于今天、昨天、本周、上周、本月、上月、本季度、上季度、本年、去年起止、年龄计算、是否同一天、是否同周、近 N 天起止、人性化相对时间(多久之前)等。
import cn.hutool.core.date.DatePattern;
import cn.hutool.core.date.LocalDateTimeUtil;
import java.time.*;
import java.time.temporal.ChronoUnit;
import java.time.temporal.TemporalAdjusters;
public class BizDateUtil {
// ====================== 【当前快捷获取】 ======================
/**
* 当前 LocalDateTime
*/
public static LocalDateTime now() {
return LocalDateTimeUtil.now();
}
/**
* 今天日期(LocalDate)
*/
public static LocalDate today() {
LocalDateTime localDateTime = LocalDateTime.now();
String format = LocalDateTimeUtil.format(localDateTime, DatePattern.NORM_DATE_PATTERN);
return LocalDateTimeUtil.parseDate(format, DatePattern.NORM_DATE_PATTERN);
}
/**
* 今天开始时间 00:00:00
*/
public static LocalDateTime beginOfToday() {
return LocalDateTimeUtil.beginOfDay(today());
}
/**
* 今天结束时间 23:59:59.999999999
*/
public static LocalDateTime endOfToday() {
return LocalDateTimeUtil.endOfDay(today());
}
/**
* 昨天开始
*/
public static LocalDateTime beginOfYesterday() {
LocalDate yesterday = today().minusDays(1);
return LocalDateTimeUtil.beginOfDay(yesterday);
}
/**
* 昨天结束
*/
public static LocalDateTime endOfYesterday() {
LocalDate yesterday = today().minusDays(1);
return LocalDateTimeUtil.endOfDay(yesterday);
}
// ====================== 【近N天】 ======================
/**
* 近n天(包含今天)起始时间
* 示例:n=7 → 【6天前 00:00:00 ~ 今天 23:59:59.999999999】
*
* @param n 天数,必须 >=1
* @return 起始时间
*/
public static LocalDateTime beginOfRecentNDays(int n) {
if (n < 1) {
throw new IllegalArgumentException("天数不能小于1");
}
LocalDate startDate = today().minusDays(n - 1);
return LocalDateTimeUtil.beginOfDay(startDate);
}
/**
* 近n天(不包含今天)起始时间
* 示例:n=7 → 【7天前 00:00:00 ~ 昨天 23:59:59.999999999】
*
* @param n 天数,必须 >=1
* @return 起始时间
*/
public static LocalDateTime beginOfRecentNDaysExcludeToday(int n) {
if (n < 1) {
throw new IllegalArgumentException("天数不能小于1");
}
LocalDate startDate = today().minusDays(n);
return LocalDateTimeUtil.beginOfDay(startDate);
}
// ====================== 【本周 / 上周(周一为第一天)】 ======================
/**
* 本周第一天(周一)00:00:00
*/
public static LocalDateTime beginOfThisWeek() {
LocalDate monday = today().with(TemporalAdjusters.previousOrSame(DayOfWeek.MONDAY));
return LocalDateTimeUtil.beginOfDay(monday);
}
/**
* 本周最后一天(周日)23:59:59.999999999
*/
public static LocalDateTime endOfThisWeek() {
LocalDate sunday = today().with(TemporalAdjusters.nextOrSame(DayOfWeek.SUNDAY));
return LocalDateTimeUtil.endOfDay(sunday);
}
/**
* 上周第一天(上周一)
*/
public static LocalDateTime beginOfLastWeek() {
LocalDate lastMonday = today()
.with(TemporalAdjusters.previousOrSame(DayOfWeek.MONDAY))
.minusWeeks(1);
return LocalDateTimeUtil.beginOfDay(lastMonday);
}
/**
* 上周最后一天(上周日)
*/
public static LocalDateTime endOfLastWeek() {
LocalDate lastSunday = today()
.with(TemporalAdjusters.previousOrSame(DayOfWeek.MONDAY))
.minusDays(1);
return LocalDateTimeUtil.endOfDay(lastSunday);
}
// ====================== 【本月 / 上月】 ======================
/**
* 本月第一天 00:00:00
*/
public static LocalDateTime beginOfThisMonth() {
LocalDate firstDay = today().with(TemporalAdjusters.firstDayOfMonth());
return LocalDateTimeUtil.beginOfDay(firstDay);
}
/**
* 本月最后一天 23:59:59.999999999
*/
public static LocalDateTime endOfThisMonth() {
LocalDate lastDay = today().with(TemporalAdjusters.lastDayOfMonth());
return LocalDateTimeUtil.endOfDay(lastDay);
}
/**
* 上月第一天
*/
public static LocalDateTime beginOfLastMonth() {
LocalDate firstDay = today().minusMonths(1).with(TemporalAdjusters.firstDayOfMonth());
return LocalDateTimeUtil.beginOfDay(firstDay);
}
/**
* 上月最后一天
*/
public static LocalDateTime endOfLastMonth() {
LocalDate lastDay = today().minusMonths(1).with(TemporalAdjusters.lastDayOfMonth());
return LocalDateTimeUtil.endOfDay(lastDay);
}
// ====================== 【本季度 / 上季度】 ======================
/**
* 获取本季度起始时间
*/
public static LocalDateTime beginOfThisQuarter() {
LocalDate nowDate = today();
int quarter = (nowDate.getMonthValue() - 1) / 3;
Month startMonth = Month.of(quarter * 3 + 1);
LocalDate firstDay = LocalDate.of(nowDate.getYear(), startMonth, 1);
return LocalDateTimeUtil.beginOfDay(firstDay);
}
/**
* 获取本季度结束时间
*/
public static LocalDateTime endOfThisQuarter() {
LocalDate nowDate = today();
int quarter = (nowDate.getMonthValue() - 1) / 3;
Month endMonth = Month.of(quarter * 3 + 3);
LocalDate lastDay = LocalDate.of(nowDate.getYear(), endMonth, 1)
.with(TemporalAdjusters.lastDayOfMonth());
return LocalDateTimeUtil.endOfDay(lastDay);
}
/**
* 上季度起始
*/
public static LocalDateTime beginOfLastQuarter() {
LocalDate nowDate = today();
int q = (nowDate.getMonthValue() - 1) / 3;
LocalDate firstDay;
if (q == 0) {
// 当前Q1,上季度是去年Q4
firstDay = LocalDate.of(nowDate.getYear() - 1, Month.OCTOBER, 1);
} else {
Month startMonth = Month.of((q - 1) * 3 + 1);
firstDay = LocalDate.of(nowDate.getYear(), startMonth, 1);
}
return LocalDateTimeUtil.beginOfDay(firstDay);
}
/**
* 上季度结束
*/
public static LocalDateTime endOfLastQuarter() {
LocalDate nowDate = today();
int q = (nowDate.getMonthValue() - 1) / 3;
LocalDate lastDay;
if (q == 0) {
lastDay = LocalDate.of(nowDate.getYear() - 1, Month.DECEMBER, 1)
.with(TemporalAdjusters.lastDayOfMonth());
} else {
Month endMonth = Month.of((q - 1) * 3 + 3);
lastDay = LocalDate.of(nowDate.getYear(), endMonth, 1)
.with(TemporalAdjusters.lastDayOfMonth());
}
return LocalDateTimeUtil.endOfDay(lastDay);
}
// ====================== 【本年 / 去年】 ======================
/**
* 本年第一天
*/
public static LocalDateTime beginOfThisYear() {
LocalDate firstDay = today().with(TemporalAdjusters.firstDayOfYear());
return LocalDateTimeUtil.beginOfDay(firstDay);
}
/**
* 本年最后一天
*/
public static LocalDateTime endOfThisYear() {
LocalDate lastDay = today().with(TemporalAdjusters.lastDayOfYear());
return LocalDateTimeUtil.endOfDay(lastDay);
}
/**
* 去年第一天
*/
public static LocalDateTime beginOfLastYear() {
LocalDate firstDay = today().minusYears(1).with(TemporalAdjusters.firstDayOfYear());
return LocalDateTimeUtil.beginOfDay(firstDay);
}
/**
* 去年最后一天
*/
public static LocalDateTime endOfLastYear() {
LocalDate lastDay = today().minusYears(1).with(TemporalAdjusters.lastDayOfYear());
return LocalDateTimeUtil.endOfDay(lastDay);
}
// ====================== 【判断工具】 ======================
/**
* 是否同一天
*/
public static boolean isSameDay(LocalDateTime dt1, LocalDateTime dt2) {
if (dt1 == null || dt2 == null) {
return false;
}
return LocalDate.from(dt1).isEqual(LocalDate.from(dt2));
}
/**
* 是否同一周(周一为一周起始)
*/
public static boolean isSameWeek(LocalDateTime dt1, LocalDateTime dt2) {
if (dt1 == null || dt2 == null) {
return false;
}
LocalDate d1 = LocalDate.from(dt1);
LocalDate d2 = LocalDate.from(dt2);
LocalDate w1 = d1.with(TemporalAdjusters.previousOrSame(DayOfWeek.MONDAY));
LocalDate w2 = d2.with(TemporalAdjusters.previousOrSame(DayOfWeek.MONDAY));
return w1.isEqual(w2);
}
/**
* 是否同一月
*/
public static boolean isSameMonth(LocalDateTime dt1, LocalDateTime dt2) {
if (dt1 == null || dt2 == null) {
return false;
}
return dt1.getYear() == dt2.getYear() && dt1.getMonthValue() == dt2.getMonthValue();
}
/**
* 时间是否在 [start, end] 闭区间内(封装hutool isIn)
*/
public static boolean isIn(LocalDateTime target, LocalDateTime start, LocalDateTime end) {
if (target == null || start == null || end == null) {
return false;
}
return LocalDateTimeUtil.isIn(target, start, end);
}
// ====================== 【年龄计算】 ======================
/**
* 根据生日计算周岁
*
* @param birthday 生日 LocalDate
* @return 周岁
*/
public static int getAge(LocalDate birthday) {
if (birthday == null) {
return 0;
}
return (int) ChronoUnit.YEARS.between(birthday, today());
}
public static int getAge(LocalDateTime birthday) {
if (birthday == null) {
return 0;
}
return getAge(LocalDate.from(birthday));
}
// ====================== 【格式化快捷方法】 ======================
/**
* yyyy-MM-dd HH:mm:ss
*/
public static String formatNormal(LocalDateTime dt) {
if (dt == null) {
return null;
}
return LocalDateTimeUtil.format(dt, DatePattern.NORM_DATETIME_PATTERN);
}
/**
* yyyy-MM-dd
*/
public static String formatDate(LocalDate date) {
if (date == null) {
return null;
}
return LocalDateTimeUtil.format(date, DatePattern.NORM_DATE_PATTERN);
}
// ====================== 【解析快捷方法】 ======================
public static LocalDateTime parseNormal(String dateStr) {
if (dateStr == null) {
return null;
}
return LocalDateTimeUtil.parse(dateStr, DatePattern.NORM_DATETIME_PATTERN);
}
// ====================== 人性化相对时间(多久之前)】 ======================
/**
* 人性化相对时间:刚刚 / x分钟前 / x小时前 / x天前,超过7天返回 yyyy-MM-dd HH:mm:ss
*
* @param time 待格式化时间
* @return 友好时间文本
*/
public static String formatRelativeTime(LocalDateTime time) {
if (time == null) {
return "";
}
LocalDateTime now = now();
// 防止传入未来时间
if (time.isAfter(now)) {
return formatNormal(time);
}
Duration duration = Duration.between(time, now);
long second = duration.getSeconds();
if (second < 60) {
return "刚刚";
}
long minute = duration.toMinutes();
if (minute < 60) {
return minute + "分钟前";
}
long hour = duration.toHours();
if (hour < 24) {
return hour + "小时前";
}
long day = duration.toDays();
if (day <= 7) {
return day + "天前";
}
// 超过7天,返回标准日期字符串
return formatNormal(time);
}
}
测试使用示例:
public class LocalDateTimeUtilTest {
public static void main(String[] args) {
System.out.println("今天开始:" + BizDateUtil.beginOfToday());
System.out.println("本周起止:" + BizDateUtil.beginOfThisWeek() + " ~ " + BizDateUtil.endOfThisWeek());
System.out.println("上月起止:" + BizDateUtil.beginOfLastMonth() + " ~ " + BizDateUtil.endOfLastMonth());
System.out.println("上季度起止:" + BizDateUtil.beginOfLastQuarter() + " ~ " + BizDateUtil.endOfLastQuarter());
System.out.println("本年起止:" + BizDateUtil.beginOfThisYear() + " ~ " + BizDateUtil.endOfThisYear());
// 年龄
LocalDate birth = LocalDate.of(2000, 5, 20);
System.out.println("年龄:" + BizDateUtil.getAge(birth));
// 判断
LocalDateTime t1 = LocalDateTime.of(2026, 11, 1, 10, 0, 0);
LocalDateTime t2 = LocalDateTime.of(2026, 11, 1, 22, 0, 0);
System.out.println("是否同一天:" + BizDateUtil.isSameDay(t1, t2));
// 近7天(含今天)
LocalDateTime recent7Start = BizDateUtil.beginOfRecentNDays(7);
System.out.println("近7天起始(含今天):" + recent7Start + " ~ " + BizDateUtil.endOfToday());
// 近7天(不含今天)
LocalDateTime recent7ExStart = BizDateUtil.beginOfRecentNDaysExcludeToday(7);
System.out.println("近7天起始(不含今天):" + recent7ExStart + " ~ " + BizDateUtil.endOfYesterday());
// 人性化时间
LocalDateTime m1 = LocalDateTime.now().minusMinutes(5);
LocalDateTime h1 = LocalDateTime.now().minusHours(3);
LocalDateTime d1 = LocalDateTime.now().minusDays(3);
LocalDateTime d2 = LocalDateTime.now().minusDays(10);
System.out.println("5分钟前" + BizDateUtil.formatRelativeTime(m1));
System.out.println("3小时前" + BizDateUtil.formatRelativeTime(h1));
System.out.println("3天前" + BizDateUtil.formatRelativeTime(d1));
System.out.println("10天前" + BizDateUtil.formatRelativeTime(d2));
}
}