Java日期时间API系列28—–Jdk8中java.time包中的新的日期时间API类,计算节假日和二十四节气。

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 localHolidayMap) 可以传入自定义公历节日数据
 * 2.农历节假日计算, getChineseHoliday* 比如getChineseHoliday(Date date) 计算date的农历节日,getChineseHoliday(Date date, Map 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 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 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 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 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 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 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 localHolidayMap)中”母亲节”, “5-W-2-7” 5表示5月,W表示星期,2表示第二个星期,7表示星期的第7天。

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

 

(2)getChineseHoliday(Date date, Map 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 localHolidayMap = new HashMap();
        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系列27—–Jdk8中java.time包中的新的日期时间API类,使用xk-time工具类创建日历应用,自定义节假日,工作日和打印日历表。

1.日历相关类

1.1 日历类 CalendarWrapper

package com.xkzhangsan.time.calendar;

import java.io.Serializable;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;

/**
 * 日历
 * 
 * @ClassName: CalendarWrapper
 * @Description: CalendarWrapper
 * @author xkzhangsan
 * @date 2020年03月18日
 */
public class CalendarWrapper implements Serializable{
    
    private static final long serialVersionUID = -4287759184630652424L;

    /**
     * 日历中所有的年 
     */
    private List years;
    
    /**
     * 日历中所有的天map,方便快速访问,key 格式:yyyy-MM-dd
     */
    private Map dayMap = new ConcurrentHashMap();
    
    /**
     * 日历中所有的天list,方便顺序遍历访问
     */
    private List dayList = new ArrayList();
    
    public CalendarWrapper() {
        super();
    }
    
    public CalendarWrapper(List years, Map dayMap, List dayList) {
        super();
        this.years = years;
        this.dayMap = dayMap;
        this.dayList = dayList;
    }

    public CalendarWrapper(List years) {
        super();
        this.years = years;
    }

    public List getYears() {
        return years;
    }

    public void setYears(List years) {
        this.years = years;
    }

    public Map getDayMap() {
        return dayMap;
    }

    public void setDayMap(Map dayMap) {
        this.dayMap = dayMap;
    }

    public List getDayList() {
        return dayList;
    }

    public void setDayList(List dayList) {
        this.dayList = dayList;
    }
}

 

1.2 日历年类 YearWrapper

 

package com.xkzhangsan.time.calendar;

import java.io.Serializable;
import java.util.List;

import com.xkzhangsan.time.calculator.DateTimeCalculatorUtil;

/**
 * 年
 * 
 * @ClassName: YearWrapper
 * @Description: YearWrapper
 * @author xkzhangsan
 * @date 2020年03月18日
 */
public class YearWrapper implements Serializable{

    private static final long serialVersionUID = 1L;
    
    /**
     * 年
     */
    private int year;
    
    /**
     * 当前年所有月
     */
    private List months;
    
    /**
     * 是否闰月
     */
    private boolean isLeapYear;
    
    /**
     * 当前年包含的天数
     */
    private int length;

    public YearWrapper(int year, List months) {
        super();
        this.year = year; 
        this.months = months;
        this.isLeapYear = DateTimeCalculatorUtil.isLeapYear(year);
        if(isLeapYear){
            this.length = 366;
        }else{
            this.length = 365;
        }
    }


    public int getYear() {
        return year;
    }

    public void setYear(int year) {
        this.year = year;
    }

    public List getMonths() {
        return months;
    }
    
    public void setMonths(List months) {
        this.months = months;
    }
    
    public boolean isLeapYear() {
        return isLeapYear;
    }

    public void setLeapYear(boolean isLeapYear) {
        this.isLeapYear = isLeapYear;
    }

    public int getLength() {
        return length;
    }


    public void setLength(int length) {
        this.length = length;
    }
}

 

1.3 日历月类 MonthWrapper

 

package com.xkzhangsan.time.calendar;

import java.io.Serializable;
import java.util.List;

import com.xkzhangsan.time.calculator.DateTimeCalculatorUtil;
import com.xkzhangsan.time.utils.CollectionUtil;

/**
 * 月
 * 
 * @ClassName: MonthWrapper
 * @Description: MonthWrapper
 * @author xkzhangsan
 * @date 2020年03月18日
 */
public class MonthWrapper implements Serializable{

    private static final long serialVersionUID = 6688876063027489849L;

    /**
     * 月
     */
    private int month;
    
    /**
     * 当月包含的所有天
     */
    private List days;
    
    /**
     * 当前月包含天数
     */
    private int length;
    
    /**
     * 获取月份中文简称, 比如一
     */
    private String monthCnShort;
    
    /**
     * 获取月份中文全称, 比如一月
     */
    private String monthCnLong;

    /**
     * 获取月英文简称, 比如 Jan
     */
    private String monthEnShort;
    
    /**
     * 获取月英文简称大写, 比如 JAN
     */
    private String monthEnShortUpper;
    
    /**
     * 获取月英文全称, 比如 January
     */
    private String monthEnLong;    
    
    public MonthWrapper(int month, List days, int length) {
        super();
        this.month = month;
        this.days = days;
        this.length = length;
        if(CollectionUtil.isNotEmpty(days)){
            DayWrapper day = days.get(0);
            if(day != null){
                this.monthCnShort = DateTimeCalculatorUtil.getMonthCnShort(day.getLocalDateTime());
                this.monthCnLong = DateTimeCalculatorUtil.getMonthCnLong(day.getLocalDateTime());
                this.monthEnShort = DateTimeCalculatorUtil.getMonthEnShort(day.getLocalDateTime());
                this.monthEnShortUpper = DateTimeCalculatorUtil.getMonthEnShortUpper(day.getLocalDateTime());
                this.monthEnLong = DateTimeCalculatorUtil.getMonthEnLong(day.getLocalDateTime());
            }
        }
    }

    public int getMonth() {
        return month;
    }

    public void setMonth(int month) {
        this.month = month;
    }
    
    public List getDays() {
        return days;
    }
    
    public void setDays(List days) {
        this.days = days;
    }

    public int getLength() {
        return length;
    }

    public void setLength(int length) {
        this.length = length;
    }

    public String getMonthCnShort() {
        return monthCnShort;
    }

    public void setMonthCnShort(String monthCnShort) {
        this.monthCnShort = monthCnShort;
    }

    public String getMonthCnLong() {
        return monthCnLong;
    }

    public void setMonthCnLong(String monthCnLong) {
        this.monthCnLong = monthCnLong;
    }

    public String getMonthEnShort() {
        return monthEnShort;
    }

    public void setMonthEnShort(String monthEnShort) {
        this.monthEnShort = monthEnShort;
    }

    public String getMonthEnShortUpper() {
        return monthEnShortUpper;
    }

    public void setMonthEnShortUpper(String monthEnShortUpper) {
        this.monthEnShortUpper = monthEnShortUpper;
    }

    public String getMonthEnLong() {
        return monthEnLong;
    }

    public void setMonthEnLong(String monthEnLong) {
        this.monthEnLong = monthEnLong;
    }
}

 

1.4 日历日类 DayWrapper

 

package com.xkzhangsan.time.calendar;

import java.io.Serializable;
import java.time.LocalDateTime;
import java.util.Date;
import java.util.Map;

import com.xkzhangsan.time.LunarDate;
import com.xkzhangsan.time.calculator.DateTimeCalculatorUtil;
import com.xkzhangsan.time.converter.DateTimeConverterUtil;
import com.xkzhangsan.time.formatter.DateTimeFormatterUtil;
import com.xkzhangsan.time.holiday.Holiday;

/**
 * 日
 * 
 * @ClassName: DayWrapper
 * @Description: DayWrapper
 * @author xkzhangsan
 * @date 2020年03月18日
 */
public class DayWrapper implements Serializable {

    private static final long serialVersionUID = 5710793952115910594L;

    /**
     * date
     */
    private Date date;

    /**
     * java8 localDateTime 丰富方法可以使用
     */
    private LocalDateTime localDateTime;

    /**
     * 日期 yyyy-MM-dd
     */
    private String dateStr;

    /**
     * 天,当月第几天
     */
    private int day;
    
    /**
     * 星期,数字,1-7
     */
    private int week;

    /**
     * 星期,中文简写,比如星期一为一
     */
    private String weekCnShort;
    
    /**
     * 星期,中文全称,比如星期一
     */
    private String weekCnLong;
    
    /**
     * 星期,英文简写,比如星期一为Mon
     */
    private String weekEnShort;
    
    /**
     * 星期,英文简写大写,比如星期一为MON
     */
    private String weekEnShortUpper;
    
    
    /**
     * 星期,英文全称,比如星期一为Monday
     */
    private String weekEnLong;

    /**
     * 公历节日
     */
    private String localHoliday;

    /**
     * 农历
     */
    private LunarDate lunarDate;

    /**
     * 农历节日
     */
    private String chineseHoliday;

    /**
     * 农历日期
     */
    private String lunarDateStr;
    
    /**
     * 农历天,比如初一
     */
    private String lunarDay;

    /**
     * 二十四节气
     */
    private String solarTerm;
    
    /**
     * 日期类型,0休息日,1其他为工作日
     */
    private int dateType;

    /**
     * 扩展信息
     */
    private Object obj;

    /**
     * 创建DayWrapper
     * 
     * @param localDateTime
     */
    public DayWrapper(LocalDateTime localDateTime) {
        this(localDateTime, false);
    }

    /**
     * 创建DayWrapper
     * 
     * @param localDateTime
     * @param includeLunarDate
     *            是否包含农历
     */
    public DayWrapper(LocalDateTime localDateTime, boolean includeLunarDate) {
        this(localDateTime, includeLunarDate, false, null, null);
    }

    /**
     * 创建DayWrapper
     * 
     * @param localDateTime
     * @param includeLunarDate
     *            是否包含农历
     * @param includeHoliday
     *            是否包含节日
     * @param localHolidayMap
     *            自定义公历节日信息localHolidayMap 自定义公历节日数据,特殊节日如,"母亲节", "5-W-2-7"
     *            5表示5月,W表示星期,2表示第二个星期,7表示星期的第7天,为null时,使用默认数据 LocalHolidayEnum
     * @param chineseHolidayMap
     *            自定义农历节日信息,特殊节日如除夕 用CHUXI表示,为null时,使用默认数据 ChineseHolidayEnum
     */
    public DayWrapper(LocalDateTime localDateTime, boolean includeLunarDate, boolean includeHoliday,
            Map localHolidayMap, Map chineseHolidayMap) {
        this(localDateTime, null, includeLunarDate, includeHoliday, localHolidayMap, chineseHolidayMap);
    }

    public DayWrapper(LocalDateTime localDateTime, Object obj, boolean includeLunarDate, boolean includeHoliday,
            Map localHolidayMap, Map chineseHolidayMap) {
        super();
        this.localDateTime = localDateTime;
        this.date = DateTimeConverterUtil.toDate(localDateTime);
        this.dateStr = DateTimeFormatterUtil.formatToDateStr(localDateTime);
        this.day = localDateTime.getDayOfMonth();
        // week
        this.week = localDateTime.getDayOfWeek().getValue();
        this.weekCnShort = DateTimeCalculatorUtil.getDayOfWeekCnShort(localDateTime);
        this.weekCnLong = DateTimeCalculatorUtil.getDayOfWeekCn(localDateTime);
        this.weekEnShort = DateTimeCalculatorUtil.getDayOfWeekEnShort(localDateTime);
        this.weekEnShortUpper = DateTimeCalculatorUtil.getDayOfWeekEnShortUpper(localDateTime);
        this.weekEnLong = DateTimeCalculatorUtil.getDayOfWeekEnLong(localDateTime);
        this.obj = obj;

        // LunarDate
        if (includeLunarDate) {
            this.lunarDate = LunarDate.from(localDateTime);
            this.lunarDateStr = lunarDate.getlDateCn();
            this.lunarDay = lunarDate.getlDayCn();
            this.solarTerm = lunarDate.getSolarTerm();
        }

        // Holiday
        if (includeHoliday) {
            this.localHoliday = Holiday.getLocalHoliday(localDateTime, localHolidayMap);
            if (includeLunarDate) {
                this.chineseHoliday = Holiday.getChineseHoliday(localDateTime, chineseHolidayMap);
            }
        }
        
        // 工作日
        this.dateType = DateTimeCalculatorUtil.isWorkDay(localDateTime)?1:0;
    }

    public Date getDate() {
        return date;
    }

    public void setDate(Date date) {
        this.date = date;
    }

    public LocalDateTime getLocalDateTime() {
        return localDateTime;
    }

    public void setLocalDateTime(LocalDateTime localDateTime) {
        this.localDateTime = localDateTime;
    }

    public Object getObj() {
        return obj;
    }

    public void setObj(Object obj) {
        this.obj = obj;
    }

    public String getDateStr() {
        return dateStr;
    }

    public void setDateStr(String dateStr) {
        this.dateStr = dateStr;
    }

    public int getDay() {
        return day;
    }

    public void setDay(int day) {
        this.day = day;
    }

    public String getWeekCnShort() {
        return weekCnShort;
    }

    public void setWeekCnShort(String weekCnShort) {
        this.weekCnShort = weekCnShort;
    }

    public String getWeekEnShort() {
        return weekEnShort;
    }

    public void setWeekEnShort(String weekEnShort) {
        this.weekEnShort = weekEnShort;
    }

    public String getWeekEnShortUpper() {
        return weekEnShortUpper;
    }

    public void setWeekEnShortUpper(String weekEnShortUpper) {
        this.weekEnShortUpper = weekEnShortUpper;
    }

    public String getWeekCnLong() {
        return weekCnLong;
    }

    public void setWeekCnLong(String weekCnLong) {
        this.weekCnLong = weekCnLong;
    }

    public String getWeekEnLong() {
        return weekEnLong;
    }

    public void setWeekEnLong(String weekEnLong) {
        this.weekEnLong = weekEnLong;
    }

    public LunarDate getLunarDate() {
        return lunarDate;
    }

    public void setLunarDate(LunarDate lunarDate) {
        this.lunarDate = lunarDate;
    }

    public String getLocalHoliday() {
        return localHoliday;
    }

    public void setLocalHoliday(String localHoliday) {
        this.localHoliday = localHoliday;
    }

    public String getChineseHoliday() {
        return chineseHoliday;
    }

    public void setChineseHoliday(String chineseHoliday) {
        this.chineseHoliday = chineseHoliday;
    }

    public String getSolarTerm() {
        return solarTerm;
    }

    public void setSolarTerm(String solarTerm) {
        this.solarTerm = solarTerm;
    }

    public String getLunarDateStr() {
        return lunarDateStr;
    }

    public void setLunarDateStr(String lunarDateStr) {
        this.lunarDateStr = lunarDateStr;
    }

    public int getWeek() {
        return week;
    }

    public void setWeek(int week) {
        this.week = week;
    }

    public int getDateType() {
        return dateType;
    }

    public void setDateType(int dateType) {
        this.dateType = dateType;
    }

    public String getLunarDay() {
        return lunarDay;
    }

    public void setLunarDay(String lunarDay) {
        this.lunarDay = lunarDay;
    }

}

 

1.5 日历工具类 CalendarUtil

 

package com.xkzhangsan.time.calendar;

import java.time.LocalDateTime;
import java.time.YearMonth;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;

import com.xkzhangsan.time.calculator.DateTimeCalculatorUtil;
import com.xkzhangsan.time.formatter.DateTimeFormatterUtil;
import com.xkzhangsan.time.utils.CollectionUtil;

/**
 * 日历工具类 
 * 包括:
 *  1.生成指定时间的日历方法,generateCalendar* 比如generateCalendar(int year, int
 * month) 生成指定年月的日历
 *  2.生成指定时间的日历,包含农历和所有节假日信息方法,generateCalendarWithHoliday*, 比如generateCalendarWithHoliday(int year, int month, Map localHolidayMap,
            Map chineseHolidayMap, Map dateTypeMap)生成指定年月的日历,包含农历和所有节假日信息,可以自定义节假日和工作日等。
 * @ClassName: CalendarUtil
 * @Description: CalendarUtil
 * @author xkzhangsan
 * @date 2020年03月18日
 */
public class CalendarUtil {

    private CalendarUtil() {
    }

    /**
     * 生成指定年月的日历
     * 
     * @param year
     * @param month
     * @return
     */
    public static CalendarWrapper generateCalendar(int year, int month) {
        return generateCalendar(year, month, false, false, null, null, null);
    }

    /**
     * 生成指定年月的日历, 包含农历信息
     * 
     * @param year
     * @param month
     * @return
     */
    public static CalendarWrapper generateCalendarWithLunar(int year, int month) {
        return generateCalendar(year, month, true, false, null, null, null);
    }

    /**
     * 生成指定年月的日历,包含公历节假日信息
     * 
     * @param year
     * @param month
     * @param localHolidayMap
     *            自定义公历节日数据,特殊节日如,"母亲节", "5-W-2-7"
     *            5表示5月,W表示星期,2表示第二个星期,7表示星期的第7天,为null时,使用默认数据 LocalHolidayEnum
     *            比如localHolidayMap.put("0801", "建军节");
     * @param dateTypeMap 日期类型,0休息日,1等其他为工作日,比如dateTypeMap.put("2020-08-07", 0);
     * @return
     */
    public static CalendarWrapper generateCalendarWithLocalHoliday(int year, int month,
            Map localHolidayMap, Map dateTypeMap) {
        return generateCalendar(year, month, false, true, localHolidayMap, null, dateTypeMap);
    }
    
    /**
     * 生成指定年月的日历,包含农历和所有节假日信息
     * @param year
     * @param month
     * @return
     */
    public static CalendarWrapper generateCalendarWithHoliday(int year, int month) {
        return generateCalendar(year, month, true, true, null, null, null);
    }

    /**
     * 生成指定年月的日历,包含农历和所有节假日信息,使用自定义数据
     * 
     * @param year
     * @param month
     * @param localHolidayMap
     *            自定义公历节日数据,特殊节日如,"母亲节", "5-W-2-7"
     *            5表示5月,W表示星期,2表示第二个星期,7表示星期的第7天,为null时,使用默认数据 LocalHolidayEnum
     *            比如localHolidayMap.put("0801", "建军节");
     * @param chineseHolidayMap
     *            自定义农历节日信息,特殊节日如除夕 用CHUXI表示,为null时,使用默认数据 ChineseHolidayEnum
     *            比如chineseHolidayMap.put("0707", "七夕情人节");
     * @param dateTypeMap 日期类型,0休息日,1等其他为工作日,比如dateTypeMap.put("2020-08-07", 0);
     * @return
     */
    public static CalendarWrapper generateCalendarWithHoliday(int year, int month, Map localHolidayMap,
            Map chineseHolidayMap, Map dateTypeMap) {
        return generateCalendar(year, month, true, true, localHolidayMap, chineseHolidayMap, dateTypeMap);
    }

    /**
     * 生成指定年月的日历,包含农历和所有节假日信息
     * 
     * @param year
     * @param month
     * @param includeLunarDate
     * @param includeHoliday
     * @param localHolidayMap
     *            自定义公历节日数据,特殊节日如,"母亲节", "5-W-2-7"
     *            5表示5月,W表示星期,2表示第二个星期,7表示星期的第7天,为null时,使用默认数据 LocalHolidayEnum
     *            比如localHolidayMap.put("0801", "建军节");
     * @param chineseHolidayMap
     *            自定义农历节日信息,特殊节日如除夕 用CHUXI表示,为null时,使用默认数据 ChineseHolidayEnum
     *            比如chineseHolidayMap.put("0707", "七夕情人节");
     * @param dateTypeMap 日期类型,0休息日,1等其他为工作日,比如dateTypeMap.put("2020-08-07", 0);
     * @return
     */
    private static CalendarWrapper generateCalendar(int year, int month, boolean includeLunarDate,
            boolean includeHoliday, Map localHolidayMap, Map chineseHolidayMap, Map dateTypeMap) {
        YearMonth yearMonth = YearMonth.of(year, month);
        CalendarWrapper calendarWrapper = new CalendarWrapper();
        Map dayMap = new ConcurrentHashMap();
        List dayList = new ArrayList();
        
        List localDateTimeList = DateTimeCalculatorUtil.getLocalDateTimeList(YearMonth.of(year, month));
        if (CollectionUtil.isEmpty(localDateTimeList)) {
            return calendarWrapper;
        }
        List dayWrapperList = new ArrayList<>();
        localDateTimeList.stream().forEach(localDateTime -> {
            DayWrapper dayWrapper = new DayWrapper(localDateTime, includeLunarDate, includeHoliday, localHolidayMap,
                    chineseHolidayMap);
            dayWrapperList.add(dayWrapper);
            dayMap.put(DateTimeFormatterUtil.formatToDateStr(localDateTime), dayWrapper);
            dayList.add(dayWrapper);
        });

        // DateType
        if(CollectionUtil.isNotEmpty(dateTypeMap) && CollectionUtil.isNotEmpty(dayMap)){
            dateTypeMap.forEach((k,v)->{
                if(dayMap.containsKey(k)){
                    dayMap.get(k).setDateType(v);
                }
            });
        }
        
        MonthWrapper monthWrapper = new MonthWrapper(month, dayWrapperList, yearMonth.lengthOfMonth());
        List monthWrapperList = new ArrayList<>();
        monthWrapperList.add(monthWrapper);
        YearWrapper yearWrapper = new YearWrapper(year, monthWrapperList);

        List yearWrapperList = new ArrayList<>();
        yearWrapperList.add(yearWrapper);
        
        calendarWrapper = new CalendarWrapper(yearWrapperList, dayMap, dayList);
        return calendarWrapper;
    }

    /**
     * 生成指定年月的日历
     * 
     * @param year
     * @return
     */
    public static CalendarWrapper generateCalendar(int year) {
        return generateCalendar(year, false, false, null, null, null);
    }

    /**
     * 生成指定年月的日历, 包含农历信息
     * 
     * @param year
     * @return
     */
    public static CalendarWrapper generateCalendarWithLunar(int year) {
        return generateCalendar(year, true, false, null, null, null);
    }

    /**
     * 生成指定年月的日历,包含公历节假日信息
     * 
     * @param year
     * @param localHolidayMap
     *            自定义公历节日数据,特殊节日如,"母亲节", "5-W-2-7"
     *            5表示5月,W表示星期,2表示第二个星期,7表示星期的第7天,为null时,使用默认数据 LocalHolidayEnum
     *            比如localHolidayMap.put("0801", "建军节");
     * @param dateTypeMap 日期类型,0休息日,1等其他为工作日,比如dateTypeMap.put("2020-08-07", 0);
     * @return
     */
    public static CalendarWrapper generateCalendarWithLocalHoliday(int year, Map localHolidayMap, Map dateTypeMap) {
        return generateCalendar(year, false, true, localHolidayMap, null, dateTypeMap);
    }
    
    /**
     * 生成指定年月的日历,包含农历和所有节假日信息
     * @param year
     * @return
     */
    public static CalendarWrapper generateCalendarWithHoliday(int year) {
        return generateCalendar(year, true, true, null, null, null);
    }

    /**
     * 生成指定年月的日历,包含农历和所有节假日信息,使用自定义数据
     * 
     * @param year
     * @param localHolidayMap
     *            自定义公历节日数据,特殊节日如,"母亲节", "5-W-2-7"
     *            5表示5月,W表示星期,2表示第二个星期,7表示星期的第7天,为null时,使用默认数据 LocalHolidayEnum
     *            比如localHolidayMap.put("0801", "建军节");
     * @param chineseHolidayMap
     *            自定义农历节日信息,特殊节日如除夕 用CHUXI表示,为null时,使用默认数据 ChineseHolidayEnum
     *            比如chineseHolidayMap.put("0707", "七夕情人节");
     * @param dateTypeMap 日期类型,0休息日,1等其他为工作日,比如dateTypeMap.put("2020-08-07", 0);
     * @return
     */
    public static CalendarWrapper generateCalendarWithHoliday(int year, Map localHolidayMap,
            Map chineseHolidayMap, Map dateTypeMap) {
        return generateCalendar(year, true, true, localHolidayMap, chineseHolidayMap, dateTypeMap);
    }

    /**
     * 生成指定年月的日历,包含农历和所有节假日信息
     * 
     * @param year
     * @param includeLunarDate
     * @param includeHoliday
     * @param localHolidayMap
     *            自定义公历节日数据,特殊节日如,"母亲节", "5-W-2-7"
     *            5表示5月,W表示星期,2表示第二个星期,7表示星期的第7天,为null时,使用默认数据 LocalHolidayEnum
     *            比如localHolidayMap.put("0801", "建军节");
     * @param chineseHolidayMap
     *            自定义农历节日信息,特殊节日如除夕 用CHUXI表示,为null时,使用默认数据 ChineseHolidayEnum
     *            比如chineseHolidayMap.put("0707", "七夕情人节");
     * @param dateTypeMap 日期类型,0休息日,1等其他为工作日,比如dateTypeMap.put("2020-08-07", 0);
     * @return
     */
    private static CalendarWrapper generateCalendar(int year, boolean includeLunarDate, boolean includeHoliday,
            Map localHolidayMap, Map chineseHolidayMap, Map dateTypeMap) {
        CalendarWrapper calendarWrapper = new CalendarWrapper();
        Map dayMap = new ConcurrentHashMap();
        List dayList = new ArrayList();
        List monthWrapperList = new ArrayList<>();
        
        for (int i = 1; i <= 12; i++) {
            YearMonth yearMonth = YearMonth.of(year, i);
            List localDateTimeList = DateTimeCalculatorUtil.getLocalDateTimeList(YearMonth.of(year, i));
            if (CollectionUtil.isEmpty(localDateTimeList)) {
                continue;
            }
            List dayWrapperList = new ArrayList<>();
            localDateTimeList.stream().forEach(localDateTime -> {
                DayWrapper dayWrapper = new DayWrapper(localDateTime, includeLunarDate, includeHoliday, localHolidayMap,
                        chineseHolidayMap);
                dayWrapperList.add(dayWrapper);
                dayMap.put(DateTimeFormatterUtil.formatToDateStr(localDateTime), dayWrapper);
                dayList.add(dayWrapper);
            });

            MonthWrapper monthWrapper = new MonthWrapper(i, dayWrapperList, yearMonth.lengthOfMonth());
            monthWrapperList.add(monthWrapper);
        }
        
        // DateType
        if(CollectionUtil.isNotEmpty(dateTypeMap) && CollectionUtil.isNotEmpty(dayMap)){
            dateTypeMap.forEach((k,v)->{
                if(dayMap.containsKey(k)){
                    dayMap.get(k).setDateType(v);
                }
            });
        }

        List yearWrapperList = new ArrayList<>();
        YearWrapper yearWrapper = new YearWrapper(year, monthWrapperList);
        yearWrapperList.add(yearWrapper);
        calendarWrapper = new CalendarWrapper(yearWrapperList, dayMap, dayList);
        return calendarWrapper;
    }
}

 

2.日历应用使用

测试代码:

 

package com.xkzhangsan.time.test;

import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.junit.Test;

import com.xkzhangsan.time.calendar.CalendarUtil;
import com.xkzhangsan.time.calendar.CalendarWrapper;
import com.xkzhangsan.time.calendar.DayWrapper;
import com.xkzhangsan.time.calendar.MonthWrapper;

public class CalendarTest {

    /**
     * 日历基本测试 generateCalendarWithHoliday
     */
    @Test
    public void calendarTest() {
        // 获取2020年日历,包含农历和所有节假日信息
        CalendarWrapper calendarWrapper = CalendarUtil.generateCalendarWithHoliday(2020, 3);
        // 输出年
        System.out.println(calendarWrapper.getYears().get(0).getYear());
        // 输出1月
        System.out.println(calendarWrapper.getYears().get(0).getMonths().get(0).getMonth());
        // 输出1日
        System.out.println(calendarWrapper.getYears().get(0).getMonths().get(0).getDays().get(0).getDay());
        // 输出1日日期格式化
        System.out.println(calendarWrapper.getYears().get(0).getMonths().get(0).getDays().get(0).getDateStr());
        // 输出1日星期
        System.out.println(calendarWrapper.getYears().get(0).getMonths().get(0).getDays().get(0).getWeekCnLong());
        // 输出1日的数据值
        System.out.println(calendarWrapper.getYears().get(0).getMonths().get(0).getDays().get(0).getObj());

        // 获取指定日期的天,并对当前天设置扩展信息
        DayWrapper dayW = calendarWrapper.getDayMap().get("2020-03-15");
        if (dayW != null) {
            dayW.setObj("hello 2020-03-15!");
        }

        // 获取指定日期的天的扩展信息
        System.out.println(calendarWrapper.getDayMap().get("2020-03-15").getObj());
        System.out.println(calendarWrapper.getYears().get(0).getMonths().get(0).getDays().get(14).getObj());

        MonthWrapper month = calendarWrapper.getYears().get(0).getMonths().get(0);
        int length = month.getLength();
        List days = month.getDays();
        int blankNum = days.get(0).getWeek();
        if (blankNum == 7) {
            blankNum = 0;
        }

        // 打印日历
        // 1.表头
        System.out.println("===================================================" + month.getMonthCnLong()+ "=================================================");
        System.out.print("日\t\t一\t\t二\t\t三\t\t四\t\t五\t\t六\n");

        // 循环打印日历内容
        // 记录当前日期值
        int count = 0;
        for (int i = 0; i < 6; i++) {
            for (int j = 0; j < 7; j++) {
                // 打印空白
                if (i == 0 && j < blankNum) {
                    System.out.print("\t\t");
                    continue;
                }

                if (count >= length) {
                    break;
                }

                // 打印日期信息
                DayWrapper dayWrapper = days.get(count);
                System.out.print(dayWrapper.getDay() + "\t\t");//
                count++;
            }
            System.out.println();
        }
    }

    /*
     * 日历自定义测试 generateCalendarWithHoliday
     */
    @Test
    public void calendarCustomTest() {
        // 公历节假日自定义
        Map localHolidayMap = new HashMap<>();
        localHolidayMap.put("0801", "建军节");

        // 农历节假日自定义
        Map chineseHolidayMap = new HashMap<>();
        chineseHolidayMap.put("0707", "七夕情人节");

        // 工作日自定义 2020-08-07周五本为工作日,这里特别设置为非工作日,2020-08-08周六本为非工作日,这里特别设置为工作日
        Map dateTypeMap = new HashMap<>();
        dateTypeMap.put("2020-08-07", 0);
        dateTypeMap.put("2020-08-08", 1);

        // 获取2020年8月日历,包含农历和所有节假日信息,包含自定义数据
        CalendarWrapper calendarWrapper = CalendarUtil.generateCalendarWithHoliday(2020, 8, localHolidayMap,
                chineseHolidayMap, dateTypeMap);
        MonthWrapper month = calendarWrapper.getYears().get(0).getMonths().get(0);
        int length = month.getLength();
        List days = month.getDays();
        int blankNum = days.get(0).getWeek();
        if (blankNum == 7) {
            blankNum = 0;
        }

        // 打印日历
        // 1.表头
        System.out.println("===================================================" + month.getMonthCnLong()+ "=================================================");
        System.out.print("日\t\t一\t\t二\t\t三\t\t四\t\t五\t\t六\n");

        // 循环打印日历内容
        // 记录当前日期值
        int count = 0;
        for (int i = 0; i < 6; i++) {
            for (int j = 0; j < 7; j++) {
                // 打印空白
                if (i == 0 && j < blankNum) {
                    System.out.print("\t\t");
                    continue;
                }

                if (count >= length) {
                    break;
                }

                // 打印日期信息
                DayWrapper dayWrapper = days.get(count);
                System.out.print(dayWrapper.getDay() + "(");//
                System.out.print(dayWrapper.getLocalHoliday());//公历节假日,会打印上面定义的 建军节
                System.out.print(dayWrapper.getLunarDay());//农历天
                System.out.print(dayWrapper.getChineseHoliday());//农历节假日,会打印上面定义的 七夕情人节
                System.out.print(dayWrapper.getSolarTerm());//二十四节气
                //是否工作日,1是,0否,默认周一到周五为工作日,周六周日为非工作日,
                //2020-08-07周五本为工作日,这里特别设置为非工作日,2020-08-08周六本为非工作日,这里特别设置为工作日,会重新设置
                System.out.print(dayWrapper.getDateType());
                System.out.print(")\t\t");
                count++;
            }
            System.out.println();
        }
    }
}

 

输出:

 

2020
3
1
2020-03-01
星期日
null
hello 2020-03-15!
hello 2020-03-15!
===================================================三月=================================================
日        一        二        三        四        五        六
1        2        3        4        5        6        7        
8        9        10        11        12        13        14        
15        16        17        18        19        20        21        
22        23        24        25        26        27        28        
29        30        31        
===================================================八月=================================================
日        一        二        三        四        五        六
                                                1(建军节十二0)        
2(十三0)        3(十四1)        4(十五1)        5(十六1)        6(十七1)        7(十八立秋0)        8(十九1)        
9(二十0)        10(廿一1)        11(廿二1)        12(廿三1)        13(廿四1)        14(廿五1)        15(廿六0)        
16(廿七0)        17(廿八1)        18(廿九1)        19(初一1)        20(初二1)        21(初三1)        22(初四0)        
23(初五处暑0)        24(初六1)        25(初七七夕情人节1)        26(初八1)        27(初九1)        28(初十1)        29(十一0)        
30(十二0)        31(十三1)        

 

欢迎提问题和建议!

 

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

 

Java日期时间API系列26—–Jdk8中java.time包中的新的日期时间API类,YearMonth类的源码,转换和应用。

Java8中为年月新增了类YearMonth,可以用来表示卡片过期时间等问题。

1.YearMonth

默认格式为:2007-12

1.1 部分源码

*
 * @implSpec
 * This class is immutable and thread-safe.
 *
 * @since 1.8
 */
public final class YearMonth
        implements Temporal, TemporalAdjuster, Comparable, Serializable {

    /**
     * Serialization version.
     */
    private static final long serialVersionUID = 4183400860270640070L;
    /**
     * Parser.
     */
    private static final DateTimeFormatter PARSER = new DateTimeFormatterBuilder()
        .appendValue(YEAR, 4, 10, SignStyle.EXCEEDS_PAD)
        .appendLiteral('-')
        .appendValue(MONTH_OF_YEAR, 2)
        .toFormatter();

    /**
     * The year.
     */
    private final int year;
    /**
     * The month-of-year, not null.
     */
    private final int month;

通过源码可以看出使用final修饰YearMonth,YearMonth是线程安全类,同时实现了Temporal, TemporalAdjuster, Comparable, Serializable接口,有属性读取,设置和加减等功能。

 

 

 1.2 创建和基本使用

        YearMonth yearMonth = YearMonth.now();
        YearMonth yearMonth2 = YearMonth.of(2020, 4);
        
        System.out.println(yearMonth);
        System.out.println(yearMonth2);
        YearMonth yearMonth3 = YearMonth.parse("2020-05");
        System.out.println(yearMonth3);
        
        YearMonth yearMonth4 = yearMonth3.plusMonths(1);
        System.out.println(yearMonth4);

输出:

2020-03
2020-04
2020-05
2020-06

 

2.应用

2.1 转换

如Date转YearMonth,YearMonth转Date等
    /**
     * Date转YearMonth
     * @param date
     * @return
     */
    public static YearMonth toYearMonth(Date date){
        LocalDate localDate = toLocalDate(date);
        return YearMonth.of(localDate.getYear(), localDate.getMonthValue());
    }
    
    /**
     * LocalDateTime转YearMonth
     * @param localDateTime
     * @return
     */
    public static YearMonth toYearMonth(LocalDateTime localDateTime){
        LocalDate localDate = toLocalDate(localDateTime);
        return YearMonth.of(localDate.getYear(), localDate.getMonthValue());
    }
    
    /**
     * LocalDate转YearMonth
     * @param localDate
     * @return
     */
    public static YearMonth toYearMonth(LocalDate localDate){
        Objects.requireNonNull(localDate, "localDate");
        return YearMonth.of(localDate.getYear(), localDate.getMonthValue());
    }
    
    /**
     * Instant转YearMonth
     * @param instant
     * @return
     */
    public static YearMonth toYearMonth(Instant instant){
        LocalDate localDate = toLocalDate(instant);
        return YearMonth.of(localDate.getYear(), localDate.getMonthValue());
    }
    
    /**
     * ZonedDateTime转YearMonth
     * @param zonedDateTime
     * @return
     */
    public static YearMonth toYearMonth(ZonedDateTime zonedDateTime){
        LocalDate localDate = toLocalDate(zonedDateTime);
        return YearMonth.of(localDate.getYear(), localDate.getMonthValue());
    }

    /**
     * YearMonth转Date
     * 注意dayOfMonth范围:1到31之间,最大值根据月份确定特殊情况,如2月闰年29,非闰年28
     * 如果要转换为当月最后一天,可以使用下面方法:toDateEndOfMonth(YearMonth)
     * @param yearMonth
     * @param dayOfMonth
     * @return
     */
    public static Date toDate(YearMonth yearMonth, int dayOfMonth) {
        Objects.requireNonNull(yearMonth, "yearMonth");
        return toDate(yearMonth.atDay(dayOfMonth));
    }
    
    /**
     * YearMonth转Date,转换为当月第一天
     * @param yearMonth
     * @return
     */
    public static Date toDateStartOfMonth(YearMonth yearMonth) {
        return toDate(yearMonth, 1);
    }
    
    /**
     * YearMonth转Date,转换为当月最后一天
     * @param yearMonth
     * @return
     */
    public static Date toDateEndOfMonth(YearMonth yearMonth) {
        Objects.requireNonNull(yearMonth, "yearMonth");
        return toDate(yearMonth.atEndOfMonth());
    }

    /**
     * YearMonth转LocalDate
     * 注意dayOfMonth范围:1到31之间,最大值根据月份确定特殊情况,如2月闰年29,非闰年28
     * 如果要转换为当月最后一天,可以使用下面方法:toLocalDateEndOfMonth(YearMonth)
     * @param yearMonth
     * @param dayOfMonth
     * @return
     */
    public static LocalDate toLocalDate(YearMonth yearMonth, int dayOfMonth) {
        Objects.requireNonNull(yearMonth, "yearMonth");
        return yearMonth.atDay(dayOfMonth);
    }
    
    /**
     * YearMonth转LocalDate,转换为当月第一天
     * @param yearMonth
     * @return
     */
    public static LocalDate toLocalDateStartOfMonth(YearMonth yearMonth) {
        return toLocalDate(yearMonth, 1);
    }
    
    /**
     * YearMonth转LocalDate,转换为当月最后一天
     * @param yearMonth
     * @return
     */
    public static LocalDate toLocalDateEndOfMonth(YearMonth yearMonth) {
        Objects.requireNonNull(yearMonth, "yearMonth");
        return yearMonth.atEndOfMonth();
    }

 

测试代码:

    @Test
    public void yearMonthConverterTest(){
        System.out.println("===================yearMonthConverterTest=====================");
        Date date = new Date();
        System.out.println(date);
        YearMonth yearMonth = DateTimeConverterUtil.toYearMonth(date);
        System.out.println(yearMonth);
        
        Date date1 = DateTimeConverterUtil.toDate(yearMonth, 15);
        //转换为当月第一天
        Date date2 = DateTimeConverterUtil.toDateStartOfMonth(yearMonth);
        //转换为当月最后一天
        Date date3 = DateTimeConverterUtil.toDateEndOfMonth(yearMonth);
        System.out.println(date1);
        System.out.println(date2);
        System.out.println(date3);
        
        LocalDate LocalDate1 = DateTimeConverterUtil.toLocalDate(yearMonth, 15);
        //转换为当月第一天
        LocalDate LocalDate2 = DateTimeConverterUtil.toLocalDateStartOfMonth(yearMonth);
        //转换为当月最后一天
        LocalDate LocalDate3 = DateTimeConverterUtil.toLocalDateEndOfMonth(yearMonth);
        System.out.println(LocalDate1);
        System.out.println(LocalDate2);
        System.out.println(LocalDate3);
    }

 

输出:

===================yearMonthConverterTest=====================
Fri Mar 20 23:41:41 CST 2020
2020-03
Sun Mar 15 00:00:00 CST 2020
Sun Mar 01 00:00:00 CST 2020
Tue Mar 31 00:00:00 CST 2020
2020-03-15
2020-03-01
2020-03-31

 

2.2 计算

获取起始日期中间的日期列表,获取指定月份的日期列表,判断是否过期等等

    /**
     * 获取指定区间的时间列表,包含起始
     * @param startInclusive
     * @param endInclusive
     * @return
     */
    public static List getLocalDateTimeList(LocalDateTime startInclusive, LocalDateTime endInclusive){
        Objects.requireNonNull(startInclusive, "startInclusive");
        Objects.requireNonNull(endInclusive, "endInclusive");
        if(startInclusive.isAfter(endInclusive)){
            throw new DateTimeException("startInclusive must before or equal endInclusive!");
        }
        List localDateTimeList = new ArrayList();
        long days = betweenTotalDays(startInclusive, endInclusive)+1;
        for(long i=0; i){
            localDateTimeList.add(startInclusive.plusDays(i));
        }
        return localDateTimeList;
    }
    
    /**
     * 获取指定区间的时间列表,包含起始
     * @param startInclusive
     * @param endInclusive
     * @return
     */
    public static List getLocalDateList(LocalDate startInclusive, LocalDate endInclusive){
        return getLocalDateTimeList(DateTimeConverterUtil.toLocalDateTime(startInclusive),
                DateTimeConverterUtil.toLocalDateTime(endInclusive)).stream()
                        .map(localDateTime -> localDateTime.toLocalDate()).collect(Collectors.toList());
    }
    
    /**
     * 获取指定区间的时间列表,包含起始
     * @param startInclusive
     * @param endInclusive
     * @return
     */
    public static List getDateList(Date startInclusive, Date endInclusive){
        return getLocalDateTimeList(DateTimeConverterUtil.toLocalDateTime(startInclusive),
                DateTimeConverterUtil.toLocalDateTime(endInclusive)).stream()
                        .map(localDateTime -> DateTimeConverterUtil.toDate(localDateTime)).collect(Collectors.toList());
    }
    
    /**
     *  获取指定年月的所有日期列表
     * @param YearMonth
     * @return
     */
    public static List getLocalDateList(YearMonth yearMonth){
        Objects.requireNonNull(yearMonth, "yearMonth");
        List localDateList = new ArrayList();
        long days = yearMonth.lengthOfMonth();
        LocalDate localDate = DateTimeConverterUtil.toLocalDateStartOfMonth(yearMonth);
        for(long i=0; i){
            localDateList.add(plusDays(localDate, i));
        }
        return localDateList;
    }
    
    /**
     *  获取指定年月的所有日期列表
     * @param yearMonthStr yyyy-MM
     * @return
     */
    public static List getLocalDateList(String yearMonthStr){
        Objects.requireNonNull(yearMonthStr, "yearMonthStr");
        YearMonth yearMonth = YearMonth.parse(yearMonthStr);
        return getLocalDateList(yearMonth);
    }
    
    /**
     *  获取指定年月的所有日期列表
     * @param yearMonth
     * @return
     */
    public static List getLocalDateTimeList(YearMonth yearMonth){
        return getLocalDateList(yearMonth).stream()
                .map(localDate -> DateTimeConverterUtil.toLocalDateTime(localDate)).collect(Collectors.toList());
    }    
    
    /**
     *  获取指定年月的所有日期列表
     * @param yearMonthStr yyyy-MM
     * @return
     */
    public static List getLocalDateTimeList(String yearMonthStr){
        return getLocalDateList(yearMonthStr).stream()
                .map(localDate -> DateTimeConverterUtil.toLocalDateTime(localDate)).collect(Collectors.toList());
    }
    
    /**
     * 获取指定年月的所有日期列表
     * @param yearMonthStr yyyy-MM
     * @return
     */
    public static List getDateList(String yearMonthStr){
        return getLocalDateList(yearMonthStr).stream().map(localDate -> DateTimeConverterUtil.toDate(localDate))
                .collect(Collectors.toList());
    }
    
    /**
     * 判断是否过期,(输入年月小于当前年月)
     * @param yearMonth
     * @return
     */
    public static boolean isExpiry(YearMonth yearMonth){
        Objects.requireNonNull(yearMonth, "yearMonth");
        if(yearMonth.isBefore(YearMonth.now())){
            return true;
        }
        return false;
    }
    
    /**
     * 判断是否过期,(输入年月小于当前年月)
     * @param yearMonthStr yyyy-MM
     * @return
     */
    public static boolean isExpiry(String yearMonthStr){
        Objects.requireNonNull(yearMonthStr, "yearMonthStr");
        YearMonth yearMonth = YearMonth.parse(yearMonthStr);
        return isExpiry(yearMonth);
    }

 

测试代码:

    /**
     * yearMonth测试
     */
    @Test
    public void yearMonthTest(){
        //是否过期
        System.out.println(DateTimeCalculatorUtil.isExpiry("2020-03"));
        
        //获取指定年月的所有日期列表
        List dateList = DateTimeCalculatorUtil.getDateList("2020-03");
        dateList.stream().forEach(date->{
            System.out.println(DateTimeFormatterUtil.formatToDateStr(date));
        });
        
        System.out.println("========================");

        //获取指定区间的时间列表,包含起始
        List dateList2 = DateTimeCalculatorUtil.getDateList(dateList.get(0), dateList.get(dateList.size()-1));
        dateList2.stream().forEach(date->{
            System.out.println(DateTimeFormatterUtil.formatToDateStr(date));
        });
        
    }

 

输出:

false
2020-03-01
2020-03-02
2020-03-03
2020-03-04
2020-03-05
2020-03-06
2020-03-07
2020-03-08
2020-03-09
2020-03-10
2020-03-11
2020-03-12
2020-03-13
2020-03-14
2020-03-15
2020-03-16
2020-03-17
2020-03-18
2020-03-19
2020-03-20
2020-03-21
2020-03-22
2020-03-23
2020-03-24
2020-03-25
2020-03-26
2020-03-27
2020-03-28
2020-03-29
2020-03-30
2020-03-31
========================
2020-03-01
2020-03-02
2020-03-03
2020-03-04
2020-03-05
2020-03-06
2020-03-07
2020-03-08
2020-03-09
2020-03-10
2020-03-11
2020-03-12
2020-03-13
2020-03-14
2020-03-15
2020-03-16
2020-03-17
2020-03-18
2020-03-19
2020-03-20
2020-03-21
2020-03-22
2020-03-23
2020-03-24
2020-03-25
2020-03-26
2020-03-27
2020-03-28
2020-03-29
2020-03-30
2020-03-31

 

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