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;
import com.xkzhangsan.time.utils.CollectionUtil;
import com.xkzhangsan.time.utils.StringUtil; /**
* 节日处理
* 包含
* 1.公历节假日计算, getLocalHoliday* 比如getLocalHoliday(Date date) 计算date的公历节日,getLocalHoliday(Date date, Map<String, String> localHolidayMap) 可以传入自定义公历节日数据
* 2.农历节假日计算, getChineseHoliday* 比如getChineseHoliday(Date date) 计算date的农历节日,getChineseHoliday(Date date, Map<String, String> chineseHolidayMap) 可以传入自定义农历节日数据
* 3.二十四节气计算, getSolarTerm* 比如getSolarTerm(Date date) 计算date的二十四节气
*
* 农历相关,仅支持公历1901-2050年的计算
* @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(date, null);
} /**
* 根据日期获取公历节日
* @param date
* @param localHolidayMap 自定义节日数据,特殊节日如,"母亲节", "5-W-2-7" 5表示5月,W表示星期,2表示第二个星期,7表示星期的第7天
* @return
*/
static String getLocalHoliday(Date date, Map<String, String> localHolidayMap){
Objects.requireNonNull(date, "date");
return getLocalHoliday(DateTimeConverterUtil.toLocalDateTime(date), localHolidayMap);
} /**
* 根据日期获取公历节日
* @param temporal 支持 LocalDate、LocalDateTime、Instant和ZonedDateTime
* @return
*/
static String getLocalHoliday(Temporal temporal){
return getLocalHoliday(temporal, null);
} /**
* 根据日期获取公历节日
* @param temporal 支持 LocalDate、LocalDateTime、Instant和ZonedDateTime
* @param localHolidayMap 自定义节日数据,特殊节日如,"母亲节", "5-W-2-7" 5表示5月,W表示星期,2表示第二个星期,7表示星期的第7天
* @return
*/
static String getLocalHoliday(Temporal temporal, Map<String, String> localHolidayMap){
Objects.requireNonNull(temporal, "temporal");
String localHoliday = "";
if(CollectionUtil.isEmpty(localHolidayMap)){
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)) {
if(StringUtil.isEmpty(localHoliday)){
localHoliday = entry.getValue();
}else{
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)) {
if(StringUtil.isEmpty(localHoliday)){
localHoliday = entry.getValue();
}else{
localHoliday = localHoliday + " " +entry.getValue();
}
}
}
}
return localHoliday;
} /**
* 根据日期获取农历几日
* @param date
* @return
*/
static String getChineseHoliday(Date date){
return getChineseHoliday(date, null);
} /**
* 根据日期获取农历几日
* @param date
* @param chineseHolidayMap 自定义节日数据,特殊节日如除夕 用CHUXI表示
* @return
*/
static String getChineseHoliday(Date date, Map<String, String> chineseHolidayMap){
Objects.requireNonNull(date, "date");
return getChineseHoliday(DateTimeConverterUtil.toLocalDateTime(date), chineseHolidayMap);
} /**
* 根据日期获取农历几日
* @param temporal 支持 LocalDate、LocalDateTime、Instant和ZonedDateTime 支持 LocalDate、LocalDateTime、Instant和ZonedDateTime
* @return
*/
static String getChineseHoliday(Temporal temporal){
return getChineseHoliday(temporal, null);
} /**
* 根据日期获取农历几日
* @param temporal 支持 LocalDate、LocalDateTime、Instant和ZonedDateTime
* @param chineseHolidayMap 自定义节日数据,特殊节日如除夕 用CHUXI表示
* @return
*/
static String getChineseHoliday(Temporal temporal, Map<String, String> chineseHolidayMap){
Objects.requireNonNull(temporal, "temporal");
String chineseHoliday = "";
if(CollectionUtil.isEmpty(chineseHolidayMap)){
chineseHolidayMap = ChineseHolidayEnum.convertToMap();
} LunarDate lunarDate = LunarDate.from(temporal); //闰月不计算节假日
if(StringUtil.isNotEmpty(lunarDate.getLeapMonthCn())){
return chineseHoliday;
}
String monthDayStr = lunarDate.formatShort();
//对比枚举日期,返回假日
for(Entry<String, String> entry : chineseHolidayMap.entrySet()){
if (entry.getKey().equals(monthDayStr)) {
if(StringUtil.isEmpty(chineseHoliday)){
chineseHoliday = entry.getValue();
}else{
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)){
if(StringUtil.isEmpty(chineseHoliday)){
chineseHoliday = entry.getValue();
}else{
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 temporal 支持 LocalDate、LocalDateTime、Instant和ZonedDateTime
* @return
*/
static String getSolarTerm(Temporal temporal){
Objects.requireNonNull(temporal, "temporal");
LunarDate lunarDate = LunarDate.from(temporal);
return lunarDate.getSolarTerm();
}
}

(1)getLocalHoliday(Date date, Map<String, String> localHolidayMap)中"母亲节", "5-W-2-7" 5表示5月,W表示星期,2表示第二个星期,7表示星期的第7天。

使用临时变量,修改月份为5月,然后使用TemporalAdjusters.dayOfWeekInMonth来计算当前月第几周第几天的日期和传入日期对比。

(2)getChineseHoliday(Date date, Map<String, String> chineseHolidayMap) 特殊节日如除夕 用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(localDate2, localHolidayMap));
} /**
* 农历节日,除夕
*/
@Test
public void chineseHolidayEnumTest(){
LocalDate localDate = LocalDate.of(2020, 1, 24);
System.out.println("localDate:"+Holiday.getChineseHoliday(localDate)); //正常农历九月初九
LocalDate localDate2 = LocalDate.of(2014, 10, 2);
System.out.println("localDate2:"+Holiday.getChineseHoliday(localDate2)); //正常农历闰九月初九 闰月不算节假日
LocalDate localDate3 = LocalDate.of(2014, 11, 1);
System.out.println("localDate3:"+Holiday.getChineseHoliday(localDate3));
} /**
* 二十四节气,2020-08-07 立秋
*/
@Test
public void solarTermEnumTest(){
LocalDate localDate = LocalDate.of(2020, 8, 7);
System.out.println(Holiday.getSolarTerm(localDate));
}

输出:

母亲节
世界地球日 localDate:除夕
localDate2:重阳节
localDate3: 立秋

源代码地址:https://github.com/xkzhangsan/xk-time

Java日期时间API系列28-----Jdk8中java.time包中的新的日期时间API类,计算节假日和二十四节气。的更多相关文章

  1. 在swt中获取jar包中的文件 uri is not hierarchical

    uri is not hierarchical 学习了:http://blog.csdn.net/zdsdiablo/article/details/1519719 在swt中获取jar包中的文件: ...

  2. API接口自动化之3 同一个war包中多个接口做自动化测试

    同一个war包中多个接口做自动化测试 一个接口用一个测试类,每个测试用例如下,比如下面是4个测试用例,每个详细的测试用例中含有请求入参,返回体校验,以此来判断每条测试用例是否通过 一个war包中,若含 ...

  3. Andriod项目开发实战(1)——如何在Eclipse中的一个包下建新包

    最开始是想将各个类分门别类地存放在不同的包中,所以想在项目源码包中新建几个不同功能的包eg:utils.model.receiver等,最后的结果应该是下图左边这样的:   很明显建立项目后的架构是上 ...

  4. Mac 如何导出ipa文件中Assets.car包中的切图

    在之前 获取 AppStore 中 应用 的 IPA 包文件(Mac OS 13+)中获取到应用的 IPA 包,可以取出应用的部分图片(如 Logo),如果项目工程中把图片添加到 Assets.xca ...

  5. 【转】Eclipse中查看jar包中的源码

    (简单的方式:通过jd-gui来进行反编译,最简单!,参考我的另一篇博文, 地址:http://www.cnblogs.com/gmq-sh/p/4277991.html) Java Decompil ...

  6. JDK中的Atomic包中的类及使用

    引言 Java从JDK1.5开始提供了java.util.concurrent.atomic包,方便程序员在多线程环境下,无锁的进行原子操作.原子变量的底层使用了处理器提供的原子指令,但是不同的CPU ...

  7. Package.json中dependencies依赖包中^符号和~符号前缀的区别

    刚git了webpack的包发现package.json里面dependencies依赖包的版本号前面的符号有两种,一种是~,一种是^,如下图标记: 然后搜了下在stackoverflow上找到一个比 ...

  8. Java8系列 (六) 新的日期和时间API

    概述 在Java8之前, 我们一般都是使用 SimpleDateFormat 来解析和格式化日期时间, 但它是线程不安全的. @Test public void test() { SimpleDate ...

  9. Java8 新的日期和时间API(笔记)

    LocalDate LocalTime Instant duration以及Period 使用LocalDate和LocalTime //2017-03-20 LocalDate date = Loc ...

  10. Redis总结(五)缓存雪崩和缓存穿透等问题 Web API系列(三)统一异常处理 C#总结(一)AutoResetEvent的使用介绍(用AutoResetEvent实现同步) C#总结(二)事件Event 介绍总结 C#总结(三)DataGridView增加全选列 Web API系列(二)接口安全和参数校验 RabbitMQ学习系列(六): RabbitMQ 高可用集群

    Redis总结(五)缓存雪崩和缓存穿透等问题   前面讲过一些redis 缓存的使用和数据持久化.感兴趣的朋友可以看看之前的文章,http://www.cnblogs.com/zhangweizhon ...

随机推荐

  1. 【Vue】自己编写排名组件

    一.需求分析 这里我是用Echarts的柱状图,倒置下y轴x轴就实现了,然后产品说跟UI不一致 我一看UI这种又给我整不会了,然后想拿Echarts改改参数搞定,同事和群友都是说自己做,不要用Echa ...

  2. 【Java】线程池配置

    先看JUC包自带的一个资源 线程池执行器: 初始化参数如下 ThreadPoolExecutor threadPoolExecutor = new ThreadPoolExecutor( corePo ...

  3. 【JS】05 DOM 文档对象模型 P2 元素的CRUD、Dom集合对象

    Element & Node 元素,或者称为节点 在JS中创建一个HTML元素,但是因为没有指定在Dom对象中的节点位置,所以页面不会发生改变 var para = document.crea ...

  4. 【Shiro】01 概述 & 快速上手

    什么是Shiro? Apache Shiro 是Java的一个权限安全框架 一些功能:认证.授权.加密.会话管理.与Web 集成.缓存等   Shiro官网地址:[ 点击访问 ] http://shi ...

  5. git警告信息:Encountered 1 file(s) that may not have been copied correctly on Windows: —— See: `git lfs help smudge` for more details.

    git报警信息: 官方讨论的帖子: https://github.com/git-lfs/git-lfs/issues/2434 说下个人的理解: 在git管理中,对于大文件(一般为压缩后的二进制文件 ...

  6. Linux系统下使用pytorch多进程读取图片数据时的注意事项——DataLoader的多进程使用注意事项

    原文: PEP 703 – Making the Global Interpreter Lock Optional in CPython 相关内容: The GIL Affects Python Li ...

  7. 树莓派命令行配置wifi密码时如何实现密码加密(密文,非明文)

    首先需要知道,树莓派系统(原生系统)的wifi配置文件为: /etc/wpa_supplicant/wpa_supplicant.conf 配置该文件时,psk属性为密码,往往我们都是使用明文来进行配 ...

  8. 纪念IE浏览器退役,哈哈哈!!!

    网址: https://haokan.baidu.com/v?pd=wisenatural&vid=16024148879625055169 ========================= ...

  9. DeepMind Lab的一些python例子—————(Ubuntu22.04系统安装DeepMind Lab)后续

    相关资料: Ubuntu22.04系统安装DeepMind Lab ====================================================== 关于DeepMind ...

  10. 7月30日CSP-S模拟赛赛后总结

    7月30日模拟赛赛后总结 \[7月30日 \ \ 模拟赛 \ \ 赛后总结 \\ 2024年7月30日 \\ by \ \ \ hcy \] 洛谷同步:点我 一.做题情况 第一题比赛 \(100pts ...