Get the solar calendar date based on the lunar calendar date and convert it into a zodiac sign

package com.zsp.quartz.util;


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

//Calendar conversion tools: lunar and solar calendar date exchange (lunar calendar date range 19000101~20491229)
public class DateUtils {
    // Calculate the lunar date from 1900 to 2049
    private final static int[] LUNAR_INFO = {
            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
    };

    //Minimum year allowed to be entered
    private final static int MIN_YEAR = 1900;
    //Maximum year allowed to be entered
    private final static int MAX_YEAR = 2049;
    // Whether there is a leap month in the current year
    private static boolean isLeapYear;
    // Starting point for calculation of Gregorian calendar date
    private final static String START_DATE = "1900-01-30";


    /**
     * Determine whether it is a leap year
     * @param year
     * @return
     */
    public static boolean isLeapYear(int year) {
        if (year % 4 == 0) {
            if (year % 100 == 0) {
                if (year % 400 == 0) {
                    return true; // Divisible by 400, it is a leap year
                } else {
                    return false; // Divisible by 100 but not by 400, not a leap year
                }
            } else {
                return true; // Divisible by 4 but not 100, it is a leap year
            }
        } else {
            return false; // Not divisible by 4, not a leap year
        }
    }
    /**
     * Calculate which month is leap in lunar calendar {@code year} year 1-12, return 0 if there is no leap
     *
     * @param year lunar year
     * @return (int) month
     */
    private static int getLeapMonth(int year) {
        return (int) (LUNAR_INFO[year - 1900] & amp; 0xf);
    }

    /**
     * Calculate the number of leap months in the lunar calendar {@code year}
     *
     * @param year lunar year
     * @return (int) number of days
     */
    private static int getLeapMonthDays(int year) {
        if (getLeapMonth(year) != 0) {
            if ((LUNAR_INFO[year - 1900] & amp; 0xf0000) == 0) {
                return 29;
            } else {
                return 30;
            }
        } else {
            return 0;
        }
    }

    /**
     * Calculate the number of days in the lunar calendar {@code lunarYeay} year {@code month}
     *
     * @param lunarYeay lunar year
     * @param month lunar month
     * @return (int)The number of days in the month
     */
    private static int getMonthDays(int lunarYeay, int month) throws Exception {
        if ((month > 31) || (month < 0)) {
            throw (new Exception("The month is wrong!"));
        }
        // 0X0FFFF[0000 {1111 1111 1111} 1111] The 12 digits in the middle represent 12 months, 1 is a big month, 0 is a small month
        int bit = 1 << (16 - month);
        if (((LUNAR_INFO[lunarYeay - 1900] & amp; 0x0FFFF) & amp; bit) == 0) {
            return 29;
        } else {
            return 30;
        }
    }

    /**
     * Calculate the total number of days in the lunar {@code year} year
     *
     * @param year lunar year
     * @return (int) total number of days
     */
    private static int getYearDays(int year) {
        int sum = 29 * 12;
        for (int i = 0x8000; i >= 0x8; i >>= 1) {
            if ((LUNAR_INFO[year - 1900] & amp; 0xfff0 & amp; i) != 0) {
                sum + + ;
            }
        }
        return sum + getLeapMonthDays(year);
    }

    /**
     * Check whether the lunar date is legal
     *
     * @param lunarYear lunar year
     * @param lunarMonth lunar month
     * @param lunarDay lunar day
     * @param leapMonthFlag leap month flag
     * @throwsException
     */
    private static void checkLunarDate(int lunarYear, int lunarMonth, int lunarDay, boolean leapMonthFlag) throws Exception {
        if ((lunarYear < MIN_YEAR) || (lunarYear > MAX_YEAR)) {
            throw (new Exception("Illegal lunar year!"));
        }
        if ((lunarMonth < 1) || (lunarMonth > 12)) {
            throw (new Exception("Illegal lunar month!"));
        }
        if ((lunarDay < 1) || (lunarDay > 30)) { // Chinese months have at most 30 days
            throw (new Exception("Illegal lunar day number!"));
        }

        int leap = getLeapMonth(lunarYear);//Calculate which month should be leap in the year
        if ((leapMonthFlag == true) & amp; & amp; (lunarMonth != leap)) {
            throw (new Exception("Illegal leap month!"));
        }
    }

    /**
     * Convert lunar calendar to solar calendar
     *
     * @param lunarDate lunar date, format YYYYMMDD
     * @param leapMonthFlag whether it is a leap month
     * @return Gregorian date, format: YYYYMMDD
     * @throwsException
     */
    public static String lunarToSolar(String lunarDate, boolean leapMonthFlag) throws Exception {
        lunarDate = lunarDate.replace("-", "");
        int lunarYear = Integer.parseInt(lunarDate.substring(0, 4));
        //Calculate the solar calendar date of the lunar month in this year
// int lunarYear = Calendar.getInstance().get(Calendar.YEAR);
        int lunarMonth = Integer.parseInt(lunarDate.substring(4, 6));
        int lunarDay = Integer.parseInt(lunarDate.substring(6, 8));

        checkLunarDate(lunarYear, lunarMonth, lunarDay, leapMonthFlag);

        int offset = 0;

        for (int i = MIN_YEAR; i < lunarYear; i + + ) {
            int yearDaysCount = getYearDays(i); // Find the number of days in a certain year in the lunar calendar
            offset + = yearDaysCount;
        }
        //Calculate the leap months in the year
        int leapMonth = getLeapMonth(lunarYear);

        if (leapMonthFlag & amp; leapMonth != lunarMonth) {
            throw (new Exception("The leap month mark you entered is incorrect!"));
        }

        //There is no leap month in the current year or the month is earlier than the leap month or has the same name as the leap month
        if (leapMonth == 0 || (lunarMonth < leapMonth) || (lunarMonth == leapMonth & amp; & amp; !leapMonthFlag)) {
            for (int i = 1; i < lunarMonth; i + + ) {
                int tempMonthDaysCount = getMonthDays(lunarYear, i);
                offset + = tempMonthDaysCount;
            }

            // Check if the date is greater than the maximum day
            if (lunarDay > getMonthDays(lunarYear, lunarMonth)) {
                throw (new Exception("Illegal lunar date!"));
            }
            offset + = lunarDay; // Add the number of days in the month
        } else {//There is a leap month in the current year, and the month is later than or equal to the leap month
            for (int i = 1; i < lunarMonth; i + + ) {
                int tempMonthDaysCount = getMonthDays(lunarYear, i);
                offset + = tempMonthDaysCount;
            }
            if (lunarMonth > leapMonth) {
                int temp = getLeapMonthDays(lunarYear); // Calculate the number of leap month days
                offset + = temp; // Add the number of leap month days

                if (lunarDay > getMonthDays(lunarYear, lunarMonth)) {
                    throw (new Exception("Illegal lunar date!"));
                }
                offset + = lunarDay;
            } else { // If you need to calculate a leap month, you should first add the number of days in the ordinary month corresponding to the leap month.
                // Calculate the month as a leap month
                int temp = getMonthDays(lunarYear, lunarMonth); // Calculate the number of non-leap month days
                offset + = temp;

                if (lunarDay > getLeapMonthDays(lunarYear)) {
                    throw (new Exception("Illegal lunar date!"));
                }
                offset + = lunarDay;
            }
        }

        SimpleDateFormat formatter = new SimpleDateFormat("yyyy-MM-dd");
        Date myDate = null;
        myDate = formatter.parse(START_DATE);
        Calendar c = Calendar.getInstance();
        c.setTime(myDate);
        c.add(Calendar.DATE, offset);
        myDate = c.getTime();

        return formatter.format(myDate);
    }



    //Convert to zodiac sign by month and day number
    public static String convertConstellation(int month, int day) {
        String value = "";
        if (((month == 3) & amp; & amp; (day >= 21)) || ((month == 4) & amp; & amp; (day <= 19))) {
            value = "Aries";
        }
        if (((month == 4) & amp; & amp; (day >= 20)) || ((month == 5) & amp; & amp; (day <= 20))) {
            value = "Taurus";
        }
        if (((month == 5) & amp; & amp; (day >= 21)) || ((month == 6) & amp; & amp; (day <= 21))) {
            value = "Gemini";
        }
        if (((month == 6) & amp; & amp; (day >= 22)) || ((month == 7) & amp; & amp; (day <= 22))) {
            value = "Cancer";
        }
        if (((month == 7) & amp; & amp; (day >= 23)) || ((month == 8) & amp; & amp; (day <= 22))) {
            value = "Leo";
        }
        if (((month == 8) & amp; & amp; (day >= 23)) || ((month == 9) & amp; & amp; (day <= 22))) {
            value = "Virgo";
        }
        if (((month == 9) & amp; & amp; (day >= 23)) || ((month == 10) & amp; & amp; (day <= 23))) {
            value = "Libra";
        }
        if (((month == 10) & amp; & amp; (day >= 24)) || ((month == 11) & amp; & amp; (day <= 22))) {
            value = "Scorpio";
        }
        if (((month == 11) & amp; & amp; (day >= 23)) || ((month == 12) & amp; & amp; (day <= 21))) {
            value = "Sagittarius";
        }
        if (((month == 12) & amp; & amp; (day >= 22)) || ((month == 1) & amp; & amp; (day <= 19))) {
            value = "Capricorn";
        }
        if (((month == 1) & amp; & amp; (day >= 20)) || ((month == 2) & amp; & amp; (day <= 18))) {
            value = "Aquarius";
        }
        if (((month == 2) & amp; & amp; (day >= 19)) || ((month == 3) & amp; & amp; (day <= 20))) {
            value = "Pisces";
        }
        return value;
    }

    //Input ID number (lunar calendar) and output zodiac sign
    public static String IDCardByConstellation(String idCard){
        // Determine whether it is a leap year
        String year = idCard.substring(6, 9);
        boolean leapYear = isLeapYear(Integer.parseInt(year));
        // Get year, month and day
        String substring = idCard.substring(6, 14);
        try{
            // Convert to solar calendar (Gregorian calendar)
            String s = lunarToSolar(substring, leapYear);
            String[] split = s.split("-");
            int month = Integer.parseInt(split[1]);
            int day = Integer.parseInt(split[2]);
            return convertConstellation(month,day);
        } catch (Exception e) {
            e.printStackTrace();
        }
        return "";
    }


    public static void main(String[] args){
        String idCard = "400000200001010011";
        System.out.println(IDCardByConstellation(idCard));
    }


}

The knowledge points of the article match the official knowledge files, and you can further learn related knowledge. Java Skill TreeHomepageOverview 136427 people are learning the system