org.openurp.base.edu.model.WeekTimeBuilder Maven / Gradle / Ivy
/*
* OpenURP, Agile University Resource Planning Solution.
*
* Copyright © 2014, The OpenURP Software.
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful.
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see .
*/
package org.openurp.base.edu.model;
import org.beangle.commons.bean.comparators.PropertyComparator;
import org.beangle.commons.collection.CollectUtils;
import org.beangle.commons.lang.tuple.Pair;
import org.beangle.orm.hibernate.udt.*;
import org.openurp.base.time.NumberRangeDigestor;
import org.openurp.base.time.NumberSequence;
import java.time.DayOfWeek;
import java.time.LocalDate;
import java.util.Calendar;
import java.util.*;
public class WeekTimeBuilder {
private final LocalDate startOn;
private final LocalDate firstWeekEndOn;
private WeekTimeBuilder(LocalDate startOn, WeekDay firstDay) {
super();
this.startOn = startOn;
LocalDate endOn = startOn;
WeekDay weekendDay = firstDay.previous();
while (endOn.getDayOfWeek().getValue() != weekendDay.getId()) {
endOn = endOn.plusDays(1);
}
firstWeekEndOn = endOn;
}
public static WeekTimeBuilder on(Semester semester) {
return new WeekTimeBuilder(semester.getBeginOn().toLocalDate(), semester.getCalendar().getFirstWeekday());
}
/**
* 这个方法都是在ftl里使用的
*
* @param time
* @return
*/
public static String digestWeekTime(WeekTime time, Semester semester) {
if (null == time) return "";
var dayofWeek = DayOfWeek.of(time.getWeekday().getId());
var firstDay = DayOfWeek.of(semester.getCalendar().getFirstWeekday().getId());
var beginOn = toDay(firstDay, semester.getBeginOn().toLocalDate(), dayofWeek);
LocalDate timeBeginOn = time.getStartOn().toLocalDate();
int weeksDistance = Weeks.between(beginOn, timeBeginOn);
long weekstate = time.getWeekstate().getValue();
if (weeksDistance < 0) {
weekstate >>= (0 - weeksDistance);
} else {
weekstate <<= weeksDistance;
}
Integer[] weekIndecies = new WeekState(weekstate).getWeekList().toArray(new Integer[0]);
String digest = NumberRangeDigestor.digest(weekIndecies, null);
return digest.replace("[", "").replace("]", "").replace("number.range.odd", "单")
.replace("number.range.even", "双");
}
public static List build(java.sql.Date beginOn, java.sql.Date endOn) {
Map timeMap = CollectUtils.newHashMap();
java.util.Calendar c = Calendar.getInstance();
java.util.Calendar e = Calendar.getInstance();
e.setTime(endOn);
c.setTime(beginOn);
while (!c.after(e)) {
WeekTime t = WeekTime.of(new java.sql.Date(c.getTime().getTime()));
WeekTime existed = timeMap.get(t.getStartOn());
if (null == existed) {
timeMap.put(t.getStartOn(), t);
} else {
existed.setWeekstate(existed.getWeekstate().bitor(t.getWeekstate()));
}
c.add(Calendar.DAY_OF_YEAR, 1);
}
List times = CollectUtils.newArrayList(timeMap.values());
Collections.sort(times, new PropertyComparator("startOn"));
return times;
}
public List buildOnOldWeekStr(WeekDay weekday, String weekstr) {
List weekList = new ArrayList();
for (int i = 0; i < weekstr.length(); i++) {
if (weekstr.charAt(i) == '1') weekList.add(i);
}
int[] weeks = new int[weekList.size()];
for (int i = 0; i < weekList.size(); i++) {
weeks[i] = weekList.get(i);
}
return build(weekday, weeks);
}
public static boolean needNormalize(WeekTime wt) {
int startYear = wt.getStartYear();
java.sql.Date lastDay = wt.getLastDay();
return startYear != lastDay.getYear() + 1900;
}
public static WeekTime normalize(WeekTime wt) {
int startYear = wt.getStartYear();
java.sql.Date lastDay = wt.getLastDay();
WeekTime nextWt = null;
while (startYear != lastDay.getYear() + 1900) {
if (null == nextWt) {
nextWt = new WeekTime();
nextWt.setBeginAt(wt.getBeginAt());
nextWt.setEndAt(wt.getEndAt());
nextWt.setStartOn(
java.sql.Date.valueOf(WeekTime.getStartOn(lastDay.getYear() + 1900, wt.getWeekday())));
nextWt.setWeekstate(WeekState.Zero);
}
wt.dropDay(lastDay);
nextWt.addDay(lastDay);
lastDay = wt.getLastDay();
}
return nextWt;
}
public static int getOffset(Semester semester, WeekDay weekday) {
LocalDate startOn = semester.getBeginOn().toLocalDate();
while (startOn.getDayOfWeek().getValue() != weekday.getId()) {
startOn = startOn.plusDays(1);
}
LocalDate yearStartOn = WeekTime.getStartOn(startOn.getYear(), weekday);
return Weeks.between(yearStartOn, startOn);
}
public static int getReverseOffset(Semester semester, WeekDay weekday) {
LocalDate startOn = semester.getBeginOn().toLocalDate();
while (startOn.getDayOfWeek().getValue() != weekday.getId()) {
startOn = startOn.plusDays(1);
}
LocalDate yearStartOn = WeekTime.getStartOn(startOn.getYear() + 1, weekday);
return Math.abs(Weeks.between(yearStartOn, startOn));
}
public List build(WeekDay weekday, Collection weeks) {
int[] weekIndices = new int[weeks.size()];
int i = 0;
for (Integer w : weeks) {
weekIndices[i] = w;
i += 1;
}
return build(weekday, weekIndices);
}
public List build(int startWeek, int endWeek) {
List weekdays = new ArrayList<>();
for (int i = startWeek; i < endWeek; i++) {
weekdays.add(i);
}
List times = new ArrayList<>();
for (WeekDay wd : WeekDay.getWeekdayArray(false)) {
times.addAll(build(wd, weekdays));
}
return times;
}
public List build(WeekDay weekday, int[] weeks) {
Map times = new HashMap();
LocalDate startDate = startOn;
while (startDate.getDayOfWeek().getValue() != weekday.getId()) {
startDate = startDate.plusDays(1);
}
int minWeek = 1;
if (startDate.isAfter(firstWeekEndOn)) minWeek = 2;
for (int week : weeks) {
if (week < minWeek) continue;
LocalDate oneday = startDate.plusWeeks(week - 1);
int year = oneday.getYear();
WeekTime weektime = times.get(year);
LocalDate yearStartOn = WeekTime.getStartOn(year, weekday);
if (null == weektime) {
weektime = new WeekTime();
times.put(year, weektime);
weektime.setStartOn(java.sql.Date.valueOf(yearStartOn));
weektime.setWeekstate(new WeekState(0));
}
weektime.setWeekstate(new WeekState(
weektime.getWeekstate().value | WeekState.of(Weeks.between(yearStartOn, oneday) + 1).value));
}
return new ArrayList(times.values());
}
public static List getYearStartOns(Semester semester, WeekDay weekday) {
int year = semester.getStartYear();
List dates = CollectUtils.newArrayList();
dates.add(java.sql.Date.valueOf(WeekTime.getStartOn(year, weekday)));
dates.add(java.sql.Date.valueOf(WeekTime.getStartOn(year, weekday)));
return dates;
}
public static java.sql.Date getStartOn(Semester semester, WeekDay weekday) {
LocalDate ld = semester.getBeginOn().toLocalDate();
while (ld.getDayOfWeek().getValue() != weekday.getId()) {
ld = ld.plusDays(1);
}
return java.sql.Date.valueOf(ld);
}
public static WeekTime of(int startWeek, int endWeek, NumberSequence.Pattern pattern) {
int[] range = NumberSequence.build(startWeek, endWeek, pattern);
WeekTime courseTime = new WeekTime();
courseTime.setWeekstate(WeekState.of(range));
return courseTime;
}
/**
* 构造某个日期(beginAt, endAt必须是同一天,只是时间不同)的WeekTime
*
* @param beginAt
* @param endAt
* @return
*/
public static WeekTime of(java.sql.Date startOn, HourMinute beginAt, HourMinute endAt) {
WeekTime time = WeekTime.of(startOn);
time.setBeginAt(beginAt);
time.setEndAt(endAt);
return time;
}
public static Pair getDateRange(Semester semester, int weekIndex) {
java.sql.Date beginOn = WeekTimeBuilder.on(semester)
.build(semester.getCalendar().getFirstWeekday(), new int[]{weekIndex}).get(0).getFirstDay();
LocalDate ld = beginOn.toLocalDate();
ld = ld.plusDays(6);
return Pair.of(beginOn, java.sql.Date.valueOf(ld));
}
public static java.sql.Date getDate(Semester semester, int teachWeek, WeekDay weekday) {
return WeekTimeBuilder.on(semester).build(weekday, new int[]{teachWeek}).get(0).getFirstDay();
}
public static int weekIndexOf(Semester semester, java.sql.Date oneday) {
LocalDate beginOn = semester.getBeginOn().toLocalDate();
int firstWeekday = beginOn.getDayOfWeek().getValue();
LocalDate timeBeginOn = oneday.toLocalDate();
while (timeBeginOn.getDayOfWeek().getValue() != firstWeekday) {
timeBeginOn = timeBeginOn.plusDays(-1);
}
return Weeks.between(beginOn, timeBeginOn);
}
public static int getStartYear(Semester semester) {
if (null != semester.getBeginOn()) {
GregorianCalendar gc = new GregorianCalendar();
gc.setTime(semester.getBeginOn());
return gc.get(Calendar.YEAR);
}
return 0;
}
public static WeekDay[] getWeekDays(Semester semester) {
boolean isSundayFirst = semester.getCalendar().getFirstWeekday().equals(WeekDay.Sun);
return WeekDay.getWeekdayArray(isSundayFirst);
}
public static WeekState collect(Semester semester, Collection dates) {
var dayofWeek = DayOfWeek.of(semester.getCalendar().getFirstWeekday().getId());
var semesterFirstday = toDay(dayofWeek, semester.getBeginOn().toLocalDate(), dayofWeek);
Set weeks = new HashSet<>();
for (LocalDate date : dates) {
var oneday = toDay(dayofWeek, date, dayofWeek);
var weekIdx = 1 + Weeks.between(semesterFirstday, oneday);
weeks.add(weekIdx);
}
return WeekState.of(new ArrayList<>(weeks));
}
private static LocalDate toDay(DayOfWeek firstDay, LocalDate date, DayOfWeek day) {
if (date.getDayOfWeek() == day) {
return date;
} else {
if (firstDay == DayOfWeek.MONDAY) {
var offset = day.getValue() - date.getDayOfWeek().getValue();
return date.plusDays(offset);
} else if (firstDay == DayOfWeek.SUNDAY) {
if (day == DayOfWeek.SUNDAY) {
var offset = day.getValue() - date.getDayOfWeek().getValue() - 7;
return date.plusDays(offset);
} else {
return date.plusDays(day.getValue() - date.getDayOfWeek().getValue());
}
} else {
throw new RuntimeException("Cannot accept first day " + firstDay);
}
}
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy