Android移动开发-Android开发日历时常用的农历和公历换算代码工具类

下面是与Android开发日历时常用的有关农历计算、公历计算、二十四气节相关的代码工具类的代码。

  • Constant.java逻辑代码如下:
package com.fukaimei.calendar.calendar;

import com.fukaimei.calendar.R;

public class Constant {

    public final static String[] weekArray = {"星期一", "星期二",
            "星期三", "星期四", "星期五", "星期六", "星期日"};
    public final static String[] festivalArray = {"元旦", "春节", "元宵节",
            "妇女节", "清明", "劳动节", "母亲节", "儿童节", "端午节",
            "建党节", "七夕节", "中秋节", "国庆节", "重阳节", "圣诞节",
            "腊八节"};
    public final static Integer[] festivalResArray = {
            R.drawable.festival_yuandan, R.drawable.festival_spring, R.drawable.festival_yuanxiao,
            R.drawable.festival_women, R.drawable.festival_qingming, R.drawable.festival_work,
            R.drawable.festival_mother, R.drawable.festival_children, R.drawable.festival_duanwu,
            R.drawable.festival_party, R.drawable.festival_qixi, R.drawable.festival_zhongqiu,
            R.drawable.festival_guoqing, R.drawable.festival_chongyang, R.drawable.festival_christmas,
            R.drawable.festival_laba
    };

    public static String[] xuhaoArray = new String[]{
            "零", "一", "二", "三", "四", "五", "六", "七", "八", "九",
            "十", "十一", "十二", "十三", "十四",
            "十五", "十六", "十七", "十八", "十九",
            "二十", "二十一", "二十二", "二十三", "二十四",
            "二十五", "二十六", "二十七", "二十八", "二十九",
            "三十", "三十一", "三十二", "三十三", "三十四",
            "三十五", "三十六", "三十七", "三十八", "三十九",
            "四十", "四十一", "四十二", "四十三", "四十四",
            "四十五", "四十六", "四十七", "四十八", "四十九",
            "五十", "五十一", "五十二", "五十三", "五十四",
            "五十五", "五十六", "五十七", "五十八", "五十九",
            "六十", "六十一", "六十二", "六十三", "六十四",
            "六十五", "六十六", "六十七", "六十八", "六十九",
            "七十", "七十一", "七十二", "七十三", "七十四",
            "七十五", "七十六", "七十七", "七十八", "七十九",
            "八十", "八十一", "八十二", "八十三", "八十四",
            "八十五", "八十六", "八十七", "八十八", "八十九",
            "九十", "九十一", "九十二", "九十三", "九十四",
            "九十五", "九十六", "九十七", "九十八", "九十九",
    };

}
  • LunarCalendar.java逻辑代码如下:
package com.fukaimei.calendar.calendar;

import android.annotation.SuppressLint;

import com.fukaimei.calendar.bean.CalendarTransfer;

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

public class LunarCalendar {
    private int year;
    private int month;
    private int day;
    private String lunarMonth;   //农历的月份
    private boolean leap;
    public int leapMonth = 0;   //闰的是哪个月

    public final static String chineseNumber[] = {"一", "二", "三", "四", "五", "六", "七",
            "八", "九", "十", "十一", "十二"};
    @SuppressLint("SimpleDateFormat")
    private static SimpleDateFormat chineseDateFormat = new SimpleDateFormat("yyyy年MM月dd日");
    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[]{
            "0101 春节",
            "0115 元宵节",
            "0505 端午节",
            "0707 七夕节",
            "0715 中元节",
            "0815 中秋节",
            "0909 重阳节",
            "1208 腊八节",
            "1224 小年",
            "0100 除夕"
    };

    //公历部分节假日
    final static String[] solarHoliday = new String[]{
            "0101 元旦",
            "0214 情人节",
            "0308 妇女节",
            "0312 植树节",
            "0315 消费者日",
            "0401 愚人节",
            "0501 劳动节",
            "0504 青年节",
            "0601 儿童节",
            "0701 建党节",
            "0801 建军节",
            "0903 抗日胜利",
            "0910 教师节",
            "1001 国庆节",
            "1010 双十节",
            "1031 万圣节",
            "1111 光棍节",
            "1224 平安夜",
            "1225 圣诞节",
    };

    //公历部分节假日
    final static String[] weekHoliday = new String[]{
            "0527 母亲节",
            "0637 父亲节",
            "0744 感恩节",
    };

    // 传回农历 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(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 ?
     * <p>
     * isday: 这个参数为false---日期为节假日时,阴历日期就返回节假日 ,true---不管日期是否为节假日依然返回这天对应的阴历日期
     */
    @SuppressLint("DefaultLocale")
    public CalendarTransfer getLunarDate(int year_log, int month_log, int day_log, boolean isday) {
        int yearCyl, monCyl, dayCyl;
        String nowadays;
        Date baseDate = null;
        Date nowaday = null;
        try {
            baseDate = chineseDateFormat.parse("1900年1月31日");
        } catch (Exception e) {
            e.printStackTrace();
        }

        nowadays = year_log + "年" + month_log + "月" + day_log + "日";
        try {
            nowaday = chineseDateFormat.parse(nowadays);
        } catch (Exception e) {
            e.printStackTrace();
        }

        // 求出和1900年1月31日相差的天数
        int offset = (int) ((nowaday.getTime() - baseDate.getTime()) / 86400000L);
        dayCyl = offset + 40;
        monCyl = 14;

        // 用offset减去每农历年的天数,计算当天是农历第几天
        // iYear最终结果是农历的年份,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
        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++;
        }
        int daysOfThisMonth;
        if (leapMonth > 0 && iMonth == (leapMonth + 1) && !leap) {
            daysOfThisMonth = leapDays(year);
        } else {
            daysOfThisMonth = monthDays(year, iMonth);
        }
        // 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;

        CalendarTransfer trans = new CalendarTransfer();
        trans.lunar_year = year;
        trans.lunar_month = month;
        trans.lunar_day = day;
        if (day == 1) {
            trans.day_name = chineseNumber[month - 1] + "月";
            if (daysOfThisMonth < 30) {
                trans.day_name = trans.day_name + "小";
            }
            if (leap) {
                trans.day_name = "闰" + trans.day_name;
            }
        } else {
            trans.day_name = getChinaDayString(day);
        }
        return trans;
    }

    public static String[] termDays = new String[24];

    @SuppressLint("DefaultLocale")
    public CalendarTransfer getSubDate(CalendarTransfer lastTrans,
                                       int year_log, int month_log, int day_log, int weekday, boolean isday) {
        CalendarTransfer trans = new CalendarTransfer();
        String day_result = "";
        String day_name = "";
        if (lastTrans.lunar_month == 0 || lastTrans.lunar_day == 0
                || lastTrans.lunar_day == 29 || lastTrans.lunar_day == 30) {
            trans = getLunarDate(year_log, month_log, day_log, isday);
            day_name = trans.day_name;
        } else {
            trans = lastTrans;
            trans.lunar_day++;
            day_name = getChinaDayString(trans.lunar_day);
        }
        trans.solar_year = year_log;
        trans.solar_month = month_log;
        trans.solar_day = day_log;
        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 smd = String.format("%02d%02d", month_log, day_log);
                if (sd.equals(smd)) {
                    day_result = getLinkName(day_result, sdv);
                    break;
                }
            }

            for (int i = 0; i < weekHoliday.length; i++) {
                int weeknum = (day_log - 1) / 7;
                if (day_log - weeknum * 7 > 0) {
                    weeknum++;
                }
                //返回公历节假日名称
                String wd = weekHoliday[i].split(" ")[0];  //节假日的日期
                String wdv = weekHoliday[i].split(" ")[1]; //节假日的名称
                String wmd = String.format("%02d%d%d", month_log, weeknum, weekday);
                if (wd.equals(wmd)) {
                    day_result = getLinkName(day_result, wdv);
                    break;
                }
            }

            for (int i = 0; i < lunarHoliday.length; i++) {
                //返回农历节假日名称
                String ld = lunarHoliday[i].split(" ")[0];   //节假日的日期
                String ldv = lunarHoliday[i].split(" ")[1];  //节假日的名称
                String lmd = String.format("%02d%02d", trans.lunar_month, trans.lunar_day);
                if (ld.equals(lmd)) {
                    day_result = getLinkName(day_result, ldv);
                    break;
                }
            }

            if (termDays[0] == null || termDays[0].length() <= 0) {
                termDays = (new SolarTerm()).getSolarDays(year_log);
            }
            for (int i = 0; i < termDays.length; i++) {
                //返回农历二十四节气名称
                String td = termDays[i].split(" ")[0];   //二十四节气的日期
                String tdv = termDays[i].split(" ")[1];  //二十四节气的名称
                String tmd = String.format("%02d%02d", month_log, day_log);
                if (td.equals(tmd)) {
                    day_result = getLinkName(day_result, tdv);
                    break;
                }
            }
        }
        if (day_result.length() > 0) {
            trans.day_name = day_result;
        } else {
            trans.day_name = day_name;
        }
        return trans;
    }

    private String getLinkName(String str, String appendStr) {
        String fullStr = str;
        if (fullStr.length() == 0) {
            fullStr = appendStr;
        } else {
            fullStr = fullStr + "/" + appendStr;
        }
        return fullStr;
    }

    public String toString() {
        if (chineseNumber[month - 1] == "一" && getChinaDayString(day) == "初一")
            return "农历" + year + "年";
        else if (getChinaDayString(day) == "初一")
            return chineseNumber[month - 1] + "月";
        else
            return getChinaDayString(day);
    }

    public int getLeapMonth() {
        return leapMonth;
    }

    public void setLeapMonth(int leapMonth) {
        this.leapMonth = leapMonth;
    }

    // 得到当前日期对应的阴历月份
    public String getLunarMonth() {
        return lunarMonth;
    }

    public void setLunarMonth(String lunarMonth) {
        this.lunarMonth = lunarMonth;
    }

    // 得到当前年对应的农历年份
    public int getYear() {
        return year;
    }

    public void setYear(int year) {
        this.year = year;
    }
}
  • SolarTerm.java逻辑代码如下:
