package cn.teammodel.utils; import cn.teammodel.common.CommonConstant; import cn.teammodel.config.exception.ServiceException; import cn.teammodel.model.entity.school.School; import org.apache.commons.lang3.tuple.Pair; import java.time.LocalDate; import java.util.Comparator; import java.util.List; /** * 学校中年级,学年,日期相关的工具类 * @author winter * @create 2023-11-28 10:15 */ public class SchoolDateUtil { /** * 通过当前时间与学校的学期安排获取当前的学年 * 学校学期: *
* "semesters": [ * { * "name": "下学期", * "start": 0, * "month": 3, * "day": 1, * "id": "2" * }, * { * "name": "上学期", * "start": 1, * "month": 9, * "day": 1, * "id": "1" * } * ** 示例: 传参 2023.11.28 返回 2023学年上学期 * 注意: 处理跨年问题 -> 2024.1.1, 应该也是 2023学年上学期,同时你需要注意,semesters 可能不止两个学期 *
*/ public static PairgetSemesterByNow(List semesters, LocalDate date) { if (semesters == null || semesters.isEmpty() || date == null) { throw new ServiceException("semesters and date must not be null or empty."); } // 将 semester 根据大小排序 semesters.sort(Comparator.comparing(s -> LocalDate.of(date.getYear(), s.getMonth(), s.getDay()))); // i = 0 的日期是开学最早, i = size - 1 是开学最晚 int size = semesters.size(); // 拿到最晚开学的日期,将年份 - 1后,与头节点组成可跨年区间 School.Semester lastSemester = semesters.get(size - 1); LocalDate lastSemesterStart = LocalDate.of(date.getYear() - 1, lastSemester.getMonth(), lastSemester.getDay()); String lastSemesterId = lastSemester.getId(); for (School.Semester semester : semesters) { // 特判头尾的提起,分别将学期区间提前和延后一年(不用延后),例如 2023.3.1 与 2023.9.1 我们分别向添加一个节点,划分其为 3 个区间: // 2022.9.1 - 2023.3.1, 2023.3.1 - 2023.9.1, 2023.9.1 - 2024.3.1 LocalDate curSemesterStart = LocalDate.of(date.getYear(), semester.getMonth(), semester.getDay()); if (date.isEqual(lastSemesterStart) || date.isAfter(lastSemesterStart) && date.isBefore(curSemesterStart)) { return Pair.of(lastSemesterId, lastSemesterStart); } lastSemesterStart = curSemesterStart; lastSemesterId = semester.getId(); } // 剩下的时间段, 学年应该就是最后一个学年 return Pair.of(lastSemester.getId(), LocalDate.of(date.getYear(), lastSemester.getMonth(), lastSemester.getDay())); } /** * 返回 ID -> 学年(组合 id: 学年-semesterId -> 2023-{semesterId}) */ public static String generateAcademicId(List semesters, LocalDate date) { Pair pair = getSemesterByNow(semesters, date); String semesterId = pair.getLeft(); LocalDate academicYear = pair.getRight(); return academicYear.getYear() + CommonConstant.DASH + semesterId; } }