【记录】Java春运日期农历输出工具类

Java实现日历农历输出工具类

package com.bq.siem.common.util;

import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.time.LocalDate;
import java.time.format.DateTimeFormatter;
import java.util.*;

/**
 * @Description 农历工具类
 * @Author li
 * @Date 2022/3/15 21:45
 **/
public class LunarCalendarUtil {
    private static int year;
    private static int month;
    private static int day;
    private static boolean leap;
    final static String chineseNumber[] = {"01", "02", "03", "04", "05", "06", "07",
            "08", "09", "10", "11", "12"};
    static SimpleDateFormat chineseDateFormat = new SimpleDateFormat("yyyy-MM-dd");

    // 春运
    private static final String SPRING_FESTIVAL_FORMAT_DATE = "今天是%s 农历%s %s";
    // 春运开始日期
    private static final LocalDate START_SPRING_FESTIVAL_DATE = LocalDate.parse("2022-01-17", DateTimeFormatter.ofPattern("yyyy-MM-dd"));
    // 春运结束日期
    private static final LocalDate END_SPRING_FESTIVAL_DATE = LocalDate.parse("2022-02-25", DateTimeFormatter.ofPattern("yyyy-MM-dd"));

    public static void main(String[] args) throws ParseException {
//        LocalDate parse = LocalDate.parse("2022-01-17", DateTimeFormatter.ofPattern("yyyy-MM-dd"));
//        String day = "春运第%s天";
//        if (parse.isBefore(END_SPRING_FESTIVAL_DATE) && parse.isAfter(START_SPRING_FESTIVAL_DATE) ||
//                parse.equals(START_SPRING_FESTIVAL_DATE) || parse.equals(END_SPRING_FESTIVAL_DATE)
//        ) {
//            day = String.format(day, parse.toEpochDay() - START_SPRING_FESTIVAL_DATE.toEpochDay() + 1);
//        } else {
//            day = "春运已结束";
//        }
//        System.out.println(day);
        System.out.println(getSpringFestivalDate());
    }

    public static List<String> getNear7Days() {
        LocalDate firstDate = START_SPRING_FESTIVAL_DATE;
        LocalDate endDate = firstDate.plusDays(6);
        LocalDate nowDate = LocalDate.now();

        if (nowDate.isAfter(endDate)) {
            firstDate = nowDate.minusDays(6);
            endDate = nowDate;
        }
        List<String> list = new ArrayList<>();
        // 先补全近7日数据
        while (firstDate.isBefore(endDate) || firstDate.equals(endDate)) {
            String date = firstDate.format(DateTimeFormatter.ofPattern("MM-dd"));
            list.add(date);
            firstDate = firstDate.plusDays(1);
        }
        System.out.println(list);
        return list;
    }

    /**
     * @Description 获取春运日期
     * @Author li
     * @Date 2022/1/19 13:25
     * @Return
     **/
    public static String getSpringFestivalDate() {
        Calendar today = Calendar.getInstance();
        String day = "春运第%s天";
        if (LocalDate.now().equals(START_SPRING_FESTIVAL_DATE) ||
                LocalDate.now().equals(END_SPRING_FESTIVAL_DATE) ||
                (LocalDate.now().isBefore(END_SPRING_FESTIVAL_DATE) && LocalDate.now().isAfter(START_SPRING_FESTIVAL_DATE))) {
            day = String.format(day, LocalDate.now().toEpochDay() - START_SPRING_FESTIVAL_DATE.toEpochDay() + 1);
        } else {
            day = "春运已结束";
        }
        try {
            return String.format(SPRING_FESTIVAL_FORMAT_DATE,
                    formatShortDateC(chineseDateFormat.parse(LocalDate.now().toString())),
                    formatDateToChinese(qian(today)),
                    day);
        } catch (ParseException e) {
            e.printStackTrace();
        }
        return "";
    }

    /**
     * 格式化中文日期短日期格式
     *
     * @param gstrDate 输入欲格式化的日期
     * @return [yyyy年MM月dd日]
     */

    public static String formatShortDateC(Date gstrDate) {
        SimpleDateFormat formatter = new SimpleDateFormat("yyyy年MM月dd日");
        String pid = formatter.format(gstrDate);
        return pid;
    }

    /**
     * @Description 农历日期
     * @param date
     * @Author li
     * @Date 2022/3/15 21:49
     * @Return
     **/
    private static String formatDateToChinese(String date) {
        String[] split = date.split("-");
        return int2chineseNum(Integer.valueOf(split[1])) + "月" + int2chineseNum(Integer.valueOf(split[2])) + "日";
    }


