Java日期时间API系列28

Wesley13
• 阅读 588

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

点赞
收藏
评论区
推荐文章
blmius blmius
3年前
MySQL:[Err] 1292 - Incorrect datetime value: ‘0000-00-00 00:00:00‘ for column ‘CREATE_TIME‘ at row 1
文章目录问题用navicat导入数据时,报错:原因这是因为当前的MySQL不支持datetime为0的情况。解决修改sql\mode:sql\mode:SQLMode定义了MySQL应支持的SQL语法、数据校验等,这样可以更容易地在不同的环境中使用MySQL。全局s
皕杰报表之UUID
​在我们用皕杰报表工具设计填报报表时,如何在新增行里自动增加id呢?能新增整数排序id吗?目前可以在新增行里自动增加id,但只能用uuid函数增加UUID编码,不能新增整数排序id。uuid函数说明:获取一个UUID,可以在填报表中用来创建数据ID语法:uuid()或uuid(sep)参数说明:sep布尔值,生成的uuid中是否包含分隔符'',缺省为
待兔 待兔
5个月前
手写Java HashMap源码
HashMap的使用教程HashMap的使用教程HashMap的使用教程HashMap的使用教程HashMap的使用教程22
Jacquelyn38 Jacquelyn38
3年前
2020年前端实用代码段,为你的工作保驾护航
有空的时候,自己总结了几个代码段,在开发中也经常使用,谢谢。1、使用解构获取json数据let jsonData  id: 1,status: "OK",data: 'a', 'b';let  id, status, data: number   jsonData;console.log(id, status, number )
Wesley13 Wesley13
3年前
Java爬虫之JSoup使用教程
title:Java爬虫之JSoup使用教程date:201812248:00:000800update:201812248:00:000800author:mecover:https://imgblog.csdnimg.cn/20181224144920712(https://www.oschin
Stella981 Stella981
3年前
HIVE 时间操作函数
日期函数UNIX时间戳转日期函数: from\_unixtime语法:   from\_unixtime(bigint unixtime\, string format\)返回值: string说明: 转化UNIX时间戳(从19700101 00:00:00 UTC到指定时间的秒数)到当前时区的时间格式举例:hive   selec
Wesley13 Wesley13
3年前
00:Java简单了解
浅谈Java之概述Java是SUN(StanfordUniversityNetwork),斯坦福大学网络公司)1995年推出的一门高级编程语言。Java是一种面向Internet的编程语言。随着Java技术在web方面的不断成熟,已经成为Web应用程序的首选开发语言。Java是简单易学,完全面向对象,安全可靠,与平台无关的编程语言。
Wesley13 Wesley13
3年前
Java日期时间API系列35
  通过Java日期时间API系列1Jdk7及以前的日期时间类(https://www.oschina.net/action/GoToLink?urlhttps%3A%2F%2Fwww.cnblogs.com%2Fxkzhangsanx%2Fp%2F12032719.html)中得知,Java8以前除了java.sql.Timestamp扩充
Wesley13 Wesley13
3年前
MySQL部分从库上面因为大量的临时表tmp_table造成慢查询
背景描述Time:20190124T00:08:14.70572408:00User@Host:@Id:Schema:sentrymetaLast_errno:0Killed:0Query_time:0.315758Lock_
Python进阶者 Python进阶者
11个月前
Excel中这日期老是出来00:00:00,怎么用Pandas把这个去除
大家好,我是皮皮。一、前言前几天在Python白银交流群【上海新年人】问了一个Pandas数据筛选的问题。问题如下:这日期老是出来00:00:00,怎么把这个去除。二、实现过程后来【论草莓如何成为冻干莓】给了一个思路和代码如下:pd.toexcel之前把这