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. app专项测试:app弱网测试(网络测试流程)

    app专项测试:app弱网测试(网络测试流程) 一.网络测试的一般流程 step1:首先要考虑网络正常的情况 ① 各个模块的功能正常可用 ② 页面元素/数据显示正常 step2:其次要考虑无网络的情况 ...

  2. 【Java】ElasticSearch 在项目里的应用

    一.前言: 好久没写笔记了,最近忙一个项目,用到ES查询,以往的笔记写ES都是搭建环境,用Kibana玩一玩 这次是直接调用API操作了,话不多说,进入主题 二.环境前提: 公司用的还是纯Elasti ...

  3. Google的TPU的运算数据类型最高为32比特,也就是说TPU不支持double数据类型,浮点数类型最高支持float32

    Google的TPU的运算数据类型最高为32比特,也就是说TPU不支持double数据类型,浮点数类型最高支持float32 地址: https://cloud.google.com/tpu/docs ...

  4. 深度学习需要float64精度吗 —— 为什么各大深度学习框架均不支持float64的深度学习运算呢 —— 商用NVIDIA显卡的float64性能是否多余呢

    首先要知道这么几个事实,也是交代一下本文要讨论的问题的背景: 各大深度学习框架均支持float64类型的简单运算,但是均不支持float64的深度学习的运算操作: 作为深度学习运行的加速设备,各种GP ...

  5. CPU利用率为多少时可以兼顾计算效率和时间效率?—— 75% —— 科学计算时如何正确的使用超线程CPU——使用超线程CPU进行计算密集型任务时的注意事项

    2023年12月28日  更新 现在这个AI火热的时代科学计算任务占比越来越大,但是平时使用时也有一些不为人注意的地方需要知道,本文就讨论一下使用超线程CPU时的注意事项. 超线程CPU就是现在的多线 ...

  6. 作为电脑屏幕的补光灯,到底是应该选Led灯还是荧光灯

    现在的台灯灯具市场基本被Led灯给霸占,这就无形之中要大家买台灯的时候只能选择Led等,我也是如此,手上有一款20年前上高中时候的"孩视宝"荧光灯的台灯,然后还有一款刚刚购入的Le ...

  7. java中的几种锁

    一.公平锁/非公平锁 公平锁是指多个线程按照申请锁的顺序来获取锁. 非公平锁是指多个线程获取锁的顺序并不是按照申请锁的顺序,有可能后申请的线程比先申请的线程优先获取锁.有可能,会造成优先级反转或者饥饿 ...

  8. python学习(一)django orm多表查询

    ###多表查询 一般的多表查询都是直接建立一个多对多关系 class Books(models.Model): users = models.ManyToManyField(User, related ...

  9. 在DLL中封装模板类的问题

    在Dll中封装类是用定义一个宏来区分导出标识的 #ifdef DLLCLASS_EXPORTS #define DLL_CLASS _declspec(dllexport) //Dll #else # ...

  10. Tree组件的快速定位更新节点的状态,以及修改节点的数据属性等操作

    当我们点击树节点的时候我们常常只能获得树的id,那么我么如何获快速定位到树节点的内容呢,除此之外,当树已经存在时,但是缺少我们想要的内容时,我们想在树节点上添加我们需要的额外的内容时该怎么办,那么就是 ...