Java 开发时间工具类
·
在 Java 开发中,处理“最近一周”、“最近一天”等时间段查询,强烈推荐使用 Java 8 引入的 java.time 包(如 LocalDateTime、LocalDate)。它不仅线程安全,而且 API 设计非常直观。
这里为你封装了一个非常实用的 TimeUtils 工具类,涵盖了日常开发中 90% 的时间段查询需求(包括最近一天、最近一周、本月、本季度等)。
🛠️ 核心时间工具类 (TimeUtils)
import java.time.*;
import java.time.format.DateTimeFormatter;
import java.time.temporal.TemporalAdjusters;
import java.util.HashMap;
import java.util.Map;
public class TimeUtils {
// 定义通用的日期时间格式
private static final DateTimeFormatter FORMATTER = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
/**
* 获取最近一天(过去24小时)
*/
public static Map<String, String> getLastDay() {
Map<String, String> map = new HashMap<>();
LocalDateTime now = LocalDateTime.now();
LocalDateTime startTime = now.minusDays(1);
map.put("startTime", startTime.format(FORMATTER));
map.put("endTime", now.format(FORMATTER));
return map;
}
/**
* 获取最近一周(过去7天)
*/
public static Map<String, String> getLastWeek() {
Map<String, String> map = new HashMap<>();
LocalDateTime now = LocalDateTime.now();
LocalDateTime startTime = now.minusWeeks(1);
map.put("startTime", startTime.format(FORMATTER));
map.put("endTime", now.format(FORMATTER));
return map;
}
/**
* 获取最近一个月(过去30天)
*/
public static Map<String, String> getLastMonth() {
Map<String, String> map = new HashMap<>();
LocalDateTime now = LocalDateTime.now();
LocalDateTime startTime = now.minusMonths(1);
map.put("startTime", startTime.format(FORMATTER));
map.put("endTime", now.format(FORMATTER));
return map;
}
/**
* 获取今天(00:00:00 到 23:59:59)
*/
public static Map<String, String> getToday() {
Map<String, String> map = new HashMap<>();
LocalDate today = LocalDate.now();
map.put("startTime", today.atStartOfDay().format(FORMATTER));
map.put("endTime", today.atTime(LocalTime.MAX).format(FORMATTER));
return map;
}
/**
* 获取本周(周一 00:00:00 到 周日 23:59:59)
*/
public static Map<String, String> getThisWeek() {
Map<String, String> map = new HashMap<>();
LocalDate today = LocalDate.now();
// 获取本周一
LocalDate startDay = today.with(TemporalAdjusters.previousOrSame(DayOfWeek.MONDAY));
// 获取本周日
LocalDate endDay = today.with(TemporalAdjusters.nextOrSame(DayOfWeek.SUNDAY));
map.put("startTime", startDay.atStartOfDay().format(FORMATTER));
map.put("endTime", endDay.atTime(LocalTime.MAX).format(FORMATTER));
return map;
}
/**
* 获取本月(1号 00:00:00 到 月末 23:59:59)
*/
public static Map<String, String> getThisMonth() {
Map<String, String> map = new HashMap<>();
LocalDate today = LocalDate.now();
LocalDate startDay = today.with(TemporalAdjusters.firstDayOfMonth());
LocalDate endDay = today.with(TemporalAdjusters.lastDayOfMonth());
map.put("startTime", startDay.atStartOfDay().format(FORMATTER));
map.put("endTime", endDay.atTime(LocalTime.MAX).format(FORMATTER));
return map;
}
/**
* 获取本季度
*/
public static Map<String, String> getThisQuarter() {
Map<String, String> map = new HashMap<>();
LocalDateTime now = LocalDateTime.now();
int month = now.getMonthValue();
int startMonth, endMonth;
if (month <= 3) { // 第一季度
startMonth = 1; endMonth = 3;
} else if (month <= 6) { // 第二季度
startMonth = 4; endMonth = 6;
} else if (month <= 9) { // 第三季度
startMonth = 7; endMonth = 9;
} else { // 第四季度
startMonth = 10; endMonth = 12;
}
LocalDateTime startTime = LocalDateTime.of(now.getYear(), startMonth, 1, 0, 0, 0);
LocalDateTime endTime = startTime.withMonth(endMonth).with(TemporalAdjusters.lastDayOfMonth()).with(LocalTime.MAX);
map.put("startTime", startTime.format(FORMATTER));
map.put("endTime", endTime.format(FORMATTER));
return map;
}
// 测试主方法
public static void main(String[] args) {
System.out.println("最近一天: " + getLastDay());
System.out.println("最近一周: " + getLastWeek());
System.out.println("今天: " + getToday());
System.out.println("本周: " + getThisWeek());
System.out.println("本季度: " + getThisQuarter());
}
}
💡 核心逻辑解析
-
最近 N 天/周/月(滑动时间窗口): 直接使用
LocalDateTime.now().minusDays(1)或minusWeeks(1)等方法,从当前时间往前推算,非常适合做“最近活跃记录”、“近7天趋势图”等查询。 -
本周/本月(固定周期): 使用了
TemporalAdjusters这个强大的时间调节器。TemporalAdjusters.previousOrSame(DayOfWeek.MONDAY):自动找到本周的周一。TemporalAdjusters.firstDayOfMonth():自动找到本月的1号。LocalTime.MAX:代表一天的最后一刻(23:59:59.999999999),确保查询能覆盖到当天的最后一秒。
⚠️ 避坑与最佳实践
-
数据库查询建议用“左闭右开”: 在写 SQL 查询时间段时,最严谨且不易出错的写法是
[开始时间, 下一周期的开始时间)。- 比如查今天的数据,条件可以写成:
create_time >= '2026-05-19 00:00:00' AND create_time < '2026-05-20 00:00:00'。 - 这样可以完美避开
23:59:59和23:59:59.999之间的毫秒级数据遗漏问题。
- 比如查今天的数据,条件可以写成:
-
时区问题: 如果你的服务器和应用不在同一个时区(比如服务器是 UTC,用户在国内),建议统一使用
ZonedDateTime或在获取当前时间时显式指定时区(如LocalDateTime.now(ZoneId.of("Asia/Shanghai"))),防止出现“跨天”时间对不上的情况。 -
格式化输出: 工具类中统一使用了
yyyy-MM-dd HH:mm:ss格式,这与你之前问的达梦数据库TO_DATE格式是完美契合的,可以直接拼接到 SQL 中使用。
更多推荐

所有评论(0)