支持0001到9999年。
This commit is contained in:
File diff suppressed because one or more lines are too long
100
src/main/java/com/nlf/calendar/LunarMonth.java
Normal file
100
src/main/java/com/nlf/calendar/LunarMonth.java
Normal file
@@ -0,0 +1,100 @@
|
||||
package com.nlf.calendar;
|
||||
|
||||
import com.nlf.calendar.util.LunarUtil;
|
||||
|
||||
/**
|
||||
* 农历月
|
||||
*
|
||||
* @author 6tail
|
||||
*/
|
||||
public class LunarMonth {
|
||||
|
||||
/**
|
||||
* 农历年
|
||||
*/
|
||||
private int year;
|
||||
|
||||
/**
|
||||
* 农历月:1-12,闰月为负数,如闰2月为-2
|
||||
*/
|
||||
private int month;
|
||||
|
||||
/**
|
||||
* 天数,大月30天,小月29天
|
||||
*/
|
||||
private int dayCount;
|
||||
|
||||
/**
|
||||
* 初一的儒略日
|
||||
*/
|
||||
private double firstJulianDay;
|
||||
|
||||
/**
|
||||
* 初始化
|
||||
* @param lunarYear 农历年
|
||||
* @param lunarMonth 农历月:1-12,闰月为负数,如闰2月为-2
|
||||
* @param dayCount 天数
|
||||
* @param firstJulianDay 初一的儒略日
|
||||
*/
|
||||
public LunarMonth(int lunarYear, int lunarMonth, int dayCount, double firstJulianDay) {
|
||||
this.year = lunarYear;
|
||||
this.month = lunarMonth;
|
||||
this.dayCount = dayCount;
|
||||
this.firstJulianDay = firstJulianDay;
|
||||
}
|
||||
|
||||
/**
|
||||
* 通过农历年月初始化
|
||||
* @param lunarYear 农历年
|
||||
* @param lunarMonth 农历月:1-12,闰月为负数,如闰2月为-2
|
||||
* @return 农历月
|
||||
*/
|
||||
public static LunarMonth fromYm(int lunarYear, int lunarMonth){
|
||||
return LunarYear.fromYear(lunarYear).getMonth(lunarMonth);
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取农历年
|
||||
* @return 农历年
|
||||
*/
|
||||
public int getYear() {
|
||||
return year;
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取农历月
|
||||
* @return 农历月:1-12,闰月为负数,如闰2月为-2
|
||||
*/
|
||||
public int getMonth() {
|
||||
return month;
|
||||
}
|
||||
|
||||
/**
|
||||
* 是否闰月
|
||||
* @return true/false
|
||||
*/
|
||||
public boolean isLeap() {
|
||||
return month < 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取天数
|
||||
* @return 天数
|
||||
*/
|
||||
public int getDayCount() {
|
||||
return dayCount;
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取初一的儒略日
|
||||
* @return 初一的儒略日
|
||||
*/
|
||||
public double getFirstJulianDay() {
|
||||
return firstJulianDay;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return year + "年" + (isLeap() ? "闰" : "") + LunarUtil.MONTH[Math.abs(month)] + "月(" + dayCount + "天)";
|
||||
}
|
||||
}
|
||||
175
src/main/java/com/nlf/calendar/LunarYear.java
Normal file
175
src/main/java/com/nlf/calendar/LunarYear.java
Normal file
@@ -0,0 +1,175 @@
|
||||
package com.nlf.calendar;
|
||||
|
||||
import com.nlf.calendar.util.ShouXingUtil;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* 农历年
|
||||
*
|
||||
* @author 6tail
|
||||
*/
|
||||
public class LunarYear {
|
||||
|
||||
/**
|
||||
* 农历年
|
||||
*/
|
||||
private int year;
|
||||
|
||||
/**
|
||||
* 农历月们
|
||||
*/
|
||||
private List<LunarMonth> months = new ArrayList<LunarMonth>();
|
||||
|
||||
/**
|
||||
* 节气儒略日们
|
||||
*/
|
||||
private List<Double> jieQiJulianDays = new ArrayList<Double>();
|
||||
|
||||
/**
|
||||
* 初始化
|
||||
*
|
||||
* @param lunarYear 农历年
|
||||
*/
|
||||
public LunarYear(int lunarYear) {
|
||||
this.year = lunarYear;
|
||||
compute();
|
||||
}
|
||||
|
||||
/**
|
||||
* 通过农历年初始化
|
||||
*
|
||||
* @param lunarYear 农历年
|
||||
* @return 农历年
|
||||
*/
|
||||
public static LunarYear fromYear(int lunarYear) {
|
||||
return new LunarYear(lunarYear);
|
||||
}
|
||||
|
||||
private void compute() {
|
||||
// 节气(中午12点)
|
||||
double[] jq = new double[25];
|
||||
// 合朔,即每月初一(中午12点)
|
||||
double[] hs = new double[15];
|
||||
// 每月天数
|
||||
int[] dayCounts = new int[hs.length - 1];
|
||||
|
||||
int year = this.year - 2000;
|
||||
// 从上年的大雪到下年的大寒
|
||||
for (int i = 0, j = Lunar.JIE_QI_IN_USE.length; i < j; i++) {
|
||||
// 精确的节气
|
||||
double t = 36525 * ShouXingUtil.saLonT((year + (17 + i) * 15d / 360) * ShouXingUtil.PI_2);
|
||||
t += ShouXingUtil.ONE_THIRD - ShouXingUtil.dtT(t);
|
||||
jieQiJulianDays.add(t + Solar.J2000);
|
||||
// 按中午12点算的节气
|
||||
if (i > 0 && i < 26) {
|
||||
jq[i - 1] = Math.round(t);
|
||||
}
|
||||
}
|
||||
|
||||
// 冬至前的初一
|
||||
double w = ShouXingUtil.calcShuo(jq[0]);
|
||||
if (w > jq[0]) {
|
||||
w -= 29.5306;
|
||||
}
|
||||
// 递推每月初一
|
||||
for (int i = 0, j = hs.length; i < j; i++) {
|
||||
hs[i] = ShouXingUtil.calcShuo(w + 29.5306 * i);
|
||||
}
|
||||
// 每月天数
|
||||
for (int i = 0, j = dayCounts.length; i < j; i++) {
|
||||
dayCounts[i] = (int) (hs[i + 1] - hs[i]);
|
||||
}
|
||||
|
||||
int leap = -1;
|
||||
if (hs[13] <= jq[24]) {
|
||||
int i = 1;
|
||||
while (hs[i + 1] > jq[2 * i] && i < 13) {
|
||||
i++;
|
||||
}
|
||||
leap = i;
|
||||
}
|
||||
|
||||
int y = this.year - 1;
|
||||
int m = 11;
|
||||
for (int i = 0, j = dayCounts.length; i < j; i++) {
|
||||
boolean isLeap = false;
|
||||
if (i == leap) {
|
||||
isLeap = true;
|
||||
m--;
|
||||
}
|
||||
this.months.add(new LunarMonth(y, isLeap ? -m : m, dayCounts[i], hs[i] + Solar.J2000));
|
||||
m++;
|
||||
if (m == 13) {
|
||||
m = 1;
|
||||
y++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取农历年
|
||||
*
|
||||
* @return 农历年
|
||||
*/
|
||||
public int getYear() {
|
||||
return year;
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取农历月们
|
||||
*
|
||||
* @return 农历月们
|
||||
*/
|
||||
public List<LunarMonth> getMonths() {
|
||||
return months;
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取节气儒略日们
|
||||
*
|
||||
* @return 节气儒略日们
|
||||
*/
|
||||
public List<Double> getJieQiJulianDays() {
|
||||
return jieQiJulianDays;
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取农历月
|
||||
*
|
||||
* @param lunarMonth 月,1-12,闰月为负数,如闰2月为-2
|
||||
* @return 农历月
|
||||
*/
|
||||
public LunarMonth getMonth(int lunarMonth) {
|
||||
for (LunarMonth m : months) {
|
||||
if (m.getYear() == year && m.getMonth() == lunarMonth) {
|
||||
return m;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取闰月
|
||||
*
|
||||
* @return 闰月数字,1代表闰1月,0代表无闰月
|
||||
*/
|
||||
public int getLeapMonth() {
|
||||
for (LunarMonth m : months) {
|
||||
if (m.getYear() == year && m.isLeap()) {
|
||||
return Math.abs(m.getMonth());
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return year + "";
|
||||
}
|
||||
|
||||
public String toFullString() {
|
||||
return year + "年";
|
||||
}
|
||||
}
|
||||
@@ -61,9 +61,11 @@ public class Solar{
|
||||
* @param minute 分钟,0到59
|
||||
* @param second 秒钟,0到59
|
||||
*/
|
||||
public Solar(int year,int month,int day,int hour,int minute,int second){
|
||||
@SuppressWarnings("MagicConstant")
|
||||
public Solar(int year, int month, int day, int hour, int minute, int second){
|
||||
calendar = Calendar.getInstance();
|
||||
calendar.set(year,month-1,day,hour,minute,second);
|
||||
calendar.set(Calendar.MILLISECOND,0);
|
||||
this.year = year;
|
||||
this.month = month;
|
||||
this.day = day;
|
||||
@@ -80,6 +82,7 @@ public class Solar{
|
||||
public Solar(Date date){
|
||||
calendar = Calendar.getInstance();
|
||||
calendar.setTime(date);
|
||||
calendar.set(Calendar.MILLISECOND,0);
|
||||
year = calendar.get(Calendar.YEAR);
|
||||
month = calendar.get(Calendar.MONTH)+1;
|
||||
day = calendar.get(Calendar.DATE);
|
||||
@@ -94,6 +97,7 @@ public class Solar{
|
||||
* @param calendar 日历
|
||||
*/
|
||||
public Solar(Calendar calendar){
|
||||
calendar.set(Calendar.MILLISECOND,0);
|
||||
this.calendar = calendar;
|
||||
year = calendar.get(Calendar.YEAR);
|
||||
month = calendar.get(Calendar.MONTH)+1;
|
||||
@@ -107,6 +111,7 @@ public class Solar{
|
||||
* 通过儒略日初始化
|
||||
* @param julianDay 儒略日
|
||||
*/
|
||||
@SuppressWarnings("MagicConstant")
|
||||
public Solar(double julianDay){
|
||||
int d = (int)(julianDay + 0.5);
|
||||
double f = julianDay + 0.5 - d;
|
||||
@@ -142,6 +147,7 @@ public class Solar{
|
||||
|
||||
calendar = Calendar.getInstance();
|
||||
calendar.set(year,month-1,day,hour,minute,second);
|
||||
calendar.set(Calendar.MILLISECOND,0);
|
||||
this.year = year;
|
||||
this.month = month;
|
||||
this.day = day;
|
||||
@@ -208,7 +214,7 @@ public class Solar{
|
||||
}
|
||||
|
||||
/**
|
||||
* 通过八字获取阳历列表(晚子时日柱按当天)
|
||||
* 通过八字获取阳历列表(晚子时日柱按当天,起始年为1900)
|
||||
* @param yearGanZhi 年柱
|
||||
* @param monthGanZhi 月柱
|
||||
* @param dayGanZhi 日柱
|
||||
@@ -220,7 +226,7 @@ public class Solar{
|
||||
}
|
||||
|
||||
/**
|
||||
* 通过八字获取阳历列表
|
||||
* 通过八字获取阳历列表(起始年为1900)
|
||||
* @param yearGanZhi 年柱
|
||||
* @param monthGanZhi 月柱
|
||||
* @param dayGanZhi 日柱
|
||||
@@ -229,6 +235,20 @@ public class Solar{
|
||||
* @return 符合的阳历列表
|
||||
*/
|
||||
public static List<Solar> fromBaZi(String yearGanZhi,String monthGanZhi,String dayGanZhi,String timeGanZhi,int sect){
|
||||
return fromBaZi(yearGanZhi,monthGanZhi,dayGanZhi,timeGanZhi,sect,1900);
|
||||
}
|
||||
|
||||
/**
|
||||
* 通过八字获取阳历列表
|
||||
* @param yearGanZhi 年柱
|
||||
* @param monthGanZhi 月柱
|
||||
* @param dayGanZhi 日柱
|
||||
* @param timeGanZhi 时柱
|
||||
* @param sect 流派,2晚子时日柱按当天,1晚子时日柱按明天
|
||||
* @param baseYear 起始年
|
||||
* @return 符合的阳历列表
|
||||
*/
|
||||
public static List<Solar> fromBaZi(String yearGanZhi,String monthGanZhi,String dayGanZhi,String timeGanZhi,int sect,int baseYear){
|
||||
sect = (1==sect)?1:2;
|
||||
List<Solar> l = new ArrayList<Solar>();
|
||||
Solar today = new Solar();
|
||||
@@ -245,18 +265,15 @@ public class Solar{
|
||||
hour = (i-1)*2;
|
||||
}
|
||||
}
|
||||
while(startYear>=SolarUtil.BASE_YEAR-1){
|
||||
while(startYear>=baseYear){
|
||||
int year = startYear-1;
|
||||
int counter = 0;
|
||||
int month = 12;
|
||||
int day;
|
||||
boolean found = false;
|
||||
while (counter < 15) {
|
||||
if(year>=SolarUtil.BASE_YEAR){
|
||||
if(year>=baseYear){
|
||||
day = 1;
|
||||
if(year==SolarUtil.BASE_YEAR&&month==SolarUtil.BASE_MONTH){
|
||||
day = SolarUtil.BASE_DAY;
|
||||
}
|
||||
Solar solar = new Solar(year, month, day, hour, 0, 0);
|
||||
lunar = solar.getLunar();
|
||||
if(lunar.getYearInGanZhiExact().equals(yearGanZhi) && lunar.getMonthInGanZhiExact().equals(monthGanZhi)){
|
||||
@@ -279,9 +296,6 @@ public class Solar{
|
||||
year--;
|
||||
}
|
||||
day = 1;
|
||||
if(year==SolarUtil.BASE_YEAR&&month==SolarUtil.BASE_MONTH){
|
||||
day = SolarUtil.BASE_DAY;
|
||||
}
|
||||
Solar solar = new Solar(year, month, day, hour, 0, 0);
|
||||
while (counter < 61) {
|
||||
lunar = solar.getLunar();
|
||||
@@ -508,11 +522,11 @@ public class Solar{
|
||||
}
|
||||
|
||||
public String toYmd(){
|
||||
return year+"-"+(month<10?"0":"")+month+"-"+(day<10?"0":"")+day;
|
||||
return String.format("%04d-%02d-%02d", year, month, day);
|
||||
}
|
||||
|
||||
public String toYmdHms(){
|
||||
return toYmd()+" "+(hour<10?"0":"")+hour+":"+(minute<10?"0":"")+minute+":"+(second<10?"0":"")+second;
|
||||
return toYmd()+" "+String.format("%02d:%02d:%02d", hour, minute, second);
|
||||
}
|
||||
|
||||
public String toFullString(){
|
||||
@@ -550,9 +564,17 @@ public class Solar{
|
||||
return next(days,false);
|
||||
}
|
||||
|
||||
/**
|
||||
* 取往后推几天的阳历日期,如果要往前推,则天数用负数
|
||||
* @param days 天数
|
||||
* @param onlyWorkday 是否仅限工作日
|
||||
* @return 阳历日期
|
||||
*/
|
||||
@SuppressWarnings("MagicConstant")
|
||||
public Solar next(int days, boolean onlyWorkday){
|
||||
Calendar c = Calendar.getInstance();
|
||||
c.set(year,month-1,day,hour,minute,second);
|
||||
c.set(Calendar.MILLISECOND,0);
|
||||
if(0!=days) {
|
||||
if(!onlyWorkday){
|
||||
c.add(Calendar.DATE,days);
|
||||
|
||||
@@ -117,6 +117,7 @@ public class SolarHalfYear {
|
||||
* @param halfYears 推移的半年数,负数为倒推
|
||||
* @return 推移后的半年
|
||||
*/
|
||||
@SuppressWarnings("MagicConstant")
|
||||
public SolarHalfYear next(int halfYears){
|
||||
if(0==halfYears){
|
||||
return new SolarHalfYear(year,month);
|
||||
|
||||
@@ -124,6 +124,7 @@ public class SolarMonth{
|
||||
* @param months 月数
|
||||
* @return 阳历月
|
||||
*/
|
||||
@SuppressWarnings("MagicConstant")
|
||||
public SolarMonth next(int months){
|
||||
Calendar c = Calendar.getInstance();
|
||||
c.set(year,month-1,1);
|
||||
|
||||
@@ -116,6 +116,7 @@ public class SolarSeason {
|
||||
* @param seasons 推移的季度数,负数为倒推
|
||||
* @return 推移后的季度
|
||||
*/
|
||||
@SuppressWarnings("MagicConstant")
|
||||
public SolarSeason next(int seasons){
|
||||
if(0==seasons){
|
||||
return new SolarSeason(year,month);
|
||||
|
||||
@@ -144,6 +144,7 @@ public class SolarWeek {
|
||||
* 获取当前日期是在当月第几周
|
||||
* @return 周序号,从1开始
|
||||
*/
|
||||
@SuppressWarnings("MagicConstant")
|
||||
public int getIndex(){
|
||||
Calendar c = Calendar.getInstance();
|
||||
c.set(year,month-1,1);
|
||||
@@ -160,6 +161,7 @@ public class SolarWeek {
|
||||
* @param separateMonth 是否按月单独计算
|
||||
* @return 推移后的阳历周
|
||||
*/
|
||||
@SuppressWarnings("MagicConstant")
|
||||
public SolarWeek next(int weeks,boolean separateMonth){
|
||||
if(0==weeks){
|
||||
return new SolarWeek(year,month,day,start);
|
||||
@@ -215,6 +217,7 @@ public class SolarWeek {
|
||||
* 获取本周第一天的阳历日期(可能跨月)
|
||||
* @return 本周第一天的阳历日期
|
||||
*/
|
||||
@SuppressWarnings("MagicConstant")
|
||||
public Solar getFirstDay(){
|
||||
Calendar c = Calendar.getInstance();
|
||||
c.set(year,month-1,day);
|
||||
|
||||
@@ -50,6 +50,7 @@ public class Yun {
|
||||
/**
|
||||
* 起运计算
|
||||
*/
|
||||
@SuppressWarnings("MagicConstant")
|
||||
private void computeStart() {
|
||||
// 上节
|
||||
JieQi prev = lunar.getPrevJie();
|
||||
@@ -60,8 +61,10 @@ public class Yun {
|
||||
// 阳男阴女顺推,阴男阳女逆推
|
||||
Solar start = forward ? current : prev.getSolar();
|
||||
Solar end = forward ? next.getSolar() : current;
|
||||
int endTimeZhiIndex = (end.getHour() == 23) ? 11 : LunarUtil.getTimeZhiIndex(end.toYmdHms().substring(11, 16));
|
||||
int startTimeZhiIndex = (start.getHour() == 23) ? 11 : LunarUtil.getTimeZhiIndex(start.toYmdHms().substring(11, 16));
|
||||
// 时辰差
|
||||
int hourDiff = LunarUtil.getTimeZhiIndex(end.toYmdHms().substring(11, 16)) - LunarUtil.getTimeZhiIndex(start.toYmdHms().substring(11, 16));
|
||||
int hourDiff = endTimeZhiIndex - startTimeZhiIndex;
|
||||
Calendar endCalendar = Calendar.getInstance();
|
||||
endCalendar.set(end.getYear(), end.getMonth() - 1, end.getDay(), 0, 0, 0);
|
||||
endCalendar.set(Calendar.MILLISECOND, 0);
|
||||
@@ -138,10 +141,12 @@ public class Yun {
|
||||
*
|
||||
* @return 阳历日期
|
||||
*/
|
||||
@SuppressWarnings("MagicConstant")
|
||||
public Solar getStartSolar() {
|
||||
Solar birth = lunar.getSolar();
|
||||
Calendar c = Calendar.getInstance();
|
||||
c.set(birth.getYear() + startYear, birth.getMonth() - 1 + startMonth, birth.getDay() + startDay, 0, 0, 0);
|
||||
c.set(Calendar.MILLISECOND,0);
|
||||
return Solar.fromCalendar(c);
|
||||
}
|
||||
|
||||
|
||||
@@ -3,34 +3,14 @@ package com.nlf.calendar.util;
|
||||
import java.util.*;
|
||||
|
||||
/**
|
||||
* 农历工具,基准日期为1900年十一月十一,对应阳历1901年1月1日,最远仅支持到2099年
|
||||
* 农历工具
|
||||
*
|
||||
* @author 6tail
|
||||
*
|
||||
*/
|
||||
public class LunarUtil{
|
||||
/** 农历基准年 */
|
||||
public static final int BASE_YEAR = 1900;
|
||||
/** 农历基准月 */
|
||||
public static final int BASE_MONTH = 11;
|
||||
/** 农历基准日 */
|
||||
public static final int BASE_DAY = 11;
|
||||
/** 农历与阳历年偏移量 */
|
||||
public static final int BASE_INDEX = 0;
|
||||
/** 基准对应的值年九星偏移量 */
|
||||
public static final int BASE_YEAR_JIU_XING_INDEX = 0;
|
||||
/** 基准对应的年干支偏移量 */
|
||||
public static final int BASE_YEAR_GANZHI_INDEX = -4;
|
||||
/** 基准对应的日干支偏移量 */
|
||||
public static final int BASE_DAY_GANZHI_INDEX = 15;
|
||||
/** 月份地支偏移量,因正月起寅 */
|
||||
public static final int BASE_MONTH_ZHI_INDEX = 2;
|
||||
/** 星期偏移量 */
|
||||
public static final int BASE_WEEK_INDEX = 2;
|
||||
/** 闰年表(存在闰月的年份偏移值) */
|
||||
public static final int[] LEAP_MONTH_YEAR = {6,14,19,25,33,36,38,41,44,52,55,79,117,136,147,150,155,158,185,193};
|
||||
/** 月份表(2个字节表示1年,共16个二进制位,前4位表示闰月月份,后12位表示每月大小) */
|
||||
public static final int[] LUNAR_MONTH = {0x00,0x04,0xad,0x08,0x5a,0x01,0xd5,0x54,0xb4,0x09,0x64,0x05,0x59,0x45,0x95,0x0a,0xa6,0x04,0x55,0x24,0xad,0x08,0x5a,0x62,0xda,0x04,0xb4,0x05,0xb4,0x55,0x52,0x0d,0x94,0x0a,0x4a,0x2a,0x56,0x02,0x6d,0x71,0x6d,0x01,0xda,0x02,0xd2,0x52,0xa9,0x05,0x49,0x0d,0x2a,0x45,0x2b,0x09,0x56,0x01,0xb5,0x20,0x6d,0x01,0x59,0x69,0xd4,0x0a,0xa8,0x05,0xa9,0x56,0xa5,0x04,0x2b,0x09,0x9e,0x38,0xb6,0x08,0xec,0x74,0x6c,0x05,0xd4,0x0a,0xe4,0x6a,0x52,0x05,0x95,0x0a,0x5a,0x42,0x5b,0x04,0xb6,0x04,0xb4,0x22,0x6a,0x05,0x52,0x75,0xc9,0x0a,0x52,0x05,0x35,0x55,0x4d,0x0a,0x5a,0x02,0x5d,0x31,0xb5,0x02,0x6a,0x8a,0x68,0x05,0xa9,0x0a,0x8a,0x6a,0x2a,0x05,0x2d,0x09,0xaa,0x48,0x5a,0x01,0xb5,0x09,0xb0,0x39,0x64,0x05,0x25,0x75,0x95,0x0a,0x96,0x04,0x4d,0x54,0xad,0x04,0xda,0x04,0xd4,0x44,0xb4,0x05,0x54,0x85,0x52,0x0d,0x92,0x0a,0x56,0x6a,0x56,0x02,0x6d,0x02,0x6a,0x41,0xda,0x02,0xb2,0xa1,0xa9,0x05,0x49,0x0d,0x0a,0x6d,0x2a,0x09,0x56,0x01,0xad,0x50,0x6d,0x01,0xd9,0x02,0xd1,0x3a,0xa8,0x05,0x29,0x85,0xa5,0x0c,0x2a,0x09,0x96,0x54,0xb6,0x08,0x6c,0x09,0x64,0x45,0xd4,0x0a,0xa4,0x05,0x51,0x25,0x95,0x0a,0x2a,0x72,0x5b,0x04,0xb6,0x04,0xac,0x52,0x6a,0x05,0xd2,0x0a,0xa2,0x4a,0x4a,0x05,0x55,0x94,0x2d,0x0a,0x5a,0x02,0x75,0x61,0xb5,0x02,0x6a,0x03,0x61,0x45,0xa9,0x0a,0x4a,0x05,0x25,0x25,0x2d,0x09,0x9a,0x68,0xda,0x08,0xb4,0x09,0xa8,0x59,0x54,0x03,0xa5,0x0a,0x91,0x3a,0x96,0x04,0xad,0xb0,0xad,0x04,0xda,0x04,0xf4,0x62,0xb4,0x05,0x54,0x0b,0x44,0x5d,0x52,0x0a,0x95,0x04,0x55,0x22,0x6d,0x02,0x5a,0x71,0xda,0x02,0xaa,0x05,0xb2,0x55,0x49,0x0b,0x4a,0x0a,0x2d,0x39,0x36,0x01,0x6d,0x80,0x6d,0x01,0xd9,0x02,0xe9,0x6a,0xa8,0x05,0x29,0x0b,0x9a,0x4c,0xaa,0x08,0xb6,0x08,0xb4,0x38,0x6c,0x09,0x54,0x75,0xd4,0x0a,0xa4,0x05,0x45,0x55,0x95,0x0a,0x9a,0x04,0x55,0x44,0xb5,0x04,0x6a,0x82,0x6a,0x05,0xd2,0x0a,0x92,0x6a,0x4a,0x05,0x55,0x0a,0x2a,0x4a,0x5a,0x02,0xb5,0x02,0xb2,0x31,0x69,0x03,0x31,0x73,0xa9,0x0a,0x4a,0x05,0x2d,0x55,0x2d,0x09,0x5a,0x01,0xd5,0x48,0xb4,0x09,0x68,0x89,0x54,0x0b,0xa4,0x0a,0xa5,0x6a,0x95,0x04,0xad,0x08,0x6a,0x44,0xda,0x04,0x74,0x05,0xb0,0x25,0x54,0x03};
|
||||
/** 旬 */
|
||||
public static final String[] XUN = {"甲子","甲戌","甲申","甲午","甲辰","甲寅"};
|
||||
/** 旬空 */
|
||||
@@ -1124,102 +1104,6 @@ public class LunarUtil{
|
||||
|
||||
protected LunarUtil(){}
|
||||
|
||||
/**
|
||||
* 计算指定日期距离基准日期的天数
|
||||
* @param year 农历年
|
||||
* @param month 农历月
|
||||
* @param day 农历日
|
||||
* @return 距离天数
|
||||
*/
|
||||
public static int computeAddDays(int year,int month,int day){
|
||||
if(BASE_YEAR==year&&BASE_MONTH==month){
|
||||
return day-BASE_DAY;
|
||||
}
|
||||
int y = BASE_YEAR;
|
||||
int m = BASE_MONTH;
|
||||
int diff = getDaysOfMonth(y,m)-BASE_DAY;
|
||||
while(y!=year||m!=month){
|
||||
m = nextMonth(y,m);
|
||||
if(m==1){
|
||||
y++;
|
||||
}
|
||||
if(y==year&&m==month){
|
||||
diff += day;
|
||||
}else {
|
||||
diff += getDaysOfMonth(y, m);
|
||||
}
|
||||
}
|
||||
return diff;
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取指定年份的闰月
|
||||
* @param year 年份
|
||||
* @return 闰月数字,1代表闰1月,0代表无闰月
|
||||
*/
|
||||
public static int getLeapMonth(int year){
|
||||
int index = year-BASE_YEAR+BASE_INDEX;
|
||||
int v = LUNAR_MONTH[2*index+1];
|
||||
v = (v>>4)&0x0F;
|
||||
return v;
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取指定年月的下一个月是第几月
|
||||
* @param y 农历年
|
||||
* @param m 农历月,闰月为负数
|
||||
* @return 1到12,闰月为负数
|
||||
*/
|
||||
public static int nextMonth(int y,int m){
|
||||
int n = Math.abs(m)+1;
|
||||
if(m>0){
|
||||
if(m==getLeapMonth(y)){
|
||||
n = -m;
|
||||
}
|
||||
}
|
||||
return 13!=n?n:1;
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取某年某月有多少天
|
||||
*
|
||||
* @param year 农历年
|
||||
* @param month 农历月,闰月为负数
|
||||
* @return 天数
|
||||
*/
|
||||
public static int getDaysOfMonth(int year,int month){
|
||||
int index = year-BASE_YEAR+BASE_INDEX;
|
||||
int v,l,d=30;
|
||||
if(1<=month&&month<=8){
|
||||
v = LUNAR_MONTH[2*index];
|
||||
l = month-1;
|
||||
if(((v>>l)&0x01)==1){
|
||||
d = 29;
|
||||
}
|
||||
}else if(9<=month&&month<=12){
|
||||
v = LUNAR_MONTH[2*index+1];
|
||||
l = month-9;
|
||||
if(((v>>l)&0x01)==1){
|
||||
d = 29;
|
||||
}
|
||||
}else{
|
||||
v = LUNAR_MONTH[2*index+1];
|
||||
v = (v>>4)&0x0F;
|
||||
if(v!=Math.abs(month)){
|
||||
d = 0;
|
||||
}else{
|
||||
d = 29;
|
||||
for(int i:LEAP_MONTH_YEAR){
|
||||
if(i==index){
|
||||
d = 30;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return d;
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取HH:mm时刻的地支序号,非法的时刻返回0
|
||||
* @param hm HH:mm时刻
|
||||
|
||||
265
src/main/java/com/nlf/calendar/util/ShouXingUtil.java
Normal file
265
src/main/java/com/nlf/calendar/util/ShouXingUtil.java
Normal file
File diff suppressed because one or more lines are too long
@@ -3,17 +3,11 @@ package com.nlf.calendar.util;
|
||||
import java.util.*;
|
||||
|
||||
/**
|
||||
* 阳历工具,基准日期为1901年1月1日,对应农历1900年十一月十一
|
||||
* 阳历工具
|
||||
*
|
||||
* @author 6tail
|
||||
*/
|
||||
public class SolarUtil{
|
||||
/** 阳历基准年 */
|
||||
public static final int BASE_YEAR = 1901;
|
||||
/** 阳历基准月 */
|
||||
public static final int BASE_MONTH = 1;
|
||||
/** 阳历基准日 */
|
||||
public static final int BASE_DAY = 1;
|
||||
/** 星期*/
|
||||
public static final String[] WEEK = {"日","一","二","三","四","五","六"};
|
||||
/** 每月天数 */
|
||||
@@ -132,17 +126,7 @@ public class SolarUtil{
|
||||
* @return true/false 闰年/非闰年
|
||||
*/
|
||||
public static boolean isLeapYear(int year){
|
||||
boolean leap = false;
|
||||
if(year%4==0){
|
||||
leap = true;
|
||||
}
|
||||
if(year%100==0){
|
||||
leap = false;
|
||||
}
|
||||
if(year%400==0){
|
||||
leap = true;
|
||||
}
|
||||
return leap;
|
||||
return (year%4 == 0 && year%100 != 0) || (year%400 == 0);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -170,6 +154,7 @@ public class SolarUtil{
|
||||
* @param start 星期几作为一周的开始,1234560分别代表星期一至星期天
|
||||
* @return 周数
|
||||
*/
|
||||
@SuppressWarnings("MagicConstant")
|
||||
public static int getWeeksOfMonth(int year,int month,int start){
|
||||
int days = getDaysOfMonth(year,month);
|
||||
Calendar c = Calendar.getInstance();
|
||||
|
||||
@@ -23,22 +23,21 @@ public class YearTest {
|
||||
for(Solar d:m.getDays()){
|
||||
//获取阴历
|
||||
Lunar lunar = d.getLunar();
|
||||
StringBuilder s = new StringBuilder();
|
||||
s.append(d.getDay()<10?"0":"");
|
||||
s.append(d.getDay());
|
||||
s.append(" ");
|
||||
s.append(lunar.getMonthInChinese());
|
||||
s.append("月");
|
||||
s.append(lunar.getDayInChinese());
|
||||
s.append(" ");
|
||||
s.append("星期");
|
||||
s.append(d.getWeekInChinese());
|
||||
s.append(" ");
|
||||
s.append(d.getFestivals());
|
||||
s.append(lunar.getFestivals());
|
||||
s.append(lunar.getJie());
|
||||
s.append(lunar.getQi());
|
||||
System.out.println(s.toString());
|
||||
String s = (d.getDay() < 10 ? "0" : "") +
|
||||
d.getDay() +
|
||||
" " +
|
||||
lunar.getMonthInChinese() +
|
||||
"月" +
|
||||
lunar.getDayInChinese() +
|
||||
" " +
|
||||
"星期" +
|
||||
d.getWeekInChinese() +
|
||||
" " +
|
||||
d.getFestivals() +
|
||||
lunar.getFestivals() +
|
||||
lunar.getJie() +
|
||||
lunar.getQi();
|
||||
System.out.println(s);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -6,6 +6,8 @@ import com.nlf.calendar.Solar;
|
||||
import org.junit.Assert;
|
||||
import org.junit.Test;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* 八字测试
|
||||
*/
|
||||
@@ -218,4 +220,14 @@ public class BaZiTest {
|
||||
Assert.assertEquals("身宫", "壬午", lunar.getEightChar().getShenGong());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testBaZi2Solar() {
|
||||
Solar solar = Solar.fromYmdHms(2027,1,27,12,0,0);
|
||||
System.out.println(solar.getLunar().getEightChar().toString());
|
||||
List<Solar> l = Solar.fromBaZi("丙午","辛丑","丙午","甲午");
|
||||
for(Solar s:l){
|
||||
System.out.println(s.toFullString());
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -196,4 +196,128 @@ public class GanZhiTest {
|
||||
Assert.assertEquals("癸巳",lunar.getMonthInGanZhiExact());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void test1() {
|
||||
Solar solar = new Solar(1996, 1, 16);
|
||||
Lunar lunar = solar.getLunar();
|
||||
Assert.assertEquals("壬子",lunar.getDayInGanZhi());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void test2() {
|
||||
Solar solar = new Solar(1997, 2, 16);
|
||||
Lunar lunar = solar.getLunar();
|
||||
Assert.assertEquals("己丑",lunar.getDayInGanZhi());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void test3() {
|
||||
Solar solar = new Solar(1998, 3, 16);
|
||||
Lunar lunar = solar.getLunar();
|
||||
Assert.assertEquals("壬戌",lunar.getDayInGanZhi());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void test4() {
|
||||
Solar solar = new Solar(1999, 4, 16);
|
||||
Lunar lunar = solar.getLunar();
|
||||
Assert.assertEquals("戊戌",lunar.getDayInGanZhi());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void test5() {
|
||||
Solar solar = new Solar(2000, 7, 16);
|
||||
Lunar lunar = solar.getLunar();
|
||||
Assert.assertEquals("乙亥",lunar.getDayInGanZhi());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void test6() {
|
||||
Solar solar = new Solar(2000, 1, 6);
|
||||
Lunar lunar = solar.getLunar();
|
||||
Assert.assertEquals("癸亥",lunar.getDayInGanZhi());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void test7() {
|
||||
Solar solar = new Solar(2000, 1, 9);
|
||||
Lunar lunar = solar.getLunar();
|
||||
Assert.assertEquals("丙寅",lunar.getDayInGanZhi());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void test8() {
|
||||
Solar solar = new Solar(2000, 2, 2);
|
||||
Lunar lunar = solar.getLunar();
|
||||
Assert.assertEquals("庚寅",lunar.getDayInGanZhi());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void test9() {
|
||||
Solar solar = new Solar(2012, 8, 5);
|
||||
Lunar lunar = solar.getLunar();
|
||||
Assert.assertEquals("戊戌",lunar.getDayInGanZhi());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void test10() {
|
||||
Solar solar = new Solar(2012, 9, 20);
|
||||
Lunar lunar = solar.getLunar();
|
||||
Assert.assertEquals("壬辰",lunar.getYearInGanZhi());
|
||||
Assert.assertEquals("己酉",lunar.getMonthInGanZhi());
|
||||
Assert.assertEquals("甲申",lunar.getDayInGanZhi());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void test11() {
|
||||
Solar solar = new Solar(2012, 10, 20);
|
||||
Lunar lunar = solar.getLunar();
|
||||
Assert.assertEquals("壬辰",lunar.getYearInGanZhi());
|
||||
Assert.assertEquals("庚戌",lunar.getMonthInGanZhi());
|
||||
Assert.assertEquals("甲寅",lunar.getDayInGanZhi());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void test12() {
|
||||
Solar solar = new Solar(2012, 11, 20);
|
||||
Lunar lunar = solar.getLunar();
|
||||
Assert.assertEquals("壬辰",lunar.getYearInGanZhi());
|
||||
Assert.assertEquals("辛亥",lunar.getMonthInGanZhi());
|
||||
Assert.assertEquals("乙酉",lunar.getDayInGanZhi());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void test13() {
|
||||
Solar solar = new Solar(2012, 12, 20);
|
||||
Lunar lunar = solar.getLunar();
|
||||
Assert.assertEquals("壬辰",lunar.getYearInGanZhi());
|
||||
Assert.assertEquals("壬子",lunar.getMonthInGanZhi());
|
||||
Assert.assertEquals("乙卯",lunar.getDayInGanZhi());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void test14() {
|
||||
Solar solar = new Solar(2012, 12, 27);
|
||||
Lunar lunar = solar.getLunar();
|
||||
Assert.assertEquals("壬辰",lunar.getYearInGanZhi());
|
||||
Assert.assertEquals("壬子",lunar.getMonthInGanZhi());
|
||||
Assert.assertEquals("壬戌",lunar.getDayInGanZhi());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void test15() {
|
||||
Solar solar = new Solar(1988, 2, 15);
|
||||
Lunar lunar = solar.getLunar();
|
||||
Assert.assertEquals("丁卯",lunar.getYearInGanZhi());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void test16() {
|
||||
Solar solar = new Solar(1988, 2, 15, 23, 30,0);
|
||||
Lunar lunar = solar.getLunar();
|
||||
Assert.assertEquals("丁卯",lunar.getYearInGanZhi());
|
||||
Assert.assertEquals("戊辰",lunar.getYearInGanZhiByLiChun());
|
||||
Assert.assertEquals("戊辰",lunar.getYearInGanZhiExact());
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -21,11 +21,54 @@ public class LunarTest {
|
||||
Assert.assertEquals("2019-05-01 00:00:00 星期三 (劳动节) 金牛座",date.getSolar().toFullString());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void test1(){
|
||||
Solar solar = new Solar(1,1,1,12,0,0);
|
||||
Assert.assertEquals("〇年冬月十八",solar.getLunar().toString());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void test2(){
|
||||
Solar solar = new Solar(9999,12,31,12,0,0);
|
||||
Assert.assertEquals("九九九九年腊月初二",solar.getLunar().toString());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void test3(){
|
||||
Lunar lunar = new Lunar(0,11,18,12,0,0);
|
||||
Assert.assertEquals("0001-01-01",lunar.getSolar().toString());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void test4(){
|
||||
Lunar lunar = new Lunar(9999,12,2,12,0,0);
|
||||
Assert.assertEquals("9999-12-31",lunar.getSolar().toString());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void test5(){
|
||||
Lunar lunar = new Lunar(1905,1,1,12,0,0);
|
||||
Assert.assertEquals("1905-02-04",lunar.getSolar().toString());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void test6(){
|
||||
Lunar lunar = new Lunar(2038,12,29,12,0,0);
|
||||
Assert.assertEquals("2039-01-23",lunar.getSolar().toString());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void test7(){
|
||||
Lunar lunar = new Lunar(2020,-4,2,13,0,0);
|
||||
Assert.assertEquals("二〇二〇年闰四月初二",lunar.toString());
|
||||
Assert.assertEquals("2020-05-24",lunar.getSolar().toString());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testNext(){
|
||||
Solar solar = new Solar(2020,1,10,12,0,0);
|
||||
Lunar lunar = solar.getLunar();
|
||||
for(int i=-500;i<500;i++){
|
||||
for(int i=-50;i<50;i++){
|
||||
Assert.assertEquals("推移天数:"+i,solar.next(i).getLunar().toFullString(),lunar.next(i).toFullString());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -20,6 +20,12 @@ public class SolarTest {
|
||||
Assert.assertEquals("二〇一九年三月廿七 己亥(猪)年 戊辰(龙)月 戊戌(狗)日 子(鼠)时 纳音[平地木 大林木 平地木 桑柘木] 星期三 (七殿泰山王诞) 西方白虎 星宿[参水猿](吉) 彭祖百忌[戊不受田田主不祥 戌不吃犬作怪上床] 喜神方位[巽](东南) 阳贵神方位[艮](东北) 阴贵神方位[坤](西南) 福神方位[坎](正北) 财神方位[坎](正北) 冲[(壬辰)龙] 煞[北]",date.getLunar().toFullString());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void test1(){
|
||||
Solar solar = new Solar(2020,5,24,13,0,0);
|
||||
Assert.assertEquals("二〇二〇年闰四月初二",solar.getLunar().toString());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testNext(){
|
||||
Solar date = new Solar(2020,1,23);
|
||||
|
||||
@@ -5,7 +5,7 @@ import org.junit.Assert;
|
||||
import org.junit.Test;
|
||||
|
||||
/**
|
||||
* 阳历测试
|
||||
* 星座测试
|
||||
*
|
||||
* @author 6tail
|
||||
*/
|
||||
|
||||
27
src/test/java/test/YunTest.java
Normal file
27
src/test/java/test/YunTest.java
Normal file
@@ -0,0 +1,27 @@
|
||||
package test;
|
||||
|
||||
import com.nlf.calendar.EightChar;
|
||||
import com.nlf.calendar.Lunar;
|
||||
import com.nlf.calendar.Solar;
|
||||
import com.nlf.calendar.eightchar.Yun;
|
||||
import org.junit.Assert;
|
||||
import org.junit.Test;
|
||||
|
||||
/**
|
||||
* 起运测试
|
||||
*/
|
||||
public class YunTest {
|
||||
|
||||
@Test
|
||||
public void test1() {
|
||||
Solar solar = new Solar(1981, 1, 29, 23, 37, 0);
|
||||
Lunar lunar = solar.getLunar();
|
||||
EightChar eightChar = lunar.getEightChar();
|
||||
Yun yun = eightChar.getYun(0);
|
||||
Assert.assertEquals("起运年数", 8, yun.getStartYear());
|
||||
Assert.assertEquals("起运月数", 0, yun.getStartMonth());
|
||||
Assert.assertEquals("起运天数", 20, yun.getStartDay());
|
||||
Assert.assertEquals("起运阳历", "1989-02-18", yun.getStartSolar().toYmd());
|
||||
}
|
||||
|
||||
}
|
||||
Reference in New Issue
Block a user