1.节气信息计算代码
package com.xkzhangsan.time.holiday; import java.time.DayOfWeek; import java.time.LocalDate; import java.time.MonthDay; import java.time.temporal.ChronoField; import java.time.temporal.ChronoUnit; import java.time.temporal.Temporal; import java.time.temporal.TemporalAdjusters; import java.util.Date; import java.util.Map; import java.util.Map.Entry; import java.util.Objects; import com.xkzhangsan.time.LunarDate; import com.xkzhangsan.time.constants.Constant; import com.xkzhangsan.time.converter.DateTimeConverterUtil; import com.xkzhangsan.time.formatter.DateTimeFormatterUtil; /** * 节日处理 * 包含 * 1.公历节假日计算, getLocalHoliday* 比如getLocalHoliday(Date date) 计算date的公历节日,getLocalHoliday(Map<String, String> localHolidayMap, Date date) 可以传入自定义节日数据 * 2.农历节假日计算, getChineseHoliday* 比如getChineseHoliday(Date date) 计算date的农历节日,getChineseHoliday(Map<String, String> chineseHolidayMap, Date date) 可以传入自定义节日数据 * 3.二十四节气计算, getSolarTerm* 比如getSolarTerm(Date date) 计算date的二十四节气 * * 农历相关,仅支持公历1901-1950年的计算 * @ClassName: Holiday * @Description: Holiday * @author xkzhangsan * @date 2019年12月30日 * @version 0.2 试用 */ public interface Holiday { /** * 根据日期获取公历节日 * @param date * @return */ static String getLocalHoliday(Date date){ return getLocalHoliday(null, date); } /** * 根据日期获取公历节日 * @param localHolidayMap 自定义节日数据,特殊节日如,"母亲节", "5-W-2-7" 5表示5月,W表示星期,2表示第二个星期,7表示星期的第7天 * @param date * @return */ static String getLocalHoliday(Map<String, String> localHolidayMap, Date date){ Objects.requireNonNull(date, "date"); return getLocalHoliday(localHolidayMap, DateTimeConverterUtil.toLocalDateTime(date)); } /** * 根据日期获取公历节日 * @param temporal * @return */ static String getLocalHoliday(Temporal temporal){ return getLocalHoliday(null, temporal); } /** * 根据日期获取公历节日 * @param localHolidayMap 自定义节日数据 * @param temporal * @return */ static String getLocalHoliday(Map<String, String> localHolidayMap, Temporal temporal){ Objects.requireNonNull(temporal, "temporal"); String localHoliday = ""; if(localHolidayMap == null || localHolidayMap.isEmpty()){ System.out.println("localHolidayMap is null, use default data"); localHolidayMap = LocalHolidayEnum.convertToMap(); } MonthDay monthDay = MonthDay.from(temporal); String monthDayStr = monthDay.format(DateTimeFormatterUtil.MMDD_FMT); for(Entry<String, String> entry : localHolidayMap.entrySet()){ if (entry.getKey().equals(monthDayStr)) { localHoliday = localHoliday + " " +entry.getValue(); } //如果为特殊格式,解析对比 if (entry.getKey().contains("W")) { String[] arr = entry.getKey().split("-"); int month = Integer.parseInt(arr[0]); int weekIndex = Integer.parseInt(arr[2]); int weekValue = Integer.parseInt(arr[3]); DayOfWeek dow = DayOfWeek.of(weekValue); //设置到当前节日的月份 Temporal tempTem = temporal.with(ChronoField.MONTH_OF_YEAR, month); //设置到当前节日的第几星期第几天 Temporal targetTem = tempTem.with(TemporalAdjusters.dayOfWeekInMonth(weekIndex, dow)); MonthDay targetMonthDay = MonthDay.from(targetTem); String targetMonthDayStr = targetMonthDay.format(DateTimeFormatterUtil.MMDD_FMT); if (monthDayStr.equals(targetMonthDayStr)) { localHoliday = localHoliday + " " +entry.getValue(); } } } return localHoliday; } /** * 根据日期获取农历几日 * @param date * @return */ static String getChineseHoliday(Date date){ return getChineseHoliday(null, date); } /** * 根据日期获取农历几日 * @param chineseHolidayMap 自定义节日数据,特殊节日如除夕 用CHUXI表示 * @param date * @return */ static String getChineseHoliday(Map<String, String> chineseHolidayMap, Date date){ Objects.requireNonNull(date, "date"); return getChineseHoliday(chineseHolidayMap, DateTimeConverterUtil.toLocalDateTime(date)); } /** * 根据日期获取农历几日 * @param temporal * @return */ static String getChineseHoliday(Temporal temporal){ return getChineseHoliday(null, temporal); } /** * 根据日期获取农历几日 * @param chineseHolidayMap 自定义节日数据 * @param temporal * @return */ static String getChineseHoliday(Map<String, String> chineseHolidayMap, Temporal temporal){ Objects.requireNonNull(temporal, "temporal"); String chineseHoliday = ""; if(chineseHolidayMap == null || chineseHolidayMap.isEmpty()){ System.out.println("chineseHolidayMap is null, use default data"); chineseHolidayMap = ChineseHolidayEnum.convertToMap(); } LunarDate lunarDate = LunarDate.from(temporal); String monthDayStr = lunarDate.formatShort(); //对比枚举日期,返回假日 for(Entry<String, String> entry : chineseHolidayMap.entrySet()){ if (entry.getKey().equals(monthDayStr)) { chineseHoliday = chineseHoliday + " " +entry.getValue(); } //如果为特殊节日除夕 if (entry.getKey().equals(Constant.CHUXI)) { LocalDate tempLocalDate = lunarDate.getLocalDate(); LocalDate targetLocalDate = tempLocalDate.plus(1, ChronoUnit.DAYS); LunarDate targetLunarDate = LunarDate.from(targetLocalDate); String targetMonthDayStr = targetLunarDate.formatShort(); if(Constant.CHUNJIE.equals(targetMonthDayStr)){ chineseHoliday = chineseHoliday + " " +entry.getValue(); } } } return chineseHoliday; } /** * 根据日期获取二十四节气 * @param date * @return */ static String getSolarTerm(Date date){ Objects.requireNonNull(date, "date"); LunarDate lunarDate = LunarDate.from(date); return lunarDate.getSolarTerm(); } /** * 根据日期获取二十四节气 * @param chineseHolidayMap * @param temporal * @return */ static String getSolarTerm(Temporal temporal){ Objects.requireNonNull(temporal, "temporal"); LunarDate lunarDate = LunarDate.from(temporal); return lunarDate.getSolarTerm(); } }
(1)getLocalHoliday(Map<String, String> localHolidayMap, Date date)中"母亲节", "5-W-2-7" 5表示5月,W表示星期,2表示第二个星期,7表示星期的第7天。
使用临时变量,修改月份为5月,然后使用TemporalAdjusters.dayOfWeekInMonth来计算当前月第几周第几天的日期和传入日期对比。
(2)getChineseHoliday(Map<String, String> chineseHolidayMap, Date date) 特殊节日如除夕 用CHUXI
除夕是一年的最后一天和闰年2月类似,具体日期不确定,使用临时变量,当前日期加一天后为春节,则传入日期为除夕。
(3)getSolarTerm(Date date)
这里使用LunarDate lunarDate = LunarDate.from(date),将当前日期转换为农历日期,获取它的节气信息。
具体可以看Java日期时间API系列11-----Jdk8中java.time包中的新的日期时间API类,使用java8日期时间API重写农历LunarDate 的calElement(int, int, int)方法。
2.测试代码
/** * 公历节日,母亲节 */ @Test public void localHolidayEnumTest(){ LocalDate localDate = LocalDate.of(2020, 5, 10); System.out.println(Holiday.getLocalHoliday(localDate)); //自定义节日数据 Map<String, String> localHolidayMap = new HashMap<String, String>(); localHolidayMap.put("0422", "世界地球日"); LocalDate localDate2 = LocalDate.of(2020, 4, 22); System.out.println(Holiday.getLocalHoliday(localHolidayMap, localDate2)); } /** * 农历节日,除夕 */ @Test public void chineseHolidayEnumTest(){ LocalDate localDate = LocalDate.of(2020, 1, 24); System.out.println(Holiday.getChineseHoliday(localDate)); } /** * 二十四节气,2020-08-07 立秋 */ @Test public void solarTermEnumTest(){ LocalDate localDate = LocalDate.of(2020, 8, 7); System.out.println(Holiday.getSolarTerm(localDate)); }
扫描二维码关注公众号,回复:
10060115 查看本文章
输出:
母亲节
世界地球日
除夕
立秋