package com.fukaimei.calendar.calendar;

import java.util.Calendar;

public class SolarTerm {
    // ========角度变换===============
    private static final double rad = 180 * 3600 / Math.PI; // 每弧度的角秒数
    private static final double RAD = 180 / Math.PI; // 每弧度的角度数
    // ================日历计算===============
    private static final double J2000 = 2451545; // 2000年前儒略日数(2000-1-1 12:00:00格林威治平时)

    // =========黄赤交角及黄赤坐标变换===========
    private static final double hcjjB[] = {84381.448, -46.8150, -0.00059,
            0.001813};// 黄赤交角系数表
    private static final double preceB[] = {0, 50287.92262, 111.24406,
            0.07699, -0.23479, -0.00178, 0.00018, 0.00001};// Date黄道上的岁差p

    private double Y = 2000;
    private double M = 1;
    private double D = 1;
    private double h = 12;
    private double m = 0;
    private double s = 0;

    private static final double[] dts = {
            // 世界时与原子时之差计算表
            -4000, 108371.7, -13036.80, 392.000, 0.0000, -500, 17201.0,
            -627.82, 16.170, -0.3413, -150, 12200.6, -346.41, 5.403, -0.1593,
            150, 9113.8, -328.13, -1.647, 0.0377, 500, 5707.5, -391.41, 0.915,
            0.3145, 900, 2203.4, -283.45, 13.034, -0.1778, 1300, 490.1, -57.35,
            2.085, -0.0072, 1600, 120.0, -9.81, -1.532, 0.1403, 1700, 10.2,
            -0.91, 0.510, -0.0370, 1800, 13.4, -0.72, 0.202, -0.0193, 1830,
            7.8, -1.81, 0.416, -0.0247, 1860, 8.3, -0.13, -0.406, 0.0292, 1880,
            -5.4, 0.32, -0.183, 0.0173, 1900, -2.3, 2.06, 0.169, -0.0135, 1920,
            21.2, 1.69, -0.304, 0.0167, 1940, 24.2, 1.22, -0.064, 0.0031, 1960,
            33.2, 0.51, 0.231, -0.0109, 1980, 51.0, 1.29, -0.026, 0.0032, 2000,
            64.7, -1.66, 5.224, -0.2905, 2150, 279.4, 732.95, 429.579, 0.0158,
            6000};

    // 取整数部分
    public static double int2(double v) {
        v = Math.floor(v);
        if (v < 0)
            return v + 1;

        return v;
    }

    // 对超过0-2PI的角度转为0-2PI
    public static double rad2mrad(double v) {
        v = v % (2 * Math.PI);
        if (v < 0)
            return v + 2 * Math.PI;

        return v;
    }

    // 计算世界时与原子时之差,传入年
    public double deltatT(double y) {
        int i = 0;
        for (i = 0; i < 100; i += 5)
            if (y < dts[i + 5] || i == 95)
                break;

        double t1 = (y - dts[i]) / (dts[i + 5] - dts[i]) * 10;
        double t2 = t1 * t1;
        double t3 = t2 * t1;
        return dts[i + 1] + dts[i + 2] * t1 + dts[i + 3] * t2 + dts[i + 4] * t3;
    }

    // 传入儒略日(J2000起算),计算UTC与原子时的差(单位:日)
    public double deltatT2(double jd) {
        return this.deltatT(jd / 365.2425 + 2000) / 86400.0;
    }

    // 公历转儒略日,UTC=1表示原日期是UTC
    public double toJD(boolean UTC) {
        double y = this.Y; // 取出年月
        double m = this.M;
        double n = 0;

        if (m <= 2) {
            m += 12;
            y--;
        }

        if (this.Y * 372 + this.M * 31 + this.D >= 588829) {
            // 判断是否为格里高利历日1582*372+10*31+15
            n = int2(y / 100);
            n = 2 - n + int2(n / 4);// 加百年闰
        }

        n += int2(365.2500001 * (y + 4716)); // 加上年引起的偏移日数
        n += int2(30.6 * (m + 1)) + this.D; // 加上月引起的偏移日数及日偏移数
        n += ((this.s / 60 + this.m) / 60 + this.h) / 24 - 1524.5;
        if (UTC)
            return n + this.deltatT2(n - J2000);

        return n;
    }

    // 儒略日数转公历,UTC=1表示目标公历是UTC
    public void setFromJD(double jd, boolean UTC) {
        if (UTC)
            jd -= this.deltatT2(jd - J2000);

        jd += 0.5;

        // 取得日数的整数部份A及小数部分F
        double A = int2(jd);
        double F = jd - A;
        double D;

        if (A > 2299161) {
            D = int2((A - 1867216.25) / 36524.25);
            A += 1 + D - int2(D / 4);
        }
        A += 1524; // 向前移4年零2个月
        this.Y = int2((A - 122.1) / 365.25);// 年
        D = A - int2(365.25 * this.Y); // 去除整年日数后余下日数
        this.M = int2(D / 30.6001); // 月数
        this.D = D - int2(this.M * 30.6001);// 去除整月日数后余下日数
        this.Y -= 4716;
        this.M--;
        if (this.M > 12)
            this.M -= 12;
        if (this.M <= 2)
            this.Y++;
        // 日的小数转为时分秒
        F *= 24;
        this.h = int2(F);
        F -= this.h;
        F *= 60;
        this.m = int2(F);
        F -= this.m;
        F *= 60;
        this.s = F;
    }

    // 设置时间,参数例:"20000101 120000"或"20000101"
    public void setFromStr(String s) {
        this.Y = Double.parseDouble(s.substring(0, 4));
        this.M = Double.parseDouble(s.substring(4, 2));
        this.D = Double.parseDouble(s.substring(6, 2));
        this.h = Double.parseDouble(s.substring(9, 2));
        this.m = Double.parseDouble(s.substring(11, 2));
        this.s = Double.parseDouble(s.substring(13, 2)); /* 将5改为了2 */
    }

    // 日期转为串
    public String toStr() {
        String Y = "     " + (int) this.Y;
        String M = "0" + (int) this.M;
        String D = "0" + (int) this.D;

        double h = this.h, m = this.m, s = Math.floor(this.s + .5);
        if (s >= 60) {
            s -= 60;
            m++;
        }
        if (m >= 60) {
            m -= 60;
            h++;
        }
        String sh = "0" + (int) h, sm = "0" + (int) m, ss = "0" + (int) s;
        Y = Y.substring(Y.length() - 5, Y.length());
        M = M.substring(M.length() - 2, M.length());
        D = D.substring(D.length() - 2, D.length());
        sh = sh.substring(sh.length() - 2, sh.length());
        sm = sm.substring(sm.length() - 2, sm.length());
        ss = ss.substring(ss.length() - 2, ss.length());
        return Y + "-" + M + "-" + D + " " + sh + ":" + sm + ":" + ss;
    }

    // 算出:jd转到当地UTC后,UTC日数的整数部分或小数部分
    // 基于J2000力学时jd的起算点是12:00:00时,所以跳日时刻发生在12:00:00,这与日历计算发生矛盾
    // 把jd改正为00:00:00起算,这样儒略日的跳日动作就与日期的跳日同步
    // 改正方法为jd=jd+0.5-deltatT+shiqu/24
    // 把儒略日的起点移动-0.5(即前移12小时)
    // 式中shiqu是时区,北京的起算点是-8小时,shiqu取8
    public double Dint_dec(double jd, int shiqu, boolean dec) {
        double u = jd + 0.5 - this.deltatT2(jd) + shiqu / 24;
        if (dec)
            return Math.floor(u); // 返回整数部分
        else
            return u - Math.floor(u); // 返回小数部分
    }

    // 计算两个日期的相差的天数,输入字串格式日期,如:"20080101"
    double d1_d2(String d1, String d2) {
        double Y = this.Y, M = this.M, D = this.D, h = this.h, m = this.m, s = this.s; // 备份原来的数据

        this.setFromStr(d1.substring(0, 8) + " 120000");
        double jd1 = this.toJD(false);
        this.setFromStr(d2.substring(0, 8) + " 120000");
        double jd2 = this.toJD(false);

        this.Y = Y;
        this.M = M;
        this.D = D;
        this.h = h;
        this.m = m;
        this.s = s; // 还原
        if (jd1 > jd2)
            return Math.floor(jd1 - jd2 + .0001);
        else
            return -Math.floor(jd2 - jd1 + .0001);
    }

    // 返回黄赤交角(常规精度),短期精度很高
    public static double hcjj1(double t) {
        double t1 = t / 36525;
        double t2 = t1 * t1;
        double t3 = t2 * t1;
        return (hcjjB[0] + hcjjB[1] * t1 + hcjjB[2] * t2 + hcjjB[3] * t3) / rad;
    }

    // 黄赤转换(黄赤坐标旋转)
    public static void HCconv(double[] JW, double E) {
        // 黄道赤道坐标变换,赤到黄E取负
        double HJ = rad2mrad(JW[0]), HW = JW[1];
        double sinE = Math.sin(E), cosE = Math.cos(E);
        double sinW = cosE * Math.sin(HW) + sinE * Math.cos(HW) * Math.sin(HJ);
        double J = Math.atan2(Math.sin(HJ) * cosE - Math.tan(HW) * sinE,
                Math.cos(HJ));
        JW[0] = rad2mrad(J);
        JW[1] = Math.asin(sinW);
    }

    // 补岁差
    public static void addPrece(double jd, double[] zb) {
        int i;
        double t = 1, v = 0, t1 = jd / 365250;
        for (i = 1; i < 8; i++) {
            t *= t1;
            v += preceB[i] * t;
        }
        zb[0] = rad2mrad(zb[0] + (v + 2.9965 * t1) / rad);
    }

