感谢 北京流年 https://blog.csdn.net/u010648159/article/details/79224993 分享,在他的基础上增加清明节、母亲节、父亲节算法

直接上代码

import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Date;
import java.util.Locale;

import org.apache.xmlbeans.impl.xb.xsdschema.Public;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

/**
 * 计算节假日期
 * @author zhan.zhu
 *
 */
public class DateToFestivalsUtil {
    
    protected static Logger logger=LoggerFactory.getLogger(DateToFestivalsUtil.class);
    
    
    private int year; // 农历的年份
    private int month;
    private int day;
    private String lunarMonth; // 农历的月份
    public int leapMonth = 0; // 闰的是哪个月
 
    final static String chineseNumber[] = { "一", "二", "三", "四", "五", "六", "七", "八", "九", "十", "十一", "十二" };
    static SimpleDateFormat chineseDateFormat = new SimpleDateFormat("yyyy年MM月dd日", Locale.CHINA);
    final static long[] lunarInfo = new long[] { //
            0x04bd8, 0x04ae0, 0x0a570, 0x054d5, 0x0d260, 0x0d950, 0x16554, 0x056a0, 0x09ad0, //
            0x055d2, 0x04ae0, 0x0a5b6, 0x0a4d0, 0x0d250, 0x1d255, 0x0b540, 0x0d6a0, 0x0ada2, //
            0x095b0, 0x14977, 0x04970, 0x0a4b0, 0x0b4b5, 0x06a50, 0x06d40, 0x1ab54, 0x02b60, //
            0x09570, 0x052f2, 0x04970, 0x06566, 0x0d4a0, 0x0ea50, 0x06e95, 0x05ad0, 0x02b60, //
            0x186e3, 0x092e0, 0x1c8d7, 0x0c950, 0x0d4a0, 0x1d8a6, 0x0b550, 0x056a0, 0x1a5b4, //
            0x025d0, 0x092d0, 0x0d2b2, 0x0a950, 0x0b557, 0x06ca0, 0x0b550, 0x15355, 0x04da0, //
            0x0a5d0, 0x14573, 0x052d0, 0x0a9a8, 0x0e950, 0x06aa0, 0x0aea6, 0x0ab50, 0x04b60, //
            0x0aae4, 0x0a570, 0x05260, 0x0f263, 0x0d950, 0x05b57, 0x056a0, 0x096d0, 0x04dd5, //
            0x04ad0, 0x0a4d0, 0x0d4d4, 0x0d250, 0x0d558, 0x0b540, 0x0b5a0, 0x195a6, 0x095b0, //
            0x049b0, 0x0a974, 0x0a4b0, 0x0b27a, 0x06a50, 0x06d40, 0x0af46, 0x0ab60, 0x09570, //
            0x04af5, 0x04970, 0x064b0, 0x074a3, 0x0ea50, 0x06b58, 0x055c0, 0x0ab60, 0x096d5, //
            0x092e0, 0x0c960, 0x0d954, 0x0d4a0, 0x0da50, 0x07552, 0x056a0, 0x0abb7, 0x025d0, //
            0x092d0, 0x0cab5, 0x0a950, 0x0b4a0, 0x0baa4, 0x0ad50, 0x055d9, 0x04ba0, 0x0a5b0, //
            0x15176, 0x052b0, 0x0a930, 0x07954, 0x06aa0, 0x0ad50, 0x05b52, 0x04b60, 0x0a6e6, //
            0x0a4e0, 0x0d260, 0x0ea65, 0x0d530, 0x05aa0, 0x076a3, 0x096d0, 0x04bd7, 0x04ad0, //
            0x0a4d0, 0x1d0b6, 0x0d250, 0x0d520, 0x0dd45, 0x0b5a0, 0x056d0, 0x055b2, 0x049b0, //
            0x0a577, 0x0a4b0, 0x0aa50, 0x1b255, 0x06d20, 0x0ada0 };
 
    // 农历部分假日
    final static String[] lunarHoliday = new String[] { "0100 除夕","0101 春节", "0115 元宵", "0505 端午", "0707 情人", "0715 中元", "0815 中秋", "0909 重阳", "1208 腊八", "1224 小年" };
 
    // 公历部分节假日
    final static String[] solarHoliday = new String[] { 
            "0101 元旦", "0214 情人", "0308 妇女", "0312 植树", "0315 消费者权益日", "0401 愚人", "0501 劳动", "0504 青年", 
            "0512 护士", "0601 儿童", "0701 建党", "0801 建军",  "0909 毛泽东逝世纪念", "0910 教师", "0928 孔子诞辰",
            "1001 国庆", "1006 老人", "1024 联合国日","1111 双11", "1112 孙中山诞辰纪念", "1220 澳门回归纪念", "1225 圣诞", "1226 毛泽东诞辰纪念" };
 
    // ====== 传回农历 y年的总天数
    final private static int yearDays(int y) {
        int i, sum = 348;
        for (i = 0x8000; i > 0x8; i >>= 1) {
            if ((lunarInfo[y - 1900] & i) != 0)
                sum += 1;
        }
        return (sum + leapDays(y));
    }
 
    // ====== 传回农历 y年闰月的天数
    final private static int leapDays(int y) {
        if (leapMonth(y) != 0) {
            if ((lunarInfo[y - 1900] & 0x10000) != 0)
                return 30;
            else
                return 29;
        } else
            return 0;
    }
 
    // ====== 传回农历 y年闰哪个月 1-12 , 没闰传回 0
    final private static int leapMonth(int y) {
        int result = (int) (lunarInfo[y - 1900] & 0xf);
        return result;
    }
 
    // ====== 传回农历 y年m月的总天数
    final private static int monthDays(int y, int m) {
        if ((lunarInfo[y - 1900] & (0x10000 >> m)) == 0)
            return 29;
        else
            return 30;
    }
 
    // ====== 传回农历 y年的生肖
    final public String animalsYear(int year) {
        final String[] Animals = new String[] { "鼠", "牛", "虎", "兔", "龙", "蛇", "马", "羊", "猴", "鸡", "狗", "猪" };
        return Animals[(year - 4) % 12];
    }
 
    // ====== 传入 月日的offset 传回干支, 0=甲子
    final private static String cyclicalm(int num) {
        final String[] Gan = new String[] { "甲", "乙", "丙", "丁", "戊", "己", "庚", "辛", "壬", "癸" };
        final String[] Zhi = new String[] { "子", "丑", "寅", "卯", "辰", "巳", "午", "未", "申", "酉", "戌", "亥" };
        return (Gan[num % 10] + Zhi[num % 12]);
    }
 
    // ====== 传入 offset 传回干支, 0=甲子
    final public String cyclical(int year) {
        int num = year - 1900 + 36;
        return (cyclicalm(num));
    }
 
    public static String getChinaDayString(int day) {
        String chineseTen[] = { "初", "十", "廿", "卅" };
        int n = day % 10 == 0 ? 9 : day % 10 - 1;
        if (day > 30)
            return "";
        if (day == 10)
            return "初十";
        else
            return chineseTen[day / 10] + chineseNumber[n];
    }
 
    /**
     * 传出y年m月d日对应的农历. yearCyl3:农历年与1864的相差数 ? monCyl4:从1900年1月31日以来,闰月数
     * dayCyl5:与1900年1月31日相差的天数,再加40 ?
     *
     * isday: 这个参数为false---日期为节假日时,阴历日期就返回节假日 ,true---不管日期是否为节假日依然返回这天对应的阴历日期
     *
     * @return
     */
    public String getLunarDate(int year_log, int month_log, int day_log,
                               boolean isday) {
        // @SuppressWarnings("unused")
        int yearCyl, monCyl, dayCyl;
        // int leapMonth = 0;
        String nowadays;
        Date baseDate = null;
        Date nowaday = null;
        try {
            baseDate = chineseDateFormat.parse("1900年1月31日");
        } catch (ParseException e) {
            e.printStackTrace(); // To change body of catch statement use
            // Options | File Templates.
        }
 
        nowadays = year_log + "年" + month_log + "月" + day_log + "日";
        try {
            nowaday = chineseDateFormat.parse(nowadays);
        } catch (ParseException e) {
            e.printStackTrace(); // To change body of catch statement use
            // Options | File Templates.
        }
 
        // 求出和1900年1月31日相差的天数
        int offset = (int) ((nowaday.getTime() - baseDate.getTime()) / 86400000L);
        dayCyl = offset + 40;
        monCyl = 14;
 
        // 用offset减去每农历年的天数
        // 计算当天是农历第几天
        // i最终结果是农历的年份
        // offset是当年的第几天
        int iYear, daysOfYear = 0;
        for (iYear = 1900; iYear < 10000 && offset > 0; iYear++) {
            daysOfYear = yearDays(iYear);
            offset -= daysOfYear;
            monCyl += 12;
        }
        if (offset < 0) {
            offset += daysOfYear;
            iYear--;
            monCyl -= 12;
        }
        // 农历年份
        year = iYear;
        setYear(year); // 设置公历对应的农历年份
 
        yearCyl = iYear - 1864;
        leapMonth = leapMonth(iYear); // 闰哪个月,1-12
        boolean leap = false;
 
        // 用当年的天数offset,逐个减去每月(农历)的天数,求出当天是本月的第几天
        int iMonth, daysOfMonth = 0;
        for (iMonth = 1; iMonth < 13 && offset > 0; iMonth++) {
            // 闰月
            if (leapMonth > 0 && iMonth == (leapMonth + 1) && !leap) {
                --iMonth;
                leap = true;
                daysOfMonth = leapDays(year);
            } else
                daysOfMonth = monthDays(year, iMonth);
 
            offset -= daysOfMonth;
            // 解除闰月
            if (leap && iMonth == (leapMonth + 1))
                leap = false;
            if (!leap)
                monCyl++;
        }
        // offset为0时,并且刚才计算的月份是闰月,要校正
        if (offset == 0 && leapMonth > 0 && iMonth == leapMonth + 1) {
            if (leap) {
                leap = false;
            } else {
                leap = true;
                --iMonth;
                --monCyl;
            }
        }
        // offset小于0时,也要校正
        if (offset < 0) {
            offset += daysOfMonth;
            --iMonth;
            --monCyl;
        }
        month = iMonth;
        setLunarMonth(chineseNumber[month - 1] + "月"); // 设置对应的阴历月份
        day = offset + 1;
 
        if (!isday) {
            // 如果日期为节假日则阴历日期则返回节假日
            // setLeapMonth(leapMonth);
            for (int i = 0; i < solarHoliday.length; i++) {
                // 返回公历节假日名称
                String sd = solarHoliday[i].split(" ")[0]; // 节假日的日期
                String sdv = solarHoliday[i].split(" ")[1]; // 节假日的名称
                String smonth_v = month_log + "";
                String sday_v = day_log + "";
                String smd = "";
                if (month_log < 10) {
                    smonth_v = "0" + month_log;
                }
                if (day_log < 10) {
                    sday_v = "0" + day_log;
                }
                smd = smonth_v + sday_v;
                if (sd.trim().equals(smd.trim())) {
                    return sdv;
                }
            }
 
            for (int i = 0; i < lunarHoliday.length; i++) {
                // 返回农历节假日名称
                String ld = lunarHoliday[i].split(" ")[0]; // 节假日的日期
                String ldv = lunarHoliday[i].split(" ")[1]; // 节假日的名称
                String lmonth_v = month + "";
                String lday_v = day + "";
                String lmd = "";
                if (month < 10) {
                    lmonth_v = "0" + month;
                }
                if (day < 10) {
                    lday_v = "0" + day;
                }
                lmd = lmonth_v + lday_v;
                if ("12".equals(lmonth_v)) { // 除夕夜需要特殊处理
                    if ((daysOfMonth == 29 && day == 29) || (daysOfMonth == 30 && day == 30)) {
                        return ldv;
                        //return "除夕";
                    }
                }
                if (ld.trim().equals(lmd.trim())) {
                    return ldv;
                }
            }
            String tombSweeping = DateToFestivalsUtil.isTombSweeping(year_log, month_log, day_log);
            if(tombSweeping !=null){
                return tombSweeping;
            }
            String motherOrFatherDay = DateToFestivalsUtil.getMotherOrFatherDay(year_log, month_log, day_log);
            
            if(motherOrFatherDay != null ){
                return motherOrFatherDay;
            }
        }
        
        return null;

// 此方法算出对应的农历的日期
        /*if (day == 1)
            return chineseNumber[month - 1] + "月";
        else
            return getChinaDayString(day);*/

}
 
    public String toString() {
        if (chineseNumber[month - 1] == "一" && getChinaDayString(day) == "初一")
            return "农历" + year + "年";
        else if (getChinaDayString(day) == "初一")
            return chineseNumber[month - 1] + "月";
        else
            return getChinaDayString(day);
        // return year + "年" + (leap ? "闰" : "") + chineseNumber[month - 1] +
        // "月" + getChinaDayString(day);
    }
 
    /*
     * public static void main(String[] args) { System.out.println(new
     * LunarCalendar().getLunarDate(2012, 1, 23)); }
     */
 
    public int getLeapMonth() {
        return leapMonth;
    }
 
    public void setLeapMonth(int leapMonth) {
        this.leapMonth = leapMonth;
    }
 
    /**
     * 得到当前日期对应的阴历月份
     *
     * @return
     */
    public String getLunarMonth() {
        return lunarMonth;
    }
 
    public void setLunarMonth(String lunarMonth) {
        this.lunarMonth = lunarMonth;
    }
 
    /**
     * 得到当前年对应的农历年份
     *
     * @return
     */
    public int getYear() {
        return year;
    }
 
    public void setYear(int year) {
        this.year = year;
    }
    
  //清明节
    private static String  isTombSweeping(int year, int month, int day) {
        if (month != 4){
            return null;
            }
        if (day != 4 && day != 5 && day != 6) {
            return null;
            }
        int tempYear = (year % 10) + (((year / 10) % 10) * 10);
        int tombSweepingDay = (int) ((tempYear * 0.2422 + 4.81) - (tempYear / 4));
        if (tombSweepingDay == day){
            return "清明节";
        } 
        return null;
    }
 
    //母亲节和父亲节
    private static String getMotherOrFatherDay(int year, int month, int day) {
        if (month != 5 && month != 6) return null;
        if ((month == 5 && (day < 8 || day > 14)) || (month == 6 && (day < 15 || day > 21))) return null;
        Calendar calendar = Calendar.getInstance();
        calendar.set(year, month - 1, 1);
        int weekDate = calendar.get(Calendar.DAY_OF_WEEK);
        weekDate = (weekDate == 1) ? 7 : weekDate - 1;
        switch (month) {
            case 5:
                if (day == 15 - weekDate) {
                    return "母亲节";
                }
                break;
            case 6:
                if (day == 22 - weekDate) {
                    return "父亲节";
                }
                break;
        }
        return null;
    }
    //统一调用的接口  
    public static  String  DateToYearMothDay(Date date ){
        SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd");
        String dateString = simpleDateFormat.format(date);
        String [] dates = dateString.split("-");
        DateToFestivalsUtil deUtil = new DateToFestivalsUtil();
        String name = deUtil.getLunarDate(Integer.parseInt(dates[0]), Integer.parseInt(dates[1]), Integer.parseInt(dates[2]),false);
        return name;
    }

public static void main(String[] args) throws ParseException { 
        String  date = "2019-02-04 21:59:06";
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        Date newDate = sdf.parse(date);

// 是节日返回 节日名称,不是节日返回null
        System.out.println(DateToFestivalsUtil.DateToYearMothDay(newDate));
   
    }

}
测试: 2019-02-04 21:59:06 为 除夕

测试: 2019-02-05 21:59:06 为 春节  ,其他的就不一一测试