    public static String int2chineseNum(int src) {
        final String num[] = {"零", "一", "二", "三", "四", "五", "六", "七", "八", "九"};
        final String unit[] = {"", "十", "百", "千", "万", "十", "百", "千", "亿", "十", "百", "千"};
        String dst = "";
        int count = 0;
        while (src > 0) {
            dst = (num[src % 10] + unit[count]) + dst;
            src = src / 10;
            count++;
        }
        return dst.replaceAll("零[千百十]", "零").replaceAll("零+万", "万")
                .replaceAll("零+亿", "亿").replaceAll("亿万", "亿零")
                .replaceAll("零+", "零").replaceAll("零$", "")
                .replaceAll("一十", "十")
                ;

    }

    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};

    // ====== 传回农历 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) {
        return (int) (lunarInfo[y - 1900] & 0xf);
    }

    // ====== 传回农历 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() {
        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 num = year - 1900 + 36;
        return (cyclicalm(num));
    }

    /** */
    /**
     *   * 传出y年m月d日对应的农历.   * yearCyl3:农历年与1864的相差数 ?   *
     * monCyl4:从1900年1月31日以来,闰月数   * dayCyl5:与1900年1月31日相差的天数,再加40 ?   * @param
     * cal   * @return
     */
    public static String qian(Calendar cal) {
        @SuppressWarnings("unused")
        int yearCyl, monCyl, dayCyl;
        int leapMonth = 0;
        Date baseDate = null;
        try {
            baseDate = chineseDateFormat.parse("1900-1-31");
        } catch (ParseException e) {
            e.printStackTrace(); // To change body of catch statement use
            // Options | File Templates.
        }
        // 求出和1900年1月31日相差的天数
        int offset = (int) ((cal.getTime().getTime() - baseDate.getTime()) / 86400000L);
        dayCyl = offset + 40;
        monCyl = 14;
        // 用offset减去每农历年的天数
        // 计算当天是农历第几天
        // i最终结果是农历的年份
        // offset是当年的第几天
        int iYear, daysOfYear = 0;
        for (iYear = 1900; iYear < 2050 && offset > 0; iYear++) {
            daysOfYear = yearDays(iYear);
            offset -= daysOfYear;
            monCyl += 12;
        }
        if (offset < 0) {
            offset += daysOfYear;
            iYear--;
            monCyl -= 12;
        }
        // 农历年份
        year = iYear;
        yearCyl = iYear - 1864;
        leapMonth = leapMonth(iYear); // 闰哪个月,1-12
        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;
        day = offset + 1;
        return year + "-" + (leap ? "闰" : "") + chineseNumber[month - 1]
                + "-" + day;
    }


    public static int doing(String date) throws ParseException {
        int ans = 0;  //默认是0,代表非节假日;1代表是节假日
        Calendar today = Calendar.getInstance();
        today.setTime(chineseDateFormat.parse(date));

        System.out.println("北京时间:" + chineseDateFormat.format(today.getTime())
                + " 农历" + qian(today));
        //today=null;

        String yang_time = chineseDateFormat.format(today.getTime());
        int yang_month = Integer.valueOf(yang_time.substring(5, 7));
        int yang_day = Integer.valueOf(yang_time.substring(8));

        String yin_time = qian(today);
        int yin_month = Integer.valueOf(yin_time.substring(5, 7));
        int yin_day = Integer.valueOf(yin_time.substring(8));

        if (veryfyYang(yang_month, yang_day)) {
            ans = 1;
        } else if (veryfyYin(yin_month, yin_day)) {
            ans = 1;
        }
        return ans;
    }

    public static boolean veryfyYang(int month, int day) {
        boolean isHoliday = false;
        //判断每个阳历月内的节日
        if (month == 1) {
            if (day == 1) {

            }
        }
        return isHoliday;
    }

    public static boolean veryfyYin(int month, int day) {
        boolean isHoliday = false;

        return isHoliday;
    }
}

输出结果:

 

LunarCalendar返回农历(阴历)日期的JAR包 根据指定日期计算对应农历日期(这个计算方法是网上找的,最初的作者是谁已经无法考证了,感谢网络资源吧!),本人封装成好用的JAR包后发不出来,供大家免费下载! toString()方法输出阴历日期(例如:癸巳年七月廿) getFullInfo()方法输出包括生肖在内的阴历日期(例如:癸巳年七月廿,生肖:蛇) 构建方法包括以下四种: public LunarCalendar(String year, String month, String date) public LunarCalendar(JComboBox jcYear, JComboBox jcMonth, JComboBox jcDate) public LunarCalendar(int year, int month, int date) public LunarCalendar(Calendar cal)) 使用前两种构建方法时,若文本内容不为数字,getErrorMessage会返回错误信息 方法摘要 java.lang.String getErrorMessage() 返回String类型的错误信息 java.lang.String getFullInfo() 返回String类型的详细阴历信息(例如:癸巳年七月廿,生肖:蛇) java.lang.String getLunarAnimal() 返回String类型的生肖(例如:蛇) java.lang.String getLunarDate() 返回String类型的阴历日期(例如:廿) java.lang.String getLunarMonth() 返回String类型的阴历月份(例如:七) java.lang.String getLunarYear() 返回String类型的阴历年份(天干地支,例如:癸巳) java.lang.String toString() 返回String类型的阴历日期(例如:癸巳年七月廿) JAR包名称:LunarCalendar version 1.0 8/26/2013 作者:Roy, Liu royliu90@live.cn
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值