    // ===============光行差==================
    private static final double GXC_e[] = {0.016708634, -0.000042037,
            -0.0000001267}; // 离心率
    private static final double GXC_p[] = {102.93735 / RAD, 1.71946 / RAD,
            0.00046 / RAD}; // 近点
    private static final double GXC_l[] = {280.4664567 / RAD,
            36000.76982779 / RAD, 0.0003032028 / RAD, 1 / 49931000 / RAD,
            -1 / 153000000 / RAD}; // 太平黄经
    private static final double GXC_k = 20.49552 / rad; // 光行差常数

    // 恒星周年光行差计算(黄道坐标中)
    public static void addGxc(double t, double[] zb) {
        double t1 = t / 36525;
        double t2 = t1 * t1;
        double t3 = t2 * t1;
        double t4 = t3 * t1;
        double L = GXC_l[0] + GXC_l[1] * t1 + GXC_l[2] * t2 + GXC_l[3] * t3
                + GXC_l[4] * t4;
        double p = GXC_p[0] + GXC_p[1] * t1 + GXC_p[2] * t2;
        double e = GXC_e[0] + GXC_e[1] * t1 + GXC_e[2] * t2;
        double dL = L - zb[0], dP = p - zb[0];
        zb[0] -= GXC_k * (Math.cos(dL) - e * Math.cos(dP)) / Math.cos(zb[1]);
        zb[1] -= GXC_k * Math.sin(zb[1]) * (Math.sin(dL) - e * Math.sin(dP));
        zb[0] = rad2mrad(zb[0]);
    }

    // ===============章动计算==================
    private static final double nutB[] = {// 章动表
            2.1824391966, -33.757045954, 0.0000362262, 3.7340E-08, -2.8793E-10,
            -171996, -1742, 92025, 89, 3.5069406862, 1256.663930738,
            0.0000105845, 6.9813E-10, -2.2815E-10, -13187, -16, 5736, -31,
            1.3375032491, 16799.418221925, -0.0000511866, 6.4626E-08,
            -5.3543E-10, -2274, -2, 977, -5, 4.3648783932, -67.514091907,
            0.0000724525, 7.4681E-08, -5.7586E-10, 2062, 2, -895, 5,
            0.0431251803, -628.301955171, 0.0000026820, 6.5935E-10, 5.5705E-11,
            -1426, 34, 54, -1, 2.3555557435, 8328.691425719, 0.0001545547,
            2.5033E-07, -1.1863E-09, 712, 1, -7, 0, 3.4638155059,
            1884.965885909, 0.0000079025, 3.8785E-11, -2.8386E-10, -517, 12,
            224, -6, 5.4382493597, 16833.175267879, -0.0000874129, 2.7285E-08,
            -2.4750E-10, -386, -4, 200, 0, 3.6930589926, 25128.109647645,
            0.0001033681, 3.1496E-07, -1.7218E-09, -301, 0, 129, -1,
            3.5500658664, 628.361975567, 0.0000132664, 1.3575E-09, -1.7245E-10,
            217, -5, -95, 3};

    public static class ZD {
        public double Lon;
        public double Obl;
    }

    // 计算黄经章动及交角章动
    public static ZD nutation(double t) {
        ZD d = new ZD();
        d.Lon = 0;
        d.Obl = 0;
        t /= 36525;
        double c, t1 = t, t2 = t1 * t1, t3 = t2 * t1, t4 = t3 * t1;// t5=t4*t1;
        for (int i = 0; i < nutB.length; i += 9) {
            c = nutB[i] + nutB[i + 1] * t1 + nutB[i + 2] * t2 + nutB[i + 3]
                    * t3 + nutB[i + 4] * t4;
            d.Lon += (nutB[i + 5] + nutB[i + 6] * t / 10) * Math.sin(c); // 黄经章动
            d.Obl += (nutB[i + 7] + nutB[i + 8] * t / 10) * Math.cos(c); // 交角章动
        }
        d.Lon /= rad * 10000; // 黄经章动
        d.Obl /= rad * 10000; // 交角章动
        return d;
    }

    // 本函数计算赤经章动及赤纬章动
    public static void nutationRaDec(double t, double[] zb) {
        double Ra = zb[0], Dec = zb[1];
        double E = hcjj1(t), sinE = Math.sin(E), cosE = Math.cos(E); // 计算黄赤交角
        ZD d = nutation(t); // 计算黄经章动及交角章动
        double cosRa = Math.cos(Ra), sinRa = Math.sin(Ra);
        double tanDec = Math.tan(Dec);
        zb[0] += (cosE + sinE * sinRa * tanDec) * d.Lon - cosRa * tanDec
                * d.Obl; // 赤经章动
        zb[1] += sinE * cosRa * d.Lon + sinRa * d.Obl; // 赤纬章动
        zb[0] = rad2mrad(zb[0]);
    }

    // =================以下是月球及地球运动参数表===================
    /***************************************
     * 如果用记事本查看此代码,请在"格式"菜单中去除"自动换行" E10是关于地球的,格式如下:
     * 它是一个数组,每3个数看作一条记录,每条记录的3个数记为A,B,C rec=A*cos(B+C*t); 式中t是J2000起算的儒略千年数
     * 每条记录的计算结果(即rec)取和即得地球的日心黄经的周期量L0 E11格式如下: rec = A*cos*(B+C*t) *t,
     * 取和后得泊松量L1 E12格式如下: rec = A*cos*(B+C*t) *t*t, 取和后得泊松量L2 E13格式如下: rec =
     * A*cos*(B+C*t) *t*t*t, 取和后得泊松量L3 最后地球的地心黄经:L = L0+L1+L2+L3+...
     * E20,E21,E22,E23...用于计算黄纬 M10,M11等是关于月球的,参数的用法请阅读Mnn()函数
     *****************************************/
    // 地球运动VSOP87参数
    private static final double E10[] = { // 黄经周期项
            1.75347045673, 0.00000000000, 0.0000000000,
            0.03341656456, 4.66925680417, 6283.0758499914,
            0.00034894275, 4.62610241759, 12566.1516999828,
            0.00003417571, 2.82886579606, 3.5231183490,
            0.00003497056, 2.74411800971, 5753.3848848968,
            0.00003135896, 3.62767041758, 77713.7714681205,
            0.00002676218, 4.41808351397, 7860.4193924392,
            0.00002342687, 6.13516237631, 3930.2096962196,
            0.00001273166, 2.03709655772, 529.6909650946,
            0.00001324292, 0.74246356352, 11506.7697697936,
            0.00000901855, 2.04505443513, 26.2983197998,
            0.00001199167, 1.10962944315, 1577.3435424478,
            0.00000857223, 3.50849156957, 398.1490034082,
            0.00000779786, 1.17882652114, 5223.6939198022,
            0.00000990250, 5.23268129594, 5884.9268465832,
            0.00000753141, 2.53339053818, 5507.5532386674,
            0.00000505264, 4.58292563052, 18849.2275499742,
            0.00000492379, 4.20506639861, 775.5226113240,
            0.00000356655, 2.91954116867, 0.0673103028,
            0.00000284125, 1.89869034186, 796.2980068164,
            0.00000242810, 0.34481140906, 5486.7778431750,
            0.00000317087, 5.84901952218, 11790.6290886588,
            0.00000271039, 0.31488607649, 10977.0788046990,
            0.00000206160, 4.80646606059, 2544.3144198834,
            0.00000205385, 1.86947813692, 5573.1428014331,
            0.00000202261, 2.45767795458, 6069.7767545534,
            0.00000126184, 1.08302630210, 20.7753954924,
            0.00000155516, 0.83306073807, 213.2990954380,
            0.00000115132, 0.64544911683, 0.9803210682,
            0.00000102851, 0.63599846727, 4694.0029547076,
            0.00000101724, 4.26679821365, 7.1135470008,
            0.00000099206, 6.20992940258, 2146.1654164752,
            0.00000132212, 3.41118275555, 2942.4634232916,
            0.00000097607, 0.68101272270, 155.4203994342,
            0.00000085128, 1.29870743025, 6275.9623029906,
            0.00000074651, 1.75508916159, 5088.6288397668,
            0.00000101895, 0.97569221824, 15720.8387848784,
            0.00000084711, 3.67080093025, 71430.6956181291,
            0.00000073547, 4.67926565481, 801.8209311238,
            0.00000073874, 3.50319443167, 3154.6870848956,
            0.00000078756, 3.03698313141, 12036.4607348882,
            0.00000079637, 1.80791330700, 17260.1546546904,
            0.00000085803, 5.98322631256, 161000.6857376741,
            0.00000056963, 2.78430398043, 6286.5989683404,
            0.00000061148, 1.81839811024, 7084.8967811152,
            0.00000069627, 0.83297596966, 9437.7629348870,
            0.00000056116, 4.38694880779, 14143.4952424306,
            0.00000062449, 3.97763880587, 8827.3902698748,
            0.00000051145, 0.28306864501, 5856.4776591154,
            0.00000055577, 3.47006009062, 6279.5527316424,
            0.00000041036, 5.36817351402, 8429.2412664666,
            0.00000051605, 1.33282746983, 1748.0164130670,
            0.00000051992, 0.18914945834, 12139.5535091068,
            0.00000049000, 0.48735065033, 1194.4470102246,
            0.00000039200, 6.16832995016, 10447.3878396044,
            0.00000035566, 1.77597314691, 6812.7668150860,
            0.00000036770, 6.04133859347, 10213.2855462110,
            0.00000036596, 2.56955238628, 1059.3819301892,
            0.00000033291, 0.59309499459, 17789.8456197850,
            0.00000035954, 1.70876111898, 2352.8661537718};
    private static final double E11[] = { // 黄经泊松1项
            6283.31966747491, 0.00000000000, 0.0000000000,
            0.00206058863, 2.67823455584, 6283.0758499914,
            0.00004303430, 2.63512650414, 12566.1516999828,
            0.00000425264, 1.59046980729, 3.5231183490,
            0.00000108977, 2.96618001993, 1577.3435424478,
            0.00000093478, 2.59212835365, 18849.2275499742,
            0.00000119261, 5.79557487799, 26.2983197998,
            0.00000072122, 1.13846158196, 529.6909650946,
            0.00000067768, 1.87472304791, 398.1490034082,
            0.00000067327, 4.40918235168, 5507.5532386674,
            0.00000059027, 2.88797038460, 5223.6939198022,
            0.00000055976, 2.17471680261, 155.4203994342,
            0.00000045407, 0.39803079805, 796.2980068164,
            0.00000036369, 0.46624739835, 775.5226113240,
            0.00000028958, 2.64707383882, 7.1135470008,
            0.00000019097, 1.84628332577, 5486.7778431750,
            0.00000020844, 5.34138275149, 0.9803210682,
            0.00000018508, 4.96855124577, 213.2990954380,
            0.00000016233, 0.03216483047, 2544.3144198834,
            0.00000017293, 2.99116864949, 6275.9623029906};
    private static final double E12[] = { // 黄经泊松2项
            0.00052918870, 0.00000000000, 0.0000000000,
            0.00008719837, 1.07209665242, 6283.0758499914,
            0.00000309125, 0.86728818832, 12566.1516999828,
            0.00000027339, 0.05297871691, 3.5231183490,
            0.00000016334, 5.18826691036, 26.2983197998,
            0.00000015752, 3.68457889430, 155.4203994342,
            0.00000009541, 0.75742297675, 18849.2275499742,
            0.00000008937, 2.05705419118, 77713.7714681205,
            0.00000006952, 0.82673305410, 775.5226113240,
            0.00000005064, 4.66284525271, 1577.3435424478};
    private static final double E13[] = {
            0.00000289226, 5.84384198723, 6283.0758499914,
            0.00000034955, 0.00000000000, 0.0000000000,
            0.00000016819, 5.48766912348, 12566.1516999828};
    private static final double E14[] = {
            0.00000114084, 3.14159265359, 0.0000000000,
            0.00000007717, 4.13446589358, 6283.0758499914,
            0.00000000765, 3.83803776214, 12566.1516999828};
    private static final double E15[] = {
            0.00000000878, 3.14159265359, 0.0000000000};
    private static final double E20[] = { // 黄纬周期项
            0.00000279620, 3.19870156017, 84334.6615813083,
            0.00000101643, 5.42248619256, 5507.5532386674,
            0.00000080445, 3.88013204458, 5223.6939198022,
            0.00000043806, 3.70444689758, 2352.8661537718,
            0.00000031933, 4.00026369781, 1577.3435424478,
            0.00000022724, 3.98473831560, 1047.7473117547,
            0.00000016392, 3.56456119782, 5856.4776591154,
            0.00000018141, 4.98367470263, 6283.0758499914,
            0.00000014443, 3.70275614914, 9437.7629348870,
            0.00000014304, 3.41117857525, 10213.2855462110};
    private static final double E21[] = {
            0.00000009030, 3.89729061890, 5507.5532386674,
            0.00000006177, 1.73038850355, 5223.6939198022};
    private static final double E30[] = { // 距离周期项
            1.00013988799, 0.00000000000, 0.0000000000,
            0.01670699626, 3.09846350771, 6283.0758499914,
            0.00013956023, 3.05524609620, 12566.1516999828,
            0.00003083720, 5.19846674381, 77713.7714681205,
            0.00001628461, 1.17387749012, 5753.3848848968,
            0.00001575568, 2.84685245825, 7860.4193924392,
            0.00000924799, 5.45292234084, 11506.7697697936,
            0.00000542444, 4.56409149777, 3930.2096962196};
    private static final double E31[] = {
            0.00103018608, 1.10748969588, 6283.0758499914,
            0.00001721238, 1.06442301418, 12566.1516999828,
            0.00000702215, 3.14159265359, 0.0000000000};
    private static final double E32[] = {
            0.00004359385, 5.78455133738, 6283.0758499914};
    private static final double E33[] = {0.00000144595, 4.27319435148,
            6283.0758499914};
    // 月球运动参数
    private static final double M10[] = {22639.5858800, 2.3555545723,
            8328.6914247251, 1.5231275E-04, 2.5041111E-07, -1.1863391E-09,
            4586.4383203, 8.0413790709, 7214.0628654588, -2.1850087E-04,
            -1.8646419E-07, 8.7760973E-10, 2369.9139357, 10.3969336431,
            15542.7542901840, -6.6188121E-05, 6.3946925E-08, -3.0872935E-10,
            769.0257187, 4.7111091445, 16657.3828494503, 3.0462550E-04,
            5.0082223E-07, -2.3726782E-09, -666.4175399, -0.0431256817,
            628.3019552485, -2.6638815E-06, 6.1639211E-10, -5.4439728E-11,
            -411.5957339, 3.2558104895, 16866.9323152810, -1.2804259E-04,
            -9.8998954E-09, 4.0433461E-11, 211.6555524, 5.6858244986,
            -1114.6285592663, -3.7081362E-04, -4.3687530E-07, 2.0639488E-09,
            205.4359530, 8.0845047526, 6585.7609102104, -2.1583699E-04,
            -1.8708058E-07, 9.3204945E-10, 191.9561973, 12.7524882154,
            23871.4457149091, 8.6124629E-05, 3.1435804E-07, -1.4950684E-09,
            164.7286185, 10.4400593249, 14914.4523349355, -6.3524240E-05,
            6.3330532E-08, -2.5428962E-10, -147.3213842, -2.3986802540,
            -7700.3894694766, -1.5497663E-04, -2.4979472E-07, 1.1318993E-09,
            -124.9881185, 5.1984668216, 7771.3771450920, -3.3094061E-05,
            3.1973462E-08, -1.5436468E-10, -109.3803637, 2.3124288905,
            8956.9933799736, 1.4964887E-04, 2.5102751E-07, -1.2407788E-09,
            55.1770578, 7.1411231536, -1324.1780250970, 6.1854469E-05,
            7.3846820E-08, -3.4916281E-10, -45.0996092, 5.6113650618,
            25195.6237400061, 2.4270161E-05, 2.4051122E-07, -1.1459056E-09,
            39.5333010, -0.9002559173, -8538.2408905558, 2.8035534E-04,
            2.6031101E-07, -1.2267725E-09, 38.4298346, 18.4383127140,
            22756.8171556428, -2.8468899E-04, -1.2251727E-07, 5.6888037E-10,
            36.1238141, 7.0666637168, 24986.0742741754, 4.5693825E-04,
            7.5123334E-07, -3.5590172E-09, 30.7725751, 16.0827581417,
            14428.1257309177, -4.3700174E-04, -3.7292838E-07, 1.7552195E-09,
            -28.3971008, 7.9982533891, 7842.3648207073, -2.2116475E-04,
            -1.8584780E-07, 8.2317000E-10, -24.3582283, 10.3538079614,
            16171.0562454324, -6.8852003E-05, 6.4563317E-08, -3.6316908E-10,
            -18.5847068, 2.8429122493, -557.3142796331, -1.8540681E-04,
            -2.1843765E-07, 1.0319744E-09, 17.9544674, 5.1553411398,
            8399.6791003405, -3.5757942E-05, 3.2589854E-08, -2.0880440E-10,
            14.5302779, 12.7956138971, 23243.1437596606, 8.8788511E-05,
            3.1374165E-07, -1.4406287E-09, 14.3796974, 15.1080427876,
            32200.1371396342, 2.3843738E-04, 5.6476915E-07, -2.6814075E-09,
            14.2514576, -24.0810366320, -2.3011998397, 1.5231275E-04,
            2.5041111E-07, -1.1863391E-09, 13.8990596, 20.7938672862,
            31085.5085803679, -1.3237624E-04, 1.2789385E-07, -6.1745870E-10,
            13.1940636, 3.3302699264, -9443.3199839914, -5.2312637E-04,
            -6.8728642E-07, 3.2502879E-09, -9.6790568, -4.7542348263,
            -16029.0808942018, -3.0728938E-04, -5.0020584E-07, 2.3182384E-09,
            -9.3658635, 11.2971895604, 24080.9951807398, -3.4654346E-04,
            -1.9636409E-07, 9.1804319E-10, 8.6055318, 5.7289501804,
            -1742.9305145148, -3.6814974E-04, -4.3749170E-07, 2.1183885E-09,
            -8.4530982, 7.5540213938, 16100.0685698171, 1.1921869E-04,
            2.8238458E-07, -1.3407038E-09, 8.0501724, 10.4831850066,
            14286.1503796870, -6.0860358E-05, 6.2714140E-08, -1.9984990E-10,
            -7.6301553, 4.6679834628, 17285.6848046987, 3.0196162E-04,
            5.0143862E-07, -2.4271179E-09, -7.4474952, -0.0862513635,
            1256.6039104970, -5.3277630E-06, 1.2327842E-09, -1.0887946E-10,
            7.3712011, 8.1276304344, 5957.4589549619, -2.1317311E-04,
            -1.8769697E-07, 9.8648918E-10, 7.0629900, 0.9591375719,
            33.7570471374, -3.0829302E-05, -3.6967043E-08, 1.7385419E-10,
            -6.3831491, 9.4966777258, 7004.5133996281, 2.1416722E-04,
            3.2425793E-07, -1.5355019E-09, -5.7416071, 13.6527441326,
            32409.6866054649, -1.9423071E-04, 5.4047029E-08, -2.6829589E-10,
            4.3740095, 18.4814383957, 22128.5152003943, -2.8202511E-04,
            -1.2313366E-07, 6.2332010E-10, -3.9976134, 7.9669196340,
            33524.3151647312, 1.7658291E-04, 4.9092233E-07, -2.3322447E-09,
            -3.2096876, 13.2398458924, 14985.4400105508, -2.5159493E-04,
            -1.5449073E-07, 7.2324505E-10, -2.9145404, 12.7093625336,
            24499.7476701576, 8.3460748E-05, 3.1497443E-07, -1.5495082E-09,
            2.7318890, 16.1258838235, 13799.8237756692, -4.3433786E-04,
            -3.7354477E-07, 1.8096592E-09, -2.5679459, -2.4418059357,
            -7072.0875142282, -1.5764051E-04, -2.4917833E-07, 1.0774596E-09,
            -2.5211990, 7.9551277074, 8470.6667759558, -2.2382863E-04,
            -1.8523141E-07, 7.6873027E-10, 2.4888871, 5.6426988169,
            -486.3266040178, -3.7347750E-04, -4.3625891E-07, 2.0095091E-09,
            2.1460741, 7.1842488353, -1952.4799803455, 6.4518350E-05,
            7.3230428E-08, -2.9472308E-10, 1.9777270, 23.1494218585,
            39414.2000050930, 1.9936508E-05, 3.7830496E-07, -1.8037978E-09,
            1.9336825, 9.4222182890, 33314.7656989005, 6.0925100E-04,
            1.0016445E-06, -4.7453563E-09, 1.8707647, 20.8369929680,
            30457.2066251194, -1.2971236E-04, 1.2727746E-07, -5.6301898E-10,
            -1.7529659, 0.4873576771, -8886.0057043583, -3.3771956E-04,
            -4.6884877E-07, 2.2183135E-09, -1.4371624, 7.0979974718,
            -695.8760698485, 5.9190587E-05, 7.4463212E-08, -4.0360254E-10,
            -1.3725701, 1.4552986550, -209.5494658307, 4.3266809E-04,
            5.1072212E-07, -2.4131116E-09, 1.2618162, 7.5108957121,
            16728.3705250656, 1.1655481E-04, 2.8300097E-07, -1.3951435E-09};
    private static final double M11[] = {1.6768000, -0.0431256817,
            628.3019552485, -2.6638815E-06, 6.1639211E-10, -5.4439728E-11,
            0.5164200, 11.2260974062, 6585.7609102104, -2.1583699E-04,
            -1.8708058E-07, 9.3204945E-10, 0.4138300, 13.5816519784,
            14914.4523349355, -6.3524240E-05, 6.3330532E-08, -2.5428962E-10,
            0.3711500, 5.5402729076, 7700.3894694766, 1.5497663E-04,
            2.4979472E-07, -1.1318993E-09, 0.2756000, 2.3124288905,
            8956.9933799736, 1.4964887E-04, 2.5102751E-07, -1.2407788E-09,
            0.2459863, -25.6198212459, -2.3011998397, 1.5231275E-04,
            2.5041111E-07, -1.1863391E-09, 0.0711800, 7.9982533891,
            7842.3648207073, -2.2116475E-04, -1.8584780E-07, 8.2317000E-10,
            0.0612800, 10.3538079614, 16171.0562454324, -6.8852003E-05,
            6.4563317E-08, -3.6316908E-10};
    private static final double M12[] = {0.0048700, -0.0431256817,
            628.3019552485, -2.6638815E-06, 6.1639211E-10, -5.4439728E-11,
            0.0022800, -27.1705318325, -2.3011998397, 1.5231275E-04,
            2.5041111E-07, -1.1863391E-09, 0.0015000, 11.2260974062,
            6585.7609102104, -2.1583699E-04, -1.8708058E-07, 9.3204945E-10};
    private static final double M20[] = {18461.2400600, 1.6279052448,
            8433.4661576405, -6.4021295E-05, -4.9499477E-09, 2.0216731E-11,
            1010.1671484, 3.9834598170, 16762.1575823656, 8.8291456E-05,
            2.4546117E-07, -1.1661223E-09, 999.6936555, 0.7276493275,
            -104.7747329154, 2.1633405E-04, 2.5536106E-07, -1.2065558E-09,
            623.6524746, 8.7690283983, 7109.2881325435, -2.1668263E-06,
            6.8896872E-08, -3.2894608E-10, 199.4837596, 9.6692843156,
            15647.5290230993, -2.8252217E-04, -1.9141414E-07, 8.9782646E-10,
            166.5741153, 6.4134738261, -1219.4032921817, -1.5447958E-04,
            -1.8151424E-07, 8.5739300E-10, 117.2606951, 12.0248388879,
            23976.2204478244, -1.3020942E-04, 5.8996977E-08, -2.8851262E-10,
            61.9119504, 6.3390143893, 25090.8490070907, 2.4060421E-04,
            4.9587228E-07, -2.3524614E-09, 33.3572027, 11.1245829706,
            15437.9795572686, 1.5014592E-04, 3.1930799E-07, -1.5152852E-09,
            31.7596709, 3.0832038997, 8223.9166918098, 3.6864680E-04,
            5.0577218E-07, -2.3928949E-09, 29.5766003, 8.8121540801,
            6480.9861772950, 4.9705523E-07, 6.8280480E-08, -2.7450635E-10,
            15.5662654, 4.0579192538, -9548.0947169068, -3.0679233E-04,
            -4.3192536E-07, 2.0437321E-09, 15.1215543, 14.3803934601,
            32304.9118725496, 2.2103334E-05, 3.0940809E-07, -1.4748517E-09,
            -12.0941511, 8.7259027166, 7737.5900877920, -4.8307078E-06,
            6.9513264E-08, -3.8338581E-10, 8.8681426, 9.7124099974,
            15019.2270678508, -2.7985829E-04, -1.9203053E-07, 9.5226618E-10,
            8.0450400, 0.6687636586, 8399.7091105030, -3.3191993E-05,
            3.2017096E-08, -1.5363746E-10, 7.9585542, 12.0679645696,
            23347.9184925760, -1.2754553E-04, 5.8380585E-08, -2.3407289E-10,
            7.4345550, 6.4565995078, -1847.7052474301, -1.5181570E-04,
            -1.8213063E-07, 9.1183272E-10, -6.7314363, -4.0265854988,
            -16133.8556271171, -9.0955337E-05, -2.4484477E-07, 1.1116826E-09,
            6.5795750, 16.8104074692, 14323.3509980023, -2.2066770E-04,
            -1.1756732E-07, 5.4866364E-10, -6.4600721, 1.5847795630,
            9061.7681128890, -6.6685176E-05, -4.3335556E-09, -3.4222998E-11,
            -6.2964773, 4.8837157343, 25300.3984729215, -1.9206388E-04,
            -1.4849843E-08, 6.0650192E-11, -5.6323538, -0.7707750092,
            733.0766881638, -2.1899793E-04, -2.5474467E-07, 1.1521161E-09,
            -5.3683961, 6.8263720663, 16204.8433027325, -9.7115356E-05,
            2.7023515E-08, -1.3414795E-10, -5.3112784, 3.9403341353,
            17390.4595376141, 8.5627574E-05, 2.4607756E-07, -1.2205621E-09,
            -5.0759179, 0.6845236457, 523.5272223331, 2.1367016E-04,
            2.5597745E-07, -1.2609955E-09, -4.8396143, -1.6710309265,
            -7805.1642023920, 6.1357413E-05, 5.5663398E-09, -7.4656459E-11,
            -4.8057401, 3.5705615768, -662.0890125485, 3.0927234E-05,
            3.6923410E-08, -1.7458141E-10, 3.9840545, 8.6945689615,
            33419.5404318159, 3.9291696E-04, 7.4628340E-07, -3.5388005E-09,
            3.6744619, 19.1659620415, 22652.0424227274, -6.8354947E-05,
            1.3284380E-07, -6.3767543E-10, 2.9984815, 20.0662179587,
            31190.2833132833, -3.4871029E-04, -1.2746721E-07, 5.8909710E-10,
            2.7986413, -2.5281611620, -16971.7070481963, 3.4437664E-04,
            2.6526096E-07, -1.2469893E-09, 2.4138774, 17.7106633865,
            22861.5918885581, -5.0102304E-04, -3.7787833E-07, 1.7754362E-09,
            2.1863132, 5.5132179088, -9757.6441827375, 1.2587576E-04,
            7.8796768E-08, -3.6937954E-10, 2.1461692, 13.4801375428,
            23766.6709819937, 3.0245868E-04, 5.6971910E-07, -2.7016242E-09,
            1.7659832, 11.1677086523, 14809.6776020201, 1.5280981E-04,
            3.1869159E-07, -1.4608454E-09, -1.6244212, 7.3137297434,
            7318.8375983742, -4.3483492E-04, -4.4182525E-07, 2.0841655E-09,
            1.5813036, 5.4387584720, 16552.6081165349, 5.2095955E-04,
            7.5618329E-07, -3.5792340E-09, 1.5197528, 16.7359480324,
            40633.6032972747, 1.7441609E-04, 5.5981921E-07, -2.6611908E-09,
            1.5156341, 1.7023646816, -17876.7861416319, -4.5910508E-04,
            -6.8233647E-07, 3.2300712E-09, 1.5102092, 5.4977296450,
            8399.6847301375, -3.3094061E-05, 3.1973462E-08, -1.5436468E-10,
            -1.3178223, 9.6261586339, 16275.8309783478, -2.8518605E-04,
            -1.9079775E-07, 8.4338673E-10, -1.2642739, 11.9817132061,
            24604.5224030729, -1.3287330E-04, 5.9613369E-08, -3.4295235E-10,
            1.1918723, 22.4217725310, 39518.9747380084, -1.9639754E-04,
            1.2294390E-07, -5.9724197E-10, 1.1346110, 14.4235191419,
            31676.6099173011, 2.4767216E-05, 3.0879170E-07, -1.4204120E-09,
            1.0857810, 8.8552797618, 5852.6842220465, 3.1609367E-06,
            6.7664088E-08, -2.2006663E-10, -1.0193852, 7.2392703065,
            33629.0898976466, -3.9751134E-05, 2.3556127E-07, -1.1256889E-09,
            -0.8227141, 11.0814572888, 16066.2815125171, 1.4748204E-04,
            3.1992438E-07, -1.5697249E-09, 0.8042238, 3.5274358950,
            -33.7870573000, 2.8263353E-05, 3.7539802E-08, -2.2902113E-10,
            0.8025939, 6.7832463846, 16833.1452579809, -9.9779237E-05,
            2.7639907E-08, -1.8858767E-10, -0.7931866, -6.3821400710,
            -24462.5470518423, -2.4326809E-04, -4.9525589E-07, 2.2980217E-09,
            -0.7910153, 6.3703481443, -591.1013369332, -1.5714346E-04,
            -1.8089785E-07, 8.0295327E-10, -0.6674056, 9.1819266386,
            24533.5347274576, 5.5197395E-05, 2.7743463E-07, -1.3204870E-09,
            0.6502226, 4.1010449356, -10176.3966721553, -3.0412845E-04,
            -4.3254175E-07, 2.0981718E-09, -0.6388131, 6.2958887075,
            25719.1509623392, 2.3794032E-04, 4.9648867E-07, -2.4069012E-09};
    private static final double M21[] = {0.0743000, 11.9537467337,
            6480.9861772950, 4.9705523E-07, 6.8280480E-08, -2.7450635E-10,
            0.0304300, 8.7259027166, 7737.5900877920, -4.8307078E-06,
            6.9513264E-08, -3.8338581E-10, 0.0222900, 12.8540026510,
            15019.2270678508, -2.7985829E-04, -1.9203053E-07, 9.5226618E-10,
            0.0199900, 15.2095572232, 23347.9184925760, -1.2754553E-04,
            5.8380585E-08, -2.3407289E-10, 0.0186900, 9.5981921614,
            -1847.7052474301, -1.5181570E-04, -1.8213063E-07, 9.1183272E-10,
            0.0169600, 7.1681781524, 16133.8556271171, 9.0955337E-05,
            2.4484477E-07, -1.1116826E-09, 0.0162300, 1.5847795630,
            9061.7681128890, -6.6685176E-05, -4.3335556E-09, -3.4222998E-11,
            0.0141900, -0.7707750092, 733.0766881638, -2.1899793E-04,
            -2.5474467E-07, 1.1521161E-09};
    private static final double M30[] = {385000.5290396, 1.5707963268,
            0.0000000000, 0.0000000E+00, 0.0000000E+00, 0.0000000E+00,
            -20905.3551378, 3.9263508990, 8328.6914247251, 1.5231275E-04,
            2.5041111E-07, -1.1863391E-09, -3699.1109330, 9.6121753977,
            7214.0628654588, -2.1850087E-04, -1.8646419E-07, 8.7760973E-10,
            -2955.9675626, 11.9677299699, 15542.7542901840, -6.6188121E-05,
            6.3946925E-08, -3.0872935E-10, -569.9251264, 6.2819054713,
            16657.3828494503, 3.0462550E-04, 5.0082223E-07, -2.3726782E-09,
            246.1584797, 7.2566208254, -1114.6285592663, -3.7081362E-04,
            -4.3687530E-07, 2.0639488E-09, -204.5861179, 12.0108556517,
            14914.4523349355, -6.3524240E-05, 6.3330532E-08, -2.5428962E-10,
            -170.7330791, 14.3232845422, 23871.4457149091, 8.6124629E-05,
            3.1435804E-07, -1.4950684E-09, -152.1378118, 9.6553010794,
            6585.7609102104, -2.1583699E-04, -1.8708058E-07, 9.3204945E-10,
            -129.6202242, -0.8278839272, -7700.3894694766, -1.5497663E-04,
            -2.4979472E-07, 1.1318993E-09, 108.7427014, 6.7692631483,
            7771.3771450920, -3.3094061E-05, 3.1973462E-08, -1.5436468E-10,
            104.7552944, 3.8832252173, 8956.9933799736, 1.4964887E-04,
            2.5102751E-07, -1.2407788E-09, 79.6605685, 0.6705404095,
            -8538.2408905558, 2.8035534E-04, 2.6031101E-07, -1.2267725E-09,
            48.8883284, 1.5276706450, 628.3019552485, -2.6638815E-06,
            6.1639211E-10, -5.4439728E-11, -34.7825237, 20.0091090408,
            22756.8171556428, -2.8468899E-04, -1.2251727E-07, 5.6888037E-10,
            30.8238599, 11.9246042882, 16171.0562454324, -6.8852003E-05,
            6.4563317E-08, -3.6316908E-10, 24.2084985, 9.5690497159,
            7842.3648207073, -2.2116475E-04, -1.8584780E-07, 8.2317000E-10,
            -23.2104305, 8.6374600436, 24986.0742741754, 4.5693825E-04,
            7.5123334E-07, -3.5590172E-09, -21.6363439, 17.6535544685,
            14428.1257309177, -4.3700174E-04, -3.7292838E-07, 1.7552195E-09,
            -16.6747239, 6.7261374666, 8399.6791003405, -3.5757942E-05,
            3.2589854E-08, -2.0880440E-10, 14.4026890, 4.9010662531,
            -9443.3199839914, -5.2312637E-04, -6.8728642E-07, 3.2502879E-09,
            -12.8314035, 14.3664102239, 23243.1437596606, 8.8788511E-05,
            3.1374165E-07, -1.4406287E-09, -11.6499478, 22.3646636130,
            31085.5085803679, -1.3237624E-04, 1.2789385E-07, -6.1745870E-10,
            -10.4447578, 16.6788391144, 32200.1371396342, 2.3843738E-04,
            5.6476915E-07, -2.6814075E-09, 10.3211071, 8.7119194804,
            -1324.1780250970, 6.1854469E-05, 7.3846820E-08, -3.4916281E-10,
            10.0562033, 7.2997465071, -1742.9305145148, -3.6814974E-04,
            -4.3749170E-07, 2.1183885E-09, -9.8844667, 12.0539813334,
            14286.1503796870, -6.0860358E-05, 6.2714140E-08, -1.9984990E-10,
            8.7515625, 6.3563649081, -9652.8694498221, -9.0458282E-05,
            -1.7656429E-07, 8.3717626E-10, -8.3791067, 4.4137085761,
            -557.3142796331, -1.8540681E-04, -2.1843765E-07, 1.0319744E-09,
            -7.0026961, -3.1834384995, -16029.0808942018, -3.0728938E-04,
            -5.0020584E-07, 2.3182384E-09, 6.3220032, 9.1248177206,
            16100.0685698171, 1.1921869E-04, 2.8238458E-07, -1.3407038E-09,
            5.7508579, 6.2387797896, 17285.6848046987, 3.0196162E-04,
            5.0143862E-07, -2.4271179E-09, -4.9501349, 9.6984267611,
            5957.4589549619, -2.1317311E-04, -1.8769697E-07, 9.8648918E-10,
            -4.4211770, 3.0260949818, -209.5494658307, 4.3266809E-04,
            5.1072212E-07, -2.4131116E-09, 4.1311145, 11.0674740526,
            7004.5133996281, 2.1416722E-04, 3.2425793E-07, -1.5355019E-09,
            -3.9579827, 20.0522347225, 22128.5152003943, -2.8202511E-04,
            -1.2313366E-07, 6.2332010E-10, 3.2582371, 14.8106422192,
            14985.4400105508, -2.5159493E-04, -1.5449073E-07, 7.2324505E-10,
            -3.1483020, 4.8266068163, 16866.9323152810, -1.2804259E-04,
            -9.8998954E-09, 4.0433461E-11, 2.6164092, 14.2801588604,
            24499.7476701576, 8.3460748E-05, 3.1497443E-07, -1.5495082E-09,
            2.3536310, 9.5259240342, 8470.6667759558, -2.2382863E-04,
            -1.8523141E-07, 7.6873027E-10, -2.1171283, -0.8710096090,
            -7072.0875142282, -1.5764051E-04, -2.4917833E-07, 1.0774596E-09,
            -1.8970368, 17.6966801503, 13799.8237756692, -4.3433786E-04,
            -3.7354477E-07, 1.8096592E-09, -1.7385258, 2.0581540038,
            -8886.0057043583, -3.3771956E-04, -4.6884877E-07, 2.2183135E-09,
            -1.5713944, 22.4077892948, 30457.2066251194, -1.2971236E-04,
            1.2727746E-07, -5.6301898E-10, -1.4225541, 24.7202181853,
            39414.2000050930, 1.9936508E-05, 3.7830496E-07, -1.8037978E-09,
            -1.4189284, 17.1661967915, 23314.1314352759, -9.9282182E-05,
            9.5920387E-08, -4.6309403E-10, 1.1655364, 3.8400995356,
            9585.2953352221, 1.4698499E-04, 2.5164390E-07, -1.2952185E-09,
            -1.1169371, 10.9930146158, 33314.7656989005, 6.0925100E-04,
            1.0016445E-06, -4.7453563E-09, 1.0656723, 1.4845449633,
            1256.6039104970, -5.3277630E-06, 1.2327842E-09, -1.0887946E-10,
            1.0586190, 11.9220903668, 8364.7398411275, -2.1850087E-04,
            -1.8646419E-07, 8.7760973E-10, -0.9333176, 9.0816920389,
            16728.3705250656, 1.1655481E-04, 2.8300097E-07, -1.3951435E-09,
            0.8624328, 12.4550876470, 6656.7485858257, -4.0390768E-04,
            -4.0490184E-07, 1.9095841E-09, 0.8512404, 4.3705828944,
            70.9876756153, -1.8807069E-04, -2.1782126E-07, 9.7753467E-10,
            -0.8488018, 16.7219647962, 31571.8351843857, 2.4110126E-04,
            5.6415276E-07, -2.6269678E-09, -0.7956264, 3.5134526588,
            -9095.5551701890, 9.4948529E-05, 4.1873358E-08, -1.9479814E-10};
    private static final double M31[] = {0.5139500, 12.0108556517,
            14914.4523349355, -6.3524240E-05, 6.3330532E-08, -2.5428962E-10,
            0.3824500, 9.6553010794, 6585.7609102104, -2.1583699E-04,
            -1.8708058E-07, 9.3204945E-10, 0.3265400, 3.9694765808,
            7700.3894694766, 1.5497663E-04, 2.4979472E-07, -1.1318993E-09,
            0.2639600, 0.7416325637, 8956.9933799736, 1.4964887E-04,
            2.5102751E-07, -1.2407788E-09, 0.1230200, -1.6139220085,
            628.3019552485, -2.6638815E-06, 6.1639211E-10, -5.4439728E-11,
            0.0775400, 8.7830116346, 16171.0562454324, -6.8852003E-05,
            6.4563317E-08, -3.6316908E-10, 0.0606800, 6.4274570623,
            7842.3648207073, -2.2116475E-04, -1.8584780E-07, 8.2317000E-10,
            0.0497000, 12.0539813334, 14286.1503796870, -6.0860358E-05,
            6.2714140E-08, -1.9984990E-10};
    private static final double M1n[] = {3.81034392032, 8.39968473021E+03,
            -3.31919929753E-05, // 月球平黄经系数
            3.20170955005E-08, -1.53637455544E-10};

    // ==================日位置计算===================
    private double EnnT = 0; // 调用Enn前先设置EnnT时间变量

    // 计算E10,E11,E20等,即:某一组周期项或泊松项算出,计算前先设置EnnT时间
    public double Enn(double[] F) {
        double v = 0;
        for (int i = 0; i < F.length; i += 3)
            v += F[i] * Math.cos(F[i + 1] + EnnT * F[i + 2]);
        return v;
    }

    // 返回地球位置,日心Date黄道分点坐标
    public double[] earCal(double jd) {
        EnnT = jd / 365250;
        double llr[] = new double[3];
        double t1 = EnnT, t2 = t1 * t1, t3 = t2 * t1, t4 = t3 * t1, t5 = t4
                * t1;
        llr[0] = Enn(E10) + Enn(E11) * t1 + Enn(E12) * t2 + Enn(E13) * t3
                + Enn(E14) * t4 + Enn(E15) * t5;
        llr[1] = Enn(E20) + Enn(E21) * t1;
        llr[2] = Enn(E30) + Enn(E31) * t1 + Enn(E32) * t2 + Enn(E33) * t3;
        llr[0] = rad2mrad(llr[0]);
        return llr;
    }

    // 传回jd时刻太阳的地心视黄经及黄纬
    public double[] sunCal2(double jd) {
        double[] sun = earCal(jd);
        sun[0] += Math.PI;
        sun[1] = -sun[1]; // 计算太阳真位置
        ZD d = nutation(jd);
        sun[0] = rad2mrad(sun[0] + d.Lon); // 补章动
        addGxc(jd, sun); // 补周年黄经光行差
        return sun; // 返回太阳视位置
    }

    // ==================月位置计算===================
    private double MnnT = 0; // 调用Mnn前先设置MnnT时间变量

    // 计算M10,M11,M20等,计算前先设置MnnT时间
    public double Mnn(double[] F) {
        double v = 0, t1 = MnnT, t2 = t1 * t1, t3 = t2 * t1, t4 = t3 * t1;
        for (int i = 0; i < F.length; i += 6)
            v += F[i]
                    * Math.sin(F[i + 1] + t1 * F[i + 2] + t2 * F[i + 3] + t3
                    * F[i + 4] + t4 * F[i + 5]);
        return v;
    }

    // 返回月球位置,返回地心Date黄道坐标
    public double[] moonCal(double jd) {
        MnnT = jd / 36525;
        double t1 = MnnT, t2 = t1 * t1, t3 = t2 * t1, t4 = t3 * t1;
        double[] llr = new double[3];
        llr[0] = (Mnn(M10) + Mnn(M11) * t1 + Mnn(M12) * t2) / rad;
        llr[1] = (Mnn(M20) + Mnn(M21) * t1) / rad;
        llr[2] = (Mnn(M30) + Mnn(M31) * t1) * 0.999999949827;
        llr[0] = llr[0] + M1n[0] + M1n[1] * t1 + M1n[2] * t2 + M1n[3] * t3
                + M1n[4] * t4;
        llr[0] = rad2mrad(llr[0]); // 地心Date黄道原点坐标(不含岁差)
        addPrece(jd, llr); // 补岁差
        return llr;
    }

