在 Java 开发中,处理“最近一周”、“最近一天”等时间段查询,强烈推荐使用 Java 8 引入的 java.time 包(如 LocalDateTimeLocalDate)。它不仅线程安全,而且 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());
    }
}

💡 核心逻辑解析

  1. 最近 N 天/周/月(滑动时间窗口): 直接使用 LocalDateTime.now().minusDays(1)minusWeeks(1) 等方法,从当前时间往前推算,非常适合做“最近活跃记录”、“近7天趋势图”等查询。

  2. 本周/本月(固定周期): 使用了 TemporalAdjusters 这个强大的时间调节器。

    • TemporalAdjusters.previousOrSame(DayOfWeek.MONDAY):自动找到本周的周一。
    • TemporalAdjusters.firstDayOfMonth():自动找到本月的1号。
    • LocalTime.MAX:代表一天的最后一刻(23:59:59.999999999),确保查询能覆盖到当天的最后一秒。

⚠️ 避坑与最佳实践

  1. 数据库查询建议用“左闭右开”: 在写 SQL 查询时间段时,最严谨且不易出错的写法是 [开始时间, 下一周期的开始时间)

    • 比如查今天的数据,条件可以写成:create_time >= '2026-05-19 00:00:00' AND create_time < '2026-05-20 00:00:00'
    • 这样可以完美避开 23:59:5923:59:59.999 之间的毫秒级数据遗漏问题。
  2. 时区问题: 如果你的服务器和应用不在同一个时区(比如服务器是 UTC,用户在国内),建议统一使用 ZonedDateTime 或在获取当前时间时显式指定时区(如 LocalDateTime.now(ZoneId.of("Asia/Shanghai"))),防止出现“跨天”时间对不上的情况。

  3. 格式化输出: 工具类中统一使用了 yyyy-MM-dd HH:mm:ss 格式,这与你之前问的达梦数据库 TO_DATE 格式是完美契合的,可以直接拼接到 SQL 中使用。

更多推荐