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. nacos配置&gateway配置服务发现一直报500

    项目场景: 这两天不是一直在搞简化配置.使用公共配置.我的服务可以通过网关访问这几个任务嘛,也是不断地踩坑补知识才总算把这几个任务都搞好了,下面就是记录过程中遇到的问题. 使用公共配置 因为发现项目使 ...

  2. 关于spring boot中mapper注入到service时IDEA报错的解决办法

    虽然这个错误不影响正常运行但是作为强迫症患者看着实属难受,经过在论坛查看资料学习到以下两种解决方法,可以供大家参考以下,如有什么错误的地方还希望各位大佬指定一下. 1.在注解@Autowired后增加 ...

  3. 【Java】 Void 类型

    void 也算一个类型,而且是基本数据类型 和其它数据类型一样提供了对应的包装类Void 每个包装类都提供一个TYPE字节实例,返回对应的原型类实例 public static void main(S ...

  4. 训练人形机器人时如何收集人类行为数据 —— 通过人来训练机器人(真人实际演示动作)or 仿真环境自动生成 —— 哪种方式更优、更可行呢

    特斯拉的老马,搞的optimus人形机器人就是通过人来训练机器人(真人实际演示动作),但是未来使用仿真环境自动生成数据是否可行呢,NVIDIA的老黄在2024 GTC上是大力推出自家的GROOT平台, ...

  5. tensorflow1.x——如何在python多线程中调用同一个session会话

    如何在python多线程中调用同一个session会话? 这个问题源于我在看的一个强化学习代码: https://gitee.com/devilmaycry812839668/scalable_age ...

  6. 删库了不用跑路!binlog恢复数据实操

    各位道友大家好呀! 想必道友们或多或少都听说过MySQL的binlog的作用,它记录了数据库整个的生命周期,可用于恢复数据或者从库同步数据. 那么如果发生了数据库误删,具体该怎样恢复数据呢? 下面就以 ...

  7. 白鲸开源 DataOps 平台加速数据分析和大模型构建

    作者 | 李晨 编辑 | Debra Chen 数据准备对于推动有效的自助式分析和数据科学实践至关重要.如今,企业大都知道基于数据的决策是成功数字化转型的关键,但要做出有效的决策,只有可信的数据才能提 ...

  8. 并查集基础 &打击罪犯

    并查集基础 真的很基础 题目描述:Description 某个地区有n(n<=1000)个犯罪团伙,当地警方按照他们的危险程度由高到低给他们编号为1-n,他们有些团伙之间有直接联系,但是任意两个 ...

  9. 【线段树合并/树上差分】[P4556 [Vani有约会] 雨天的尾巴 /【模板】线段树合并

    [线段树合并/树上差分]P4556 [Vani有约会] 雨天的尾巴 /[模板]线段树合并 思路 对 \(x,y,lca(u,v),fa_{lca(u,v)}\) 四个点进行树上差分,然后用线段树合并动 ...

  10. PCIe简介

    PCIe简介 Peripheral Component Interconnect Express (PCI),高速串行计算机扩展总线标准,PCIe对外围设备的组织方式是树形结构. 拓扑结构 根: 树的 ...