java 传入一个日期, 计算公历节日和农历节假日的常用类(包括除夕、清明节、母亲节、父亲节的算法)相关推荐

  1. java 日历计算农历和节假日的常用类(包括除夕的算法)

    最近在写日历,发现很多开源的常用的日历根本不能显示出除夕这个节日,所以在github上找到一个计算出大部分农历之后修改了一下,这里科普下,除夕有可能是29,也有可能是30,中国农历一个月只有29天或者 ...

  2. java定义一个方法计算三角形,长方形,圆形面积和周长

    java定义一个方法计算三角形,长方形,圆形面积和周长 /*** 定义一个方法,返回一个圆的周长 半径* 定义一个方法,返回一个圆的面积 半径* 定义一个方法,返回一个矩形的周长 长 宽* 定义一个方 ...

  3. java判断一个日期是否为工作日

    java判断一个日期是否为工作日 /*** @Author :feiyang* @Date :Created in 7:47 PM 2019/12/3*/ public class LocalDate ...

  4. 分享一个自己写的取中国农历相关数据的类。包含:农历年月日,生肖,星座,年龄,天干,地支等方法...

    分享一个自己写的取中国农历相关数据的类.包含:农历年月日,生肖,星座,年龄,天干,地支等方法.此类自己花了一上午的时间写的,适用于像相亲网等类似的网站 主要使用了微软针对东亚地区的农历类Chinese ...

  5. Java实现简单日期计算功能

    使用java实现简单的日期计算,可以通过自定义日期类来实现,具体实现如下: 一.Date自定义类 在自定义Date类中,创建year.month.days的私有属性代表日期的年.月.日.并创建Gett ...

  6. 用java写一个日期相减方法

    你好,这是一个用于计算两个日期之间的天数差的 Java 方法: import java.time.LocalDate; import java.time.temporal.ChronoUnit;pub ...

  7. java传入一个字符串 将它分割成大写字符为首的字符串数组

    /*      * 传入一个字符串 将它分割成大写字符为首的字符串数组      */     private ArrayList<String> splitByUpperCase(Str ...

  8. JAVA传入一个字符串,返回一个字符串中的大写字母

    /**      *       * @param 传入一个字符串      * @return 返回一个字符串中的大写字母      */     private static String str ...

  9. java定义一个日期类 包括年 月 日_【说明】 设计一个日期类Date包括年、月、日等私有数据成员。要求实现日期..._考试资料网...

    填空题[说明] 设计一个日期类Date包括年.月.日等私有数据成员.要求实现日期的基本运算,如某日期加上天数.某日期减去天数.两日期相差的天数等. 在Date类中设计如下重载运算符函数: Date o ...

  10. 给定一个日期计算 days天后的日期

    //2019-10-31 //日期计算#include <iostream> using namespace std; typedef struct date{int year;//年in ...

最新文章

  1. 聊一聊对外API接口的存活检查可以怎么做
  2. asciidoc文件阅读_可搜索的文件? 是的你可以。 选择AsciiDoc的另一个原因
  3. 在墙上找垂直线_墙上如何快速找水平线
  4. nasa注册_今天是黑洞星期五!
  5. 程序员需要了解依赖冲突的原因以及解决办法
  6. 怎样搭建轻量级架构-代码组织篇
  7. mysql for vs2013_mysql vs2013
  8. 编程语言(1)--Go 语言环境安装
  9. Java程序员月薪三万,需要技术达到什么水平?
  10. python ----元组方法以及修改细节
  11. 初识Visual Studio 2010(四)—— 创建ASP.NET网站
  12. ftp中转服务器,bat实现的ftp中转
  13. 软件项目管理(学习笔记)
  14. 算法初阶05:魔方矩阵
  15. vue json对象转数组_vue-vue-router 快速了解,多看看能扎实基础
  16. 18个基于Web的代码开发编辑器
  17. Python123 英文字符的鲁棒输入
  18. 多视图几何三维重建实战系列之COLMAP
  19. 《东藏记》—— 读后总结
  20. AoPS Volume 1 基础数论 总结

热门文章

  1. mysql 唯一约束和唯一索引_谈谈唯一约束和唯一索引
  2. 软件开发中如何评估工作量
  3. QGIS快速提取建筑和道路矢量
  4. Tinder活号技术在YouTube上面居然有用模拟器和浏览器玩明白了使用谷歌下载的
  5. 国家2000坐标系的理解
  6. 16行Python代码 批量采集 短视频音乐素材❤
  7. [EE261学习笔记] 4.常用的几个傅里叶变换相关公式
  8. PLM系统的经济收益
  9. 【算法面试】TopN问题
  10. nginx的cgi模块