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

如何在Thymeleaf的th:each中按日期过滤集合?

解决Thymeleaf th:each嵌套迭代中的日期过滤问题

问题根源分析

你遇到的问题核心有两点:

  1. Date对象构造错误:Java的java.util.Date(int year, int month, int date)构造器中,year需传入年份-1900,month是0~11的索引值。你写的new Date(2024,11,10)实际生成的是3924年12月10日,完全偏离预期日期。
  2. Date对象比较精度问题:直接用eq比较两个Date对象会精确到毫秒,数据库返回的dateAppointment通常包含具体时间(如2024-11-10 14:30:00),但你构造的days是当天0点的日期,两者毫秒数不同导致匹配失败。

方案一:前端修正过滤逻辑(适合小数据量场景)

先修正后端Date对象的创建方式,再在Thymeleaf中通过日期格式化后比较年/月/日部分:

后端修正Date创建代码

import java.time.LocalDate;
import java.time.ZoneId;
import java.util.Date;
import java.util.List;
import java.util.Arrays;

// 生成正确的2024-11-10和2024-12-05的Date对象
LocalDate date1 = LocalDate.of(2024, 11, 10);
Date day1 = Date.from(date1.atStartOfDay(ZoneId.systemDefault()).toInstant());

LocalDate date2 = LocalDate.of(2024, 12, 5);
Date day2 = Date.from(date2.atStartOfDay(ZoneId.systemDefault()).toInstant());

List<Date> days = Arrays.asList(day1, day2);
model.addAttribute("days", days);

// 预约数据获取逻辑不变
List<oCalendar> calendaries = myRepository.findAppointmentBeginEnd(dateBegin, dateEnd);
model.addAttribute("calendaries", calendaries);

前端Thymeleaf过滤代码

<tr th:each="day : ${days}">
    <!-- 通过格式化日期为统一格式,只比较年/月/日部分 -->
    <tr th:each="cal : ${calendaries.?[#dates.format(dateAppointment, 'yyyy-MM-dd') == #dates.format(day, 'yyyy-MM-dd')]}">
        <td th:text="${#dates.format(cal.dateAppointment, 'yyyy-MM-dd HH:mm')}"></td>
        <td th:text="${cal.hourAppointment}"></td>
    </tr>
</tr>

方案二:后端提前分组(性能更优,推荐)

避免前端循环过滤的性能损耗,在后端将预约数据按日期分组,前端直接根据日期取对应数据:

后端分组代码

import java.time.LocalDate;
import java.time.ZoneId;
import java.util.Date;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

// 生成LocalDate类型的日期列表(替代原Date类型的days)
List<LocalDate> dayList = List.of(
    LocalDate.of(2024, 11, 10),
    LocalDate.of(2024, 12, 5)
);
model.addAttribute("dayList", dayList);

// 预约数据按日期分组
List<oCalendar> calendaries = myRepository.findAppointmentBeginEnd(dateBegin, dateEnd);
Map<LocalDate, List<oCalendar>> calendarMap = calendaries.stream()
    .collect(Collectors.groupingBy(cal -> 
        // 将Date转成LocalDate,提取日期部分
        cal.getDateAppointment().toInstant().atZone(ZoneId.systemDefault()).toLocalDate()
    ));
model.addAttribute("calendarMap", calendarMap);

前端渲染代码

<tr th:each="localDay : ${dayList}">
    <!-- 直接获取当前日期对应的预约列表,无数据时显示空列表 -->
    <tr th:each="cal : ${calendarMap.get(localDay) ?: #lists.emptyList()}">
        <td th:text="${#dates.format(cal.dateAppointment, 'yyyy-MM-dd HH:mm')}"></td>
        <td th:text="${cal.hourAppointment}"></td>
    </tr>
</tr>

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.15 23:04:57