You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Java中如何简洁判断LocalDateTime是否在指定营业时间区间

需求说明

需要校验给定LocalDateTime实例是否在商家营业时间范围内,营业时间规则如下:

  • 周一至周五:8:00 - 12:30、14:00 - 18:00
  • 周六:8:00 - 14:00

原有实现存在大量重复逻辑,需要更整洁、可读性更高的写法,可借助Java 8 Lambda特性完成优化。原有实现代码如下:

static boolean duringWorkingHours(LocalDateTime dateTime){
    //MO - FR 08:00 - 12:30
    //MO - FR 14:00 - 18:00
    //SA      08:00 - 14:00

    LocalDateTime morningStart   = dateTime.with(LocalTime.of(8,0));
    LocalDateTime morningEnd     = dateTime.with(LocalTime.of(12,30));
    LocalDateTime afternoonStart = dateTime.with(LocalTime.of(14,0));
    LocalDateTime afternoonEnd   = dateTime.with(LocalTime.of(18,0));

    LocalDateTime saturdayStart  = dateTime.with(LocalTime.of(8,0));
    LocalDateTime saturdayEnd    = dateTime.with(LocalTime.of(14,0));

    Set<DayOfWeek> weekDays      = Set.of(DayOfWeek.MONDAY, DayOfWeek.TUESDAY, DayOfWeek.WEDNESDAY, DayOfWeek.THURSDAY,DayOfWeek.FRIDAY);

    boolean isWeekDay       = weekDays.contains(dateTime.getDayOfWeek());
    boolean isSaturday      = dateTime.getDayOfWeek() == DayOfWeek.SATURDAY;

    boolean isMorning       = (dateTime.isEqual(morningStart) || dateTime.isEqual(morningEnd))
            || (dateTime.isAfter(morningStart) && dateTime.isBefore(morningEnd));

    boolean isAfternoon     = (dateTime.isEqual(afternoonStart) || dateTime.isEqual(afternoonEnd))
            || (dateTime.isAfter(afternoonStart) && dateTime.isBefore(afternoonEnd));

    boolean isSaturdayRange = (dateTime.isEqual(saturdayStart) || dateTime.isEqual(saturdayEnd))
            || (dateTime.isAfter(saturdayStart) && dateTime.isBefore(saturdayEnd));

    return (isWeekDay && isMorning) || (isWeekDay && isAfternoon) || (isSaturday && isSaturdayRange);
}
优化方案

原有代码最大的冗余点是每次都基于传入时间构造多个LocalDateTime实例做区间判断,实际上只需要提取传入时间的DayOfWeek(判断周几)和LocalTime(判断当天时间点)即可完成校验,不需要构造多余的日期对象。
优化后将营业规则抽为静态配置,和判断逻辑解耦,借助Stream Lambda简化多时段匹配逻辑,代码如下:

import java.time.DayOfWeek;
import java.time.LocalDateTime;
import java.time.LocalTime;
import java.util.List;
import java.util.Map;

public class WorkingHoursValidator {
    // 抽离公共时段配置,避免重复定义
    private static final List<TimeRange> WEEKDAY_RANGES = List.of(
            new TimeRange(LocalTime.of(8, 0), LocalTime.of(12, 30)),
            new TimeRange(LocalTime.of(14, 0), LocalTime.of(18, 0))
    );
    private static final List<TimeRange> SATURDAY_RANGES = List.of(
            new TimeRange(LocalTime.of(8, 0), LocalTime.of(14, 0))
    );

    // 按星期几映射对应营业时段,后续调整规则直接修改该配置即可
    private static final Map<DayOfWeek, List<TimeRange>> WORKING_HOURS_RULES = Map.of(
            DayOfWeek.MONDAY, WEEKDAY_RANGES,
            DayOfWeek.TUESDAY, WEEKDAY_RANGES,
            DayOfWeek.WEDNESDAY, WEEKDAY_RANGES,
            DayOfWeek.THURSDAY, WEEKDAY_RANGES,
            DayOfWeek.FRIDAY, WEEKDAY_RANGES,
            DayOfWeek.SATURDAY, SATURDAY_RANGES
    );

    static boolean duringWorkingHours(LocalDateTime dateTime) {
        List<TimeRange> todayRanges = WORKING_HOURS_RULES.get(dateTime.getDayOfWeek());
        if (todayRanges == null) {
            return false; // 周日无营业配置直接返回false
        }
        LocalTime checkTime = dateTime.toLocalTime();
        // 用Lambda判断是否匹配任意一个营业时段
        return todayRanges.stream().anyMatch(range -> range.contains(checkTime));
    }

    // 内部时间区间类,封装闭区间判断逻辑
    private static class TimeRange {
        private final LocalTime start;
        private final LocalTime end;

        public TimeRange(LocalTime start, LocalTime end) {
            this.start = start;
            this.end = end;
        }

        public boolean contains(LocalTime time) {
            // 等价于 >= start 且 <= end,包含边界时间点
            return !time.isBefore(start) && !time.isAfter(end);
        }
    }
}
优化点说明
  • 去掉冗余的LocalDateTime构造:仅提取星期和时间点做判断,减少不必要的对象创建,逻辑更直观
  • 配置与逻辑解耦:营业规则统一维护在静态配置中,后续调整营业时间、新增营业时段不需要修改核心判断逻辑
  • 消除重复判断代码:抽离时间区间类统一做边界判断,避免多段重复的isEqual/isAfter/isBefore组合判断,降低出错概率
  • 用Stream的anyMatch实现多时段匹配,语义清晰,代码简洁
  • 公共时段复用:周一到周五的相同时段只定义一次,避免重复代码

内容的提问来源于stack exchange,提问作者bbKing

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.26 10:27:39