    // 传回月球的地心视黄经及视黄纬
    public double[] moonCal2(double jd) {
        double[] moon = moonCal(jd);
        ZD d = nutation(jd);
        moon[0] = rad2mrad(moon[0] + d.Lon); // 补章动
        return moon;
    }

    // 传回月球的地心视赤经及视赤纬
    public double[] moonCal3(double jd) {
        double[] moon = moonCal(jd);
        HCconv(moon, hcjj1(jd));
        nutationRaDec(jd, moon); // 补赤经及赤纬章动
        // 如果黄赤转换前补了黄经章动及交章动,就不能再补赤经赤纬章动
        return moon;
    }

    // ==================地心坐标中的日月位置计算===================
    public double jiaoCai(int lx, double t, double jiao) {
        // lx=1时计算t时刻日月角距与jiao的差, lx=0计算t时刻太阳黄经与jiao的差
        double[] sun = earCal(t); // 计算太阳真位置(先算出日心坐标中地球的位置)
        sun[0] += Math.PI;
        sun[1] = -sun[1]; // 转为地心坐标
        addGxc(t, sun); // 补周年光行差
        if (lx == 0) {
            ZD d = nutation(t);
            sun[0] += d.Lon; // 补黄经章动
            return rad2mrad(jiao - sun[0]);
        }
        double[] moon = moonCal(t); // 日月角差与章动无关
        return rad2mrad(jiao - (moon[0] - sun[0]));
    }

    // ==================已知位置反求时间===================
    public double jiaoCal(double t1, double jiao, int lx) {
        // t1是J2000起算儒略日数
        // 已知角度(jiao)求时间(t)
        // lx=0是太阳黄经达某角度的时刻计算(用于节气计算)
        // lx=1是日月角距达某角度的时刻计算(用于定朔望等)
        // 传入的t1是指定角度对应真时刻t的前一些天
        // 对于节气计算,应满足t在t1到t1+360天之间,对于Y年第n个节气(n=0是春分),t1可取值Y*365.2422+n*15.2
        // 对于朔望计算,应满足t在t1到t1+25天之间,在此范围之外,求右边的根
        double t2 = t1, t = 0, v;
        if (lx == 0)
            t2 += 360; // 在t1到t2范围内求解(范气360天范围),结果置于t
        else
            t2 += 25;
        jiao *= Math.PI / 180; // 待搜索目标角
        // 利用截弦法计算
        double v1 = jiaoCai(lx, t1, jiao); // v1,v2为t1,t2时对应的黄经
        double v2 = jiaoCai(lx, t2, jiao);
        if (v1 < v2)
            v2 -= 2 * Math.PI; // 减2pi作用是将周期性角度转为连续角度
        double k = 1, k2; // k是截弦的斜率
        for (int i = 0; i < 10; i++) { // 快速截弦求根,通常截弦三四次就已达所需精度
            k2 = (v2 - v1) / (t2 - t1); // 算出斜率
            if (Math.abs(k2) > 1e-15)
                k = k2; // 差商可能为零,应排除
            t = t1 - v1 / k;
            v = jiaoCai(lx, t, jiao);// 直线逼近法求根(直线方程的根)
            if (v > 1)
                v -= 2 * Math.PI; // 一次逼近后,v1就已接近0,如果很大,则应减1周
            if (Math.abs(v) < 1e-8)
                break; // 已达精度
            t1 = t2;
            v1 = v2;
            t2 = t;
            v2 = v; // 下一次截弦
        }
        return t;
    }

    // ==================节气计算===================
    public static final String jqB[] = { // 节气表
            "春分", "清明", "谷雨", "立夏", "小满", "芒种", "夏至", "小暑", "大暑", "立秋", "处暑", "白露",
            "秋分", "寒露", "霜降", "立冬", "小雪", "大雪", "冬至", "小寒", "大寒", "立春", "雨水",
            "惊蛰"};

    public void JQtest(int y) { // 节气使计算范例,y是年分,这是个测试函数
        double jd = 365.2422 * (y - 2000), q;
        String s1, s2;
        for (int i = 0; i < 24; i++) {
            q = jiaoCal(jd + i * 15.2, i * 15, 0);
            q = q + J2000 + (double) 8 / 24; // 计算第i个节气(i=0是春分),结果转为北京时
            setFromJD(q, true);
            s1 = toStr(); // 将儒略日转成世界时
            setFromJD(q, false);
            s2 = toStr(); // 将儒略日转成日期格式(输出日期形式的力学时)
            System.out.println(jqB[i] + " : " + s1 + " " + s2); // 显示
        }
    }

    // =================定朔弦望计算========================
    public void dingSuo(int y, double arc) { // 这是个测试函数
        double jd = 365.2422 * (y - 2000), q;
        String s1, s2;
        System.out.println("月份:世界时  原子时");
        for (int i = 0; i < 12; i++) {
            q = jiaoCal(jd + 29.5 * i, arc, 1) + J2000 + 8 / 24; // 计算第i个节气(i=0是春风),结果转为北京时
            setFromJD(q, true);
            s1 = toStr(); // 将儒略日转成世界时
            setFromJD(q, false);
            s2 = toStr(); // 将儒略日转成日期格式(输出日期形式的力学时)
            System.out.println((i + 1) + "月 : " + s1 + " " + s2); // 显示
        }
    }

