一些项目中会有日历或日期设置,最基本的会显示工作日,休息日,节假日等等,下面就是基于项目中的日历管理功能,要显示工作日,休息日,节假日
public class HolidayUtils {
private static Logger logger = LoggerFactory.getLogger(HolidayUtils.class);
public static Map<String,Map<String,OtherData>> monthToHolidayDate = new ConcurrentHashMap<>(12);
public static Map<String,OtherData> dateToOtherData = new ConcurrentHashMap<>(12);
public static void main(String[] args) {
System.out.println(getAllHoliday(2024));
}
/**
* 获取周末和节假日
*
* @param year
* @return
*/
public static List<String> getAllHoliday(int year) {
// 获取所有的周末
Set<String> allWeekend = getAllWeekend(year);
// http://timor.tech/api/holiday api文档地址
Map apiHoliday = getApiHoliday(year);
Integer code = (Integer) apiHoliday.get("code");
if (code != 0) {
return null;
}
Map<String, Map<String, Object>> holiday = (Map<String, Map<String, Object>>) apiHoliday.get("holiday");
Set<String> strings = holiday.keySet();
for (String str : strings) {
Map<String, Object> stringObjectMap = holiday.get(str);
Integer wage = (Integer) stringObjectMap.get("wage");
String date = (String) stringObjectMap.get("date");
//筛选掉补班
if (wage.equals(1)) {
allWeekend.remove(date);
} else {
allWeekend.add(date);
}
int monthByDate = CalendarUtils.getMonthByDate(CalendarUtils.parseDateStrToDate(date, "yyyy-MM-dd"));
if (!monthToHolidayDate.containsKey(monthByDate)){
monthToHolidayDate.put(monthByDate+"",new HashMap<>());
}
Map<String, OtherData> dateToOtherData = monthToHolidayDate.get(monthByDate);
if (dateToOtherData == null) dateToOtherData = new HashMap<>();
if (!dateToOtherData.containsKey(date)){
OtherData otherData = new OtherData();
otherData.putAll(stringObjectMap);
dateToOtherData.put(date,otherData);
dateToOtherData.put(date,otherData);
}
}
List<String> result = new ArrayList<>(allWeekend);
result = result.stream().sorted().collect(Collectors.toList());
return result;
}
/**
* 获取节假日不含周末
*
* @param year
* @return
*/
private static Map getApiHoliday(int year) {
String url = "http://timor.tech/api/holiday/year/" + year;
String rsa = HttpUtil.get(url);
logger.info("rsa:{}",rsa);
Map map = JsonConverter.jsonStrToObject(rsa, Map.class);
return map;
}
/**
* 获取周末 月从0开始
*
* @param year
* @return
*/
public static Set<String> getAllWeekend(int year) {
Set<String> dateList = new HashSet<>();
SimpleDateFormat simdf = new SimpleDateFormat("yyyy-MM-dd");
Calendar calendar = new GregorianCalendar(year, 0, 1);
Calendar endCalendar = new GregorianCalendar(year, 11, 31);
while (true) {
int weekday = calendar.get(Calendar.DAY_OF_WEEK);
if (weekday == 1 || weekday == 7) {
dateList.add(simdf.format(calendar.getTime()));
}
calendar.add(Calendar.DATE, 1);
if (calendar.getTimeInMillis() >= endCalendar.getTimeInMillis()) {
break;
}
}
return dateList;
}
public static Map<String,OtherData> getHolidayByMonth(String month,Date date){
if (monthToHolidayDate == null) return new HashMap<>();
if (StringUtils.isNotBlank(month)){
month = CalendarUtils.getMonthByDate(date) + "";
Map<String, OtherData> dateToOtherData = monthToHolidayDate.get(month);
if (dateToOtherData == null) dateToOtherData = new HashMap<>();
return dateToOtherData;
}
return new HashMap<>();
}
public static OtherData getHolidayByDate(Date date){
String month = CalendarUtils.getMonthByDate(date) + "";
Map<String, OtherData> dateToOtherData = monthToHolidayDate.get(month);
if (dateToOtherData == null || dateToOtherData.size() == 0) return null;
String dateStr = CalendarUtils.toString(date, "yyyy-MM-dd");
OtherData otherData = dateToOtherData.get(dateStr);
if (otherData != null && otherData.obtainVal("wage",Integer.class) != null
&& 1 == otherData.obtainVal("wage",Integer.class)){
return null;
}
return otherData;
}
public static String isHoliday(Date date){
String month = CalendarUtils.getMonthByDate(date) + "";
Map<String, OtherData> dateToOtherData = monthToHolidayDate.get(month);
if (dateToOtherData == null || dateToOtherData.size() == 0) return null;
String dateStr = CalendarUtils.toString(date, "yyyy-MM-dd");
OtherData otherData = dateToOtherData.get(dateStr);
if (otherData == null) return null;
if (otherData != null && otherData.obtainVal("wage",Integer.class) != null
&& 1 == otherData.obtainVal("wage",Integer.class)){
return DateRec.DATE_TYPE_WORK;
}
return DateRec.DATE_TYPE_HOLIDAY;
}
}
{
"code": 0,
"holiday": {
"01-01": {
"holiday": true,
"name": "元旦",
"wage": 3,
"date": "2024-01-01",
"rest": 1
},
"02-04": {
"holiday": false,
"name": "春节前补班",
"wage": 1,
"after": false,
"target": "春节",
"date": "2024-02-04",
"rest": 9
},
"02-10": {
"holiday": true,
"name": "初一",
"wage": 3,
"date": "2024-02-10",
"rest": 15
},
"02-11": {
"holiday": true,
"name": "初二",
"wage": 3,
"date": "2024-02-11",
"rest": 1
},
"02-12": {
"holiday": true,
"name": "初三",
"wage": 3,
"date": "2024-02-12"
},
"02-13": {
"holiday": true,
"name": "初四",
"wage": 2,
"date": "2024-02-13"
},
"02-14": {
"holiday": true,
"name": "初五",
"wage": 2,
"date": "2024-02-14"
},
"02-15": {
"holiday": true,
"name": "初六",
"wage": 2,
"date": "2024-02-15"
},
"02-16": {
"holiday": true,
"name": "初七",
"wage": 2,
"date": "2024-02-16"
},
"02-17": {
"holiday": true,
"name": "初八",
"wage": 2,
"date": "2024-02-17"
},
"02-18": {
"holiday": false,
"name": "春节后补班",
"wage": 1,
"after": true,
"target": "春节",
"date": "2024-02-18"
},
"04-04": {
"holiday": true,
"name": "清明节",
"wage": 3,
"date": "2024-04-04",
"rest": 46
},
"04-05": {
"holiday": true,
"name": "清明节",
"wage": 2,
"date": "2024-04-05"
},
"04-06": {
"holiday": true,
"name": "清明节",
"wage": 2,
"date": "2024-04-06"
},
"04-07": {
"holiday": false,
"name": "清明节后补班",
"wage": 1,
"target": "清明节",
"after": true,
"date": "2024-04-07"
},
"04-28": {
"holiday": false,
"name": "劳动节前补班",
"wage": 1,
"target": "劳动节",
"after": false,
"date": "2024-04-28"
},
"05-01": {
"holiday": true,
"name": "劳动节",
"wage": 3,
"date": "2024-05-01"
},
"05-02": {
"holiday": true,
"name": "劳动节",
"wage": 2,
"date": "2024-05-02",
"rest": 1
},
"05-03": {
"holiday": true,
"name": "劳动节",
"wage": 3,
"date": "2024-05-03"
},
"05-04": {
"holiday": true,
"name": "劳动节",
"wage": 3,
"date": "2024-05-04"
},
"05-05": {
"holiday": true,
"name": "劳动节",
"wage": 3,
"date": "2024-05-05"
},
"05-11": {
"holiday": false,
"name": "劳动节后补班",
"after": true,
"wage": 1,
"target": "劳动节",
"date": "2024-05-11"
},
"06-08": {
"holiday": true,
"name": "端午节",
"wage": 2,
"date": "2024-06-08"
},
"06-09": {
"holiday": true,
"name": "端午节",
"wage": 2,
"date": "2024-06-09"
},
"06-10": {
"holiday": true,
"name": "端午节",
"wage": 3,
"date": "2024-06-10"
},
"09-14": {
"holiday": false,
"name": "中秋节前补班",
"after": false,
"wage": 1,
"target": "中秋节",
"date": "2024-09-14",
"rest": 96
},
"09-15": {
"holiday": true,
"name": "中秋节",
"wage": 2,
"date": "2024-09-15",
"rest": 97
},
"09-16": {
"holiday": true,
"name": "中秋节",
"wage": 2,
"date": "2024-09-16"
},
"09-17": {
"holiday": true,
"name": "中秋节",
"wage": 3,
"date": "2024-09-17"
},
"09-29": {
"holiday": false,
"name": "国庆节前补班",
"after": false,
"wage": 1,
"target": "国庆节",
"date": "2024-09-29"
},
"10-01": {
"holiday": true,
"name": "国庆节",
"wage": 3,
"date": "2024-10-01"
},
"10-02": {
"holiday": true,
"name": "国庆节",
"wage": 3,
"date": "2024-10-02",
"rest": 1
},
"10-03": {
"holiday": true,
"name": "国庆节",
"wage": 3,
"date": "2024-10-03"
},
"10-04": {
"holiday": true,
"name": "国庆节",
"wage": 2,
"date": "2024-10-04"
},
"10-05": {
"holiday": true,
"name": "国庆节",
"wage": 2,
"date": "2024-10-05"
},
"10-06": {
"holiday": true,
"name": "国庆节",
"wage": 2,
"date": "2024-10-06",
"rest": 1
},
"10-07": {
"holiday": true,
"name": "国庆节",
"wage": 2,
"date": "2024-10-07",
"rest": 1
},
"10-12": {
"holiday": false,
"after": true,
"wage": 1,
"name": "国庆节后补班",
"target": "国庆节",
"date": "2024-10-12"
}
}
}
@Entity
@Table(
name = "t_daterec",
indexes={
@Index(name="idx_t_daterec1",columnList="dateType"),
@Index(name="idx_t_daterec2",columnList="dateTime")
}
)
public class DateRec extends ExBizEntity {
public static final String DATE_TYPE_WORK = "work";
public static final String DATE_TYPE_WEEKEND = "weekend";
public static final String DATE_TYPE_HOLIDAY = "holiday";
@Column(length=20,nullable=false)
private String dateType;//日历类型
private Date dateTime;//日期
public String getDateType() {
return dateType;
}
public Date getDateTime() {
return dateTime;
}
public DateRec() {
}
public DateRec(String id,String dateType, Date dateRTime) {
this.id = id;
this.dateType = dateType;
this.dateTime = dateTime;
}
}
@Entity
@Table(
name = "t_holiday",
indexes={
@Index(name="idx_t_holiday1",columnList="holidayDate")
}
)
public class Holiday extends ExBizEntity{
private Date holidayDate;
public Holiday() {
}
public Holiday(Date holidayDate) {
this.holidayDate = holidayDate;
}
public Date getHolidayDate() {
return holidayDate;
}
}
@MappedSuperclass
public abstract class ExBizEntity extends ValueObjectEntity {
@Type(type="com.xysd.common.utils.hibernateType.MyCustomJsonType")
private OtherData exAttr = new OtherData();//额外属性map
public OtherData getExAttr() {
return exAttr;
}
protected ExBizEntity(){
super();
}
protected ExBizEntity(Map<String, Object> exAttr) {
super();
this.getNotNullExAttrWithUpdate().putAll(exAttr);
}
//获取非空扩展属性
private OtherData getNotNullExAttrWithUpdate() {
if(this.exAttr == null) this.exAttr = new OtherData();
return this.exAttr;
}
public void clearExAttr(){
this.exAttr = null;
}
//更新扩展属性
public void updateExAttr(Map<String, Object> exAttr){
this.getNotNullExAttrWithUpdate().clear();
if(exAttr==null) {
this.exAttr = null;
return;
}
this.addAttrs(exAttr);
}
//添加扩展属性
public void addAttr(String key, Object value){
if(StringUtils.isBlank(key)) return;
if(value==null) {
this.getNotNullExAttrWithUpdate().remove(key);
}else {
this.getNotNullExAttrWithUpdate().put(key, value);
}
}
//添加扩展属性
public void addAttrs(Map<String, Object> exAttr){
if(exAttr==null) return;
for (Map.Entry<String,Object> e : exAttr.entrySet()) {
this.addAttr(e.getKey(), e.getValue());
}
}
//获取指定类型的对象
@Transient
public <T> T getAttr(String key) {
if(this.exAttr==null) return null;
return this.exAttr.obtainVal(key);
}
//获取指定类型的对象
@Transient
public <T> T getAttr(String key, Class<T> valClass) {
if(this.exAttr==null) return null;
return this.exAttr.obtainVal(key, valClass);
}
//获取指定转换类型的对象
@Transient
public <T> T getAttr(String key, TypeReference<T> valTypeRef) {
if(this.exAttr==null) return null;
return this.exAttr.obtainVal(key, valTypeRef);
}
}
@MappedSuperclass
public abstract class ValueObjectEntity extends IEntity{
public static String SYSCODE_CAD="cad";//系统编码-cad:cad接口
protected Date createTime = new Date();//创建时间
@Type(type = "org.hibernate.type.NumericBooleanType")
protected boolean history=false;
@Column(length=40)
protected String createIp;//创建时的ip
protected int valid=1;//有效性
protected Date lastUpdateDate = new Date();//最后更新时间
@Column(length=10)
protected String syscode=SYSCODE_HDXF; //数据系统编码
public Date getCreateTime() {
return createTime;
}
public boolean isHistory() {
return history;
}
public String getCreateIp() {
return createIp;
}
public int getValid() {
return valid;
}
public Date getLastUpdateDate() {
return lastUpdateDate;
}
public String getSyscode() {
return syscode;
}
protected ValueObjectEntity() {
super();
}
@Transient
public boolean isValidEntity(){
return this.getValid()==1;
}
public void updateValid(int valid){
this.valid = valid;
}
}
@MappedSuperclass
public abstract class IEntity {
@Id
@Column(length=100)
@GeneratedValue(generator="uuidkey")
@GenericGenerator(name="uuidkey", strategy = "com.xysd.common.utils.BaseIDGenerator")
protected String id;
public String getId() {
return this.id;
}
/**
* 对比俩个实体是否是同一个
*/
public boolean compareObject(IEntity other) {
return other != null && new EqualsBuilder().
append(this.id, other.getId()).
isEquals();
}
}
public class BaseIDGenerator implements IdentifierGenerator {
private static AutoIncrementIdUtil autoIncrementIdUtil;
public static void registAutoIncrementIdUtil(AutoIncrementIdUtil autoIncrementIdUtil){
BaseIDGenerator.autoIncrementIdUtil = autoIncrementIdUtil;
}
@Override
public Serializable generate(SharedSessionContractImplementor arg0,
Object o) throws HibernateException {
if(o instanceof NeedAutoIncrementId){
NeedAutoIncrementId entity = (NeedAutoIncrementId) o;
String id = entity.obtainId();
if(!StringUtils.isEmpty(id)){
entity.initId(id);
}else {
id = autoIncrementIdUtil.getId(entity.getClass().getSimpleName(), entity.obtainParentId(),
entity.obtainLength(), entity.obtainSeparator());
entity.initId(id);
}
return id;
}
if(o instanceof IEntity){
//允许自己指定ID
IEntity be = (IEntity)o;
if(StringUtils.isNotBlank(be.getId())){
return be.getId();
}
}
return Utils.getUUID("");
}
}
@ApiOperation(value="日历管理查看",httpMethod="GET")
@ApiImplicitParams({
@ApiImplicitParam(name="year",value="年份",required=true),
@ApiImplicitParam(name="month",value="月份",required=true)
})
@RequestMapping(value = "/dates/list", method = RequestMethod.GET)
public String getDates(@RequestParam int year, @RequestParam int month, HttpServletRequest hreq) {
String weeks = myService.getDates(year,month);
return weeks;
}
}
@Service
public class MyService {
@Autowired
private DateRecRepositoryHibernate dateRecRepositoryHibernate;
@PostConstruct
public void init(){
//加载国家法定节假日
HolidayUtils.getAllHoliday(CalendarUtils.getCurrentYear());
Map<String, OtherData> dateToOtherData = HolidayUtils.dateToOtherData;
List<Holiday> holidays = this.dateRecRepositoryHibernate.getHolidays();
if (CollectionUtils.isNotEmpty(holidays)) {
for (Holiday holiday : holidays) {
HolidayUtils.dateToOtherData.put(CalendarUtils.toString(holiday.getHolidayDate(), "yyyy-MM-dd"), holiday.getExAttr());
}
} else {
for (Map.Entry<String, OtherData> entry : dateToOtherData.entrySet()) {
Holiday h = new Holiday(CalendarUtils.parseDateStrToDate(entry.getKey(), "yyyy-MM-dd"));
h.addAttrs(entry.getValue());
this.dateRecRepositoryHibernate.createOrUpdateHoliday(h);
}
}
}
public String getDates(int year, int month) {
//要返回前端展示使用
List<WeekDTO> weeks = new ArrayList<WeekDTO>();
//获取year年month月的第一天
Date monthBegin = CalendarUtils.getMonthBeginByYearAndMonth(year, month);
//获取year年month月的最后一天
Date monthEnd = CalendarUtils.getMonthEndByYearAndMonth(year, month);
WeekValObj wo = CalendarUtils.getWeekValObjByDateOfYear(monthBegin);
//获取year年month月的第一天是这一年中第几周
int weekNumOfMonthBegin = wo.getWeek();
//selectYear就是year
int selectedYear = wo.getYear();
Map<String, DateDTO> allDates = new HashMap<String, DateDTO>();
List<String> dates = new ArrayList<String>();
int weekNum = 7;
for (int k = 0; k < weekNum; k++) {
//获取selectyear年总共有几周
int maxWeekOfYear = CalendarUtils.getMaxWeekCountByYear(selectedYear);
//获取selectedYear年第weekNumOfMonthBegin周的第一天日期
Date weekBegin = CalendarUtils.getWeekBeginByYearAndWeek(selectedYear, weekNumOfMonthBegin);
List<DateDTO> weekDates = new ArrayList<DateDTO>();
if (weekBegin == null) {//如果没有获取到 则默认为year+1年的第一周的第一天日期
weekBegin = CalendarUtils.getWeekBeginByYearAndWeek(year + 1, 1);
}
if (weekBegin != null && weekBegin.getTime() < monthEnd.getTime()) {
for (int i = 0; i < 7; i++) {
//开始取第weekNumOfMonthBegin周的第i天
Date d = DateUtils.addDays(weekBegin, i);
String type = null;
if (StringUtils.isNotBlank(HolidayUtils.isHoliday(d))) {
type = HolidayUtils.isHoliday(d);
} else {
type = DateRec.DATE_TYPE_WORK;
if (i >= 5) {
type = DateRec.DATE_TYPE_WEEKEND;
}
}
//是否要展示
boolean display = d.getTime() >= monthBegin.getTime() && d.getTime() <= monthEnd.getTime();
String dateStr = CalendarUtils.toString(d, "yyyy-MM-dd");
DateDTO dateDTO = new DateDTO(dateStr, type, display);
weekDates.add(dateDTO);
allDates.put(dateDTO.getDate(), dateDTO);
}
weeks.add(new WeekDTO(year, weekNumOfMonthBegin, weekDates));
}
if (weekNumOfMonthBegin >= maxWeekOfYear) {
selectedYear++;
weekNumOfMonthBegin = 1;
} else {
weekNumOfMonthBegin++;
}
}
dates.addAll(allDates.keySet());
Map<String, Object> params = new HashMap<>();
params.put("dates", dates);
List<DateRec> existedDateRecs = this.dateRecRepositoryHibernate.getDateRecBy(params);
for (DateRec drec : existedDateRecs) {
//已存在的
DateDTO dto = allDates.remove(drec.getId());
if (dto != null) {
dto.setDateType(drec.getDateType());
}
}
for (DateDTO dto : allDates.values()) {
//需要创建的
DateRec drec = new DateRec(dto.getDate(),dto.getDateType(), CalendarUtils.parseDateStrToDate(dto.getDate(), "yyyy-MM-dd"));
this.dateRecRepositoryHibernate.createOrUpdateDateRec(drec);
}
return JsonConverter.toJsonStr(weeks);
}
}
@Repository
public class DateRecRepositoryHibernate extends JpaHibernateRepository {
public void createOrUpdateDateRec(DateRec dateRec){
this.getSession().saveOrUpdate(dateRec);
}
public List<DateRec> getDateRecBy(Map<String,Object> params){
StringBuffer sql = new StringBuffer();
sql.append(" select id from t_daterec where valid = 1 ");
if (params.get("ids") != null){
sql.append(" and id in (:ids) ");
}
if (params.get("dates") != null){
sql.append(" and date in (:dates) ");
}
if (params.get("dateTypes") != null){
sql.append(" and date_type in (:dateTypes) ");
}
List<String> ids = this.createSQLQueryByMapParams(sql.toString(), params).list();
if (CollectionUtils.isEmpty(ids)) return new ArrayList<>();
List<DateRec> recs = this.findByOrderedIds(DateRec.class, ids);
if (recs == null) return new ArrayList<>();
return recs;
}
public void createOrUpdateHoliday(Holiday holiday){
this.getSession().saveOrUpdate(holiday);
}
public List<Holiday> getHolidays(){
String sql = "select d from " + Holiday.class.getName() + " d where d.holidayDate >= : begin and d.holidayDate <= :end ";
List<Holiday> list = this.createHQLQueryByMapParams(Holiday.class, sql, Utils.buildMap("begin", CalendarUtils.getCurrentYearBeginDate(), "end", CalendarUtils.getCurrentYearEndDate())).list();
if (list == null) list = new ArrayList<>();
return list;
}
}
[
{
"year": 2024,
"weekNum": 5,
"dates": [
{
"date": "2024-01-29",
"dateType": "work",
"display": false
},
{
"date": "2024-01-30",
"dateType": "work",
"display": false
},
{
"date": "2024-01-31",
"dateType": "work",
"display": false
},
{
"date": "2024-02-01",
"dateType": "work",
"display": true
},
{
"date": "2024-02-02",
"dateType": "work",
"display": true
},
{
"date": "2024-02-03",
"dateType": "weekend",
"display": true
},
{
"date": "2024-02-04",
"dateType": "weekend",
"display": true
}
]
},
{
"year": 2024,
"weekNum": 6,
"dates": [
{
"date": "2024-02-05",
"dateType": "work",
"display": true
},
{
"date": "2024-02-06",
"dateType": "work",
"display": true
},
{
"date": "2024-02-07",
"dateType": "work",
"display": true
},
{
"date": "2024-02-08",
"dateType": "work",
"display": true
},
{
"date": "2024-02-09",
"dateType": "work",
"display": true
},
{
"date": "2024-02-10",
"dateType": "weekend",
"display": true
},
{
"date": "2024-02-11",
"dateType": "weekend",
"display": true
}
]
},
{
"year": 2024,
"weekNum": 7,
"dates": [
{
"date": "2024-02-12",
"dateType": "work",
"display": true
},
{
"date": "2024-02-13",
"dateType": "work",
"display": true
},
{
"date": "2024-02-14",
"dateType": "work",
"display": true
},
{
"date": "2024-02-15",
"dateType": "work",
"display": true
},
{
"date": "2024-02-16",
"dateType": "work",
"display": true
},
{
"date": "2024-02-17",
"dateType": "weekend",
"display": true
},
{
"date": "2024-02-18",
"dateType": "weekend",
"display": true
}
]
},
{
"year": 2024,
"weekNum": 8,
"dates": [
{
"date": "2024-02-19",
"dateType": "work",
"display": true
},
{
"date": "2024-02-20",
"dateType": "work",
"display": true
},
{
"date": "2024-02-21",
"dateType": "work",
"display": true
},
{
"date": "2024-02-22",
"dateType": "work",
"display": true
},
{
"date": "2024-02-23",
"dateType": "work",
"display": true
},
{
"date": "2024-02-24",
"dateType": "weekend",
"display": true
},
{
"date": "2024-02-25",
"dateType": "weekend",
"display": true
}
]
},
{
"year": 2024,
"weekNum": 9,
"dates": [
{
"date": "2024-02-26",
"dateType": "work",
"display": true
},
{
"date": "2024-02-27",
"dateType": "work",
"display": true
},
{
"date": "2024-02-28",
"dateType": "work",
"display": true
},
{
"date": "2024-02-29",
"dateType": "work",
"display": true
},
{
"date": "2024-03-01",
"dateType": "work",
"display": false
},
{
"date": "2024-03-02",
"dateType": "weekend",
"display": false
},
{
"date": "2024-03-03",
"dateType": "weekend",
"display": false
}
]
}
]