    // =================农历计算========================
    /*****
     * 1.冬至所在的UTC日期保存在A[0],根据"规定1"得知在A[0]之前(含A[0])的那个UTC朔日定为年首日期
     * 冬至之后的中气分保存在A[1],A[2],A[3]...A[13],其中A[12]又回到了冬至,共计算13次中气
     * 2.连续计算冬至后14个朔日,即起算时间时A[0]+1 14个朔日编号为0,1...12,保存在C[0],C[1]...C[13]
     * 这14个朔日表示编号为0月,1月,...12月0月的各月终止日期,但要注意实际终止日是新月初一,不属本月
     * 这14个朔日同样表示编号为1月,2月...的开始日期
     * 设某月编号为n,那么开始日期为C[n-1],结束日期为C[n],如果每月都含中气,该月所含的中气为A[n]
     * 注:为了全总计算出13个月的大小月情况,须算出14个朔日。
     * 3.闰年判断:含有13个月的年份是闰年 当第13月(月编号12月)终止日期大于冬至日,
     * 即C[12]〉A[12], 那么该月是新年,本年没月12月,本年共12个月
     * 当第13月(月编号12月)终止日期小等于冬至日,即C[12]≤A[12],那么该月是本年的有效月份,本年共13个月
     * 4.闰年中处理闰月:13个月中至少1个月份无中气,首个无中气的月置闰,在n=1...12月中找到闰月,即C[n]≤A[n]
     * 从农历年首的定义知道,0月一定含有中气冬至,所以不可能是闰月。 首月有时很贪心,除冬至外还可能再吃掉本年或前年的另一个中气
     * 定出闰月后,该月及以后的月编号减1
     * 5.以上所述的月编号不是日常生活中说的"正月","二月"等月名称:
     * 如果"建子",0月为首月,如果"建寅",2月的月名"正月",3月是"二月",其余类推
     *****/
    private static final String yueMing[] = {"正", "二", "三", "四", "五", "六",
            "七", "八", "九", "十", "十一", "十二"};

    public void paiYue(int y) { // 农历排月序计算,可定出农历
        double zq[] = new double[20];
        double jq[] = new double[20];
        double hs[] = new double[20];

        // 从冬至开始,连续计算14个中气时刻
        int i;
        double t1 = 365.2422 * (y - 2000) - 50; // 农历年首始于前一年的冬至,为了节气中气一起算,取前年大雪之前
        for (i = 0; i < 14; i++) { // 计算节气(从冬至开始),注意:返回的是力学时
            zq[i] = jiaoCal(t1 + i * 30.4, i * 30 - 90, 0); // 中气计算,冬至的太阳黄经是270度(或-90度)
            jq[i] = jiaoCal(t1 + i * 30.4, i * 30 - 105, 0); // 顺便计算节气,它不是农历定朔计算所必需的
        }
        // 在冬至过后,连续计算14个日月合朔时刻
        double dongZhiJia1 = zq[0] + 1 - Dint_dec(zq[0], 8, false); // 冬至过后的第一天0点的儒略日数
        hs[0] = jiaoCal(dongZhiJia1, 0, 1); // 首月结束的日月合朔时刻
        for (i = 1; i < 14; i++)
            hs[i] = jiaoCal(hs[i - 1] + 25, 0, 1);
        // 算出中气及合朔时刻的日数(不含小数的日数计数,以便计算日期之间的差值)
        double A[] = new double[20];
        double B[] = new double[20];
        double C[] = new double[20];
        for (i = 0; i < 14; i++) { // 取当地UTC日数的整数部分
            A[i] = Dint_dec(zq[i], 8, true);
            B[i] = Dint_dec(jq[i], 8, true);
            C[i] = Dint_dec(hs[i], 8, true);
        }
        // 闰月及大小月分析
        int tot = 12, nun = -1;
        int yn[] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 0, 0}; // 月编号
        if (C[12] <= A[12]) { // 闰月分析
            yn[12] = 12;
            tot = 13; // 编号为12的月是本年的有效月份,本年总月数13个
            for (i = 1; i < 13; i++)
                if (C[i] <= A[i])
                    break;
            for (nun = i - 1; i < 13; i++)
                yn[i - 1]--; // 注意yn中不含农历首月(所以取i-1),在公历中农历首月总是去年的所以不多做计算
        }
        String syn[] = new String[20];
        for (i = 0; i < tot; i++) { // 转为建寅月名,并做大小月分析
            syn[i] = yueMing[(yn[i] + 10) % 12]; // 转建寅月名
            if (i == nun)
                syn[i] += "闰";
            else
                syn[i] += "月"; // 标记是否闰月
            if (C[i + 1] - C[i] > 29)
                syn[i] += "大";
            else
                syn[i] += "小"; // 标记大小月
        }
        // 显示
        String out = "节气    手表时            中气    手表时            农历月   朔的手表时\r\n";
        for (i = 0; i < tot; i++) {
            int zm = (i * 2 + 18) % 24;
            int jm = (i * 2 + 17) % 24; // 中气名节气名
            setFromJD(jq[i] + J2000 + (double) 8 / 24, true);
            out += jqB[jm] + ":" + toStr() + " "; // 显示节气
            setFromJD(zq[i] + J2000 + (double) 8 / 24, true);
            out += jqB[zm] + ":" + toStr() + " "; // 显示中气
            setFromJD(hs[i] + J2000 + (double) 8 / 24, true);
            out += syn[i] + ":" + toStr() + "\r\n"; // 显示日月合朔
        }
        System.out.println(out);
    }

    private static String[] sSolarTerms = {"小寒", "大寒",
            "立春", "雨水", "惊蛰", "春分", "清明", "谷雨",
            "立夏", "小满", "芒种", "夏至", "小暑", "大暑",
            "立秋", "处暑", "白露", "秋分", "寒露", "霜降",
            "立冬", "小雪", "大雪", "冬至"};

    public SolarTerm() {
    }

    /**
     * 获取公历年份中二十四节气的具体时间。
     *
     * @param year
     * @return 二十四节气对应的公历日期,每年以小寒开始
     */
    public Calendar[] getSolarTermCalendars(int year) {
        Calendar[] solarTermCalendars = new Calendar[24];
        double jd = 365.2422 * (year - 2000), q;
        int j;
        for (int i = 0; i < 24; i++) {
            j = (i - 5);
            q = jiaoCal(jd + j * 15.2, j * 15, 0);
            q = q + J2000 + (double) 8 / 24; // 计算第i个节气(i=0是春分),结果转为北京时
            setFromJD(q, true);
            solarTermCalendars[i] = toCalendar();
        }
        return solarTermCalendars;
    }

    // 日期转换为Calendar
    private Calendar toCalendar() {
        Calendar cal = Calendar.getInstance();
        double h = this.h, m = this.m, s = Math.floor(this.s + .5);
        if (s >= 60) {
            s -= 60;
            m++;
        }
        if (m >= 60) {
            m -= 60;
            h++;
        }
        cal.set((int) Y, (int) M, (int) D, (int) h, (int) m, (int) s);

        return cal;
    }

    public String[] getSolarDays(int year) {
        Calendar[] calArray = (new SolarTerm()).getSolarTermCalendars(2015);
        String[] solarDays = new String[calArray.length];
        for (int i = 0; i < calArray.length; i++) {
            Calendar cal = calArray[i];
            int month = cal.get(Calendar.MONTH);
            if (month == 0) {
                month = 12;
            }
            int day = cal.get(Calendar.DAY_OF_MONTH);
            solarDays[i] = month + "" + day + " " + sSolarTerms[i];
            solarDays[i] = String.format("%02d%02d %s", month, day, sSolarTerms[i]);
        }
        return solarDays;
    }

    public static void main(String[] arg) {
        String[] termDays = (new SolarTerm()).getSolarDays(2015);
        for (int i = 0; i < termDays.length; i++) {
            System.out.println(termDays[i]);
        }
    }

}
  • SpecialCalendar.java逻辑代码如下:
package com.fukaimei.calendar.calendar;

import java.util.Calendar;
import java.util.Date;

import android.util.Log;

public class SpecialCalendar {

    private static final String TAG = "SpecialCalendar";

    // 判断是否为闰年
    public static boolean isLeapYear(int year) {
        if (year % 100 == 0 && year % 400 == 0) {
            return true;
        } else if (year % 100 != 0 && year % 4 == 0) {
            return true;
        }
        return false;
    }

    //得到某月有多少天数
    public static int getDaysOfMonth(boolean isLeapyear, int month) {
        int daysOfMonth = 0;
        switch (month) {
            case 1:
            case 3:
            case 5:
            case 7:
            case 8:
            case 10:
            case 12:
                daysOfMonth = 31;
                break;
            case 4:
            case 6:
            case 9:
            case 11:
                daysOfMonth = 30;
                break;
            case 2:
                if (isLeapyear) {
                    daysOfMonth = 29;
                } else {
                    daysOfMonth = 28;
                }

        }
        return daysOfMonth;
    }

    //指定某年中的某月的第一天是星期几
    public static int getWeekdayOfMonth(int year, int month) {
        int dayOfWeek = 0;
        Calendar cal = Calendar.getInstance();
        cal.set(year, month - 1, 1);
        dayOfWeek = cal.get(Calendar.DAY_OF_WEEK) - 1;
        Log.d(TAG, " ===dayOfWeek===  " + dayOfWeek);
        if (dayOfWeek == 0) {
            dayOfWeek = 7;
        }
        Log.d(TAG, " ===dayOfWeek===  " + dayOfWeek);
        return dayOfWeek;
    }

    public static int getTodayWeek() {
        int week = 0;
        Calendar cal = Calendar.getInstance();
        cal.setTime(new Date());
        week = cal.get(Calendar.WEEK_OF_YEAR);
        return week;
    }

}

发布了72 篇原创文章 · 获赞 154 · 访问量 23万+

猜你喜欢

转载自blog.csdn.net/fukaimei/article/details/78440599