1
0
mirror of synced 2026-02-23 13:28:00 +08:00

optimized codes and fix negative month bug @ Lunar.getXiu()

This commit is contained in:
6tail
2019-05-05 15:45:00 +08:00
parent c196e58ec8
commit 6db884b981
16 changed files with 366 additions and 109 deletions

View File

@@ -9,7 +9,7 @@ import com.nlf.calendar.util.SolarUtil;
/**
* 农历日期
*
*
* @author 6tail
*
*/
@@ -73,7 +73,9 @@ public class Lunar{
int diff = 0;
for(int i=startY;i<y;i++){
diff += 365;
if(SolarUtil.isLeapYear(i)) diff += 1;
if(SolarUtil.isLeapYear(i)){
diff += 1;
}
}
for(int i=startM;i<m;i++){
diff += SolarUtil.getDaysOfMonth(y,i);
@@ -84,7 +86,9 @@ public class Lunar{
while(lunarD>lastDate){
lunarD -= lastDate;
lunarM = LunarUtil.nextMonth(lunarY,lunarM);
if(lunarM==1) lunarY++;
if(lunarM==1){
lunarY++;
}
lastDate = LunarUtil.getDaysOfMonth(lunarY,lunarM);
}
year = lunarY;
@@ -116,7 +120,7 @@ public class Lunar{
/**
* 获取干
*
*
* @return 干,如辛
*/
public String getGan(){
@@ -125,7 +129,7 @@ public class Lunar{
/**
* 获取支
*
*
* @return 支,如亥
*/
public String getZhi(){
@@ -134,7 +138,7 @@ public class Lunar{
/**
* 获取生肖
*
*
* @return 生肖,如虎
*/
public String getShengxiao(){
@@ -143,12 +147,15 @@ public class Lunar{
/**
* 获取中文的月
*
*
* @return 中文月,如正月
*/
public String getMonthInChinese(){
if(month>0) return LunarUtil.MONTH[month];
else return ""+LunarUtil.MONTH[-month];
if(month>0){
return LunarUtil.MONTH[month];
}else{
return ""+LunarUtil.MONTH[-month];
}
}
/**
@@ -161,7 +168,7 @@ public class Lunar{
/**
* 获取中文日
*
*
* @return 中文日,如初一
*/
public String getDayInChinese(){
@@ -170,7 +177,7 @@ public class Lunar{
/**
* 获取节
*
*
* @return 节
*/
public String getJie(){
@@ -184,16 +191,24 @@ public class Lunar{
index++;
}
int term = LunarUtil.JIE_MAP[solarMonth-1][4*index+ry%4];
if(ry==121&&solarMonth==4) term = 5;
if(ry==132&&solarMonth==4) term = 5;
if(ry==194&&solarMonth==6) term = 6;
if(solarDay==term) s = LunarUtil.JIE[solarMonth-1];
if(ry==121&&solarMonth==4){
term = 5;
}
if(ry==132&&solarMonth==4){
term = 5;
}
if(ry==194&&solarMonth==6){
term = 6;
}
if(solarDay==term){
s = LunarUtil.JIE[solarMonth-1];
}
return s;
}
/**
* 获取气
*
*
* @return 气
*/
public String getQi(){
@@ -207,24 +222,30 @@ public class Lunar{
index++;
}
int term = LunarUtil.QI_MAP[solarMonth-1][4*index+ry%4];
if(ry==171&&solarMonth==3) term = 21;
if(ry==181&&solarMonth==5) term = 21;
if(solarDay==term) s = LunarUtil.QI[solarMonth-1];
if(ry==171&&solarMonth==3){
term = 21;
}
if(ry==181&&solarMonth==5){
term = 21;
}
if(solarDay==term){
s = LunarUtil.QI[solarMonth-1];
}
return s;
}
/**
* 获取宿
*
*
* @return 宿
*/
public String getXiu(){
return LunarUtil.XIU[day-1][month-1];
return LunarUtil.XIU[day-1][Math.abs(month)-1];
}
/**
* 获取政
*
*
* @return 政
*/
public String getZheng(){
@@ -257,19 +278,21 @@ public class Lunar{
/**
* 获取节日,有可能一天会有多个节日
*
*
* @return 春节等
*/
public List<String> getFestivals(){
List<String> l = new ArrayList<String>();
String f = LunarUtil.FESTIVAL.get(month+"-"+day);
if(null!=f) l.add(f);
if(null!=f){
l.add(f);
}
return l;
}
/**
* 转换为阳历日期
*
*
* @return 阳历日期
*/
private Solar toSolar(){
@@ -281,7 +304,9 @@ public class Lunar{
while(true){
diff += LunarUtil.getDaysOfMonth(y,m);
m = LunarUtil.nextMonth(y,m);
if(m==1) y++;
if(m==1){
y++;
}
if(y==year&&m==month){
diff += day;
break;
@@ -292,7 +317,7 @@ public class Lunar{
c.add(Calendar.DATE,diff);
return new Solar(c);
}
public String toFullString(){
StringBuilder s = new StringBuilder();
s.append(toString());
@@ -321,13 +346,14 @@ public class Lunar{
return s.toString();
}
@Override
public String toString(){
return getGan()+getZhi()+""+getMonthInChinese()+""+getDayInChinese();
}
/**
* 获取年份
*
*
* @return 如2015
*/
public int getYear(){
@@ -336,7 +362,7 @@ public class Lunar{
/**
* 获取月份
*
*
* @return 1到12负数为闰月
*/
public int getMonth(){
@@ -345,7 +371,7 @@ public class Lunar{
/**
* 获取日期
*
*
* @return 日期
*/
public int getDay(){
@@ -355,4 +381,4 @@ public class Lunar{
public Solar getSolar(){
return solar;
}
}
}

View File

@@ -8,7 +8,7 @@ import com.nlf.calendar.util.SolarUtil;
/**
* 阳历日期
*
*
* @author 6tail
*
*/
@@ -31,7 +31,7 @@ public class Solar{
/**
* 通过年月日初始化
*
*
* @param year 年
* @param month 月1到12
* @param day 日1到31
@@ -46,7 +46,7 @@ public class Solar{
/**
* 通过日期初始化
*
*
* @param date 日期
*/
public Solar(Date date){
@@ -56,10 +56,10 @@ public class Solar{
month = calendar.get(Calendar.MONTH)+1;
day = calendar.get(Calendar.DATE);
}
/**
* 通过日历初始化
*
*
* @param calendar 日历
*/
public Solar(Calendar calendar){
@@ -103,7 +103,7 @@ public class Solar{
/**
* 是否闰年
*
*
* @return true/false 闰年/非闰年
*/
public boolean isLeapYear(){
@@ -112,7 +112,7 @@ public class Solar{
/**
* 获取星期0代表周日1代表周一
*
*
* @return 0123456
*/
public int getWeek(){
@@ -121,7 +121,7 @@ public class Solar{
/**
* 获取星期的中文
*
*
* @return 日一二三四五六
*/
public String getWeekInChinese(){
@@ -130,51 +130,69 @@ public class Solar{
/**
* 获取节日,有可能一天会有多个节日
*
*
* @return 劳动节等
*/
public List<String> getFestivals(){
List<String> l = new ArrayList<String>();
//获取几月几日对应的节日
String f = SolarUtil.FESTIVAL.get(month+"-"+day);
if(null!=f) l.add(f);
if(null!=f){
l.add(f);
}
//计算几月第几个星期几对应的节日
//第几周
int weekInMonth = calendar.get(Calendar.WEEK_OF_MONTH);
//星期几0代表星期天
int week = getWeek();
//星期天很奇葩,会多算一周,需要减掉
if(0==week) weekInMonth--;
if(0==week){
weekInMonth--;
}
f = SolarUtil.WEEK_FESTIVAL.get(month+"-"+weekInMonth+"-"+week);
if(null!=f) l.add(f);
if(null!=f){
l.add(f);
}
return l;
}
/**
* 获取星座
*
*
* @return 星座
*/
public String getXingzuo(){
int index = 11,m = month,d = day;
int y = m*100+d;
if(y>=321&&y<=419) index = 0;
else if(y>=420&&y<=520) index = 1;
else if(y>=521&&y<=620) index = 2;
else if(y>=621&&y<=722) index = 3;
else if(y>=723&&y<=822) index = 4;
else if(y>=823&&y<=922) index = 5;
else if(y>=923&&y<=1022) index = 6;
else if(y>=1023&&y<=1121) index = 7;
else if(y>=1122&&y<=1221) index = 8;
else if(y>=1222||y<=119) index = 9;
else if(y<=218) index = 10;
if(y>=321&&y<=419){
index = 0;
}else if(y>=420&&y<=520){
index = 1;
}else if(y>=521&&y<=620){
index = 2;
}else if(y>=621&&y<=722){
index = 3;
}else if(y>=723&&y<=822){
index = 4;
}else if(y>=823&&y<=922){
index = 5;
}else if(y>=923&&y<=1022){
index = 6;
}else if(y>=1023&&y<=1121){
index = 7;
}else if(y>=1122&&y<=1221){
index = 8;
}else if(y>=1222||y<=119){
index = 9;
}else if(y<=218){
index = 10;
}
return SolarUtil.XINGZUO[index];
}
/**
* 获取年份
*
*
* @return 如2015
*/
public int getYear(){
@@ -183,7 +201,7 @@ public class Solar{
/**
* 获取月份
*
*
* @return 1到12
*/
public int getMonth(){
@@ -192,13 +210,13 @@ public class Solar{
/**
* 获取日期
*
*
* @return 1到31之间的数字
*/
public int getDay(){
return day;
}
/**
* 获取农历
* @return 农历
@@ -209,17 +227,18 @@ public class Solar{
/**
* 获取日历
*
*
* @return 日历
*/
public Calendar getCalendar(){
return calendar;
}
@Override
public String toString(){
return year+"-"+(month<10?"0":"")+month+"-"+(day<10?"0":"")+day;
}
public String toFullString(){
StringBuilder s = new StringBuilder();
s.append(toString());
@@ -253,4 +272,4 @@ public class Solar{
return new Solar(c);
}
}
}

View File

@@ -7,6 +7,8 @@ import java.util.List;
/**
* 阳历半年
*
* @author 6tail
*/
public class SolarHalfYear {
/** 年 */
@@ -14,6 +16,9 @@ public class SolarHalfYear {
/** 月 */
private int month;
/** 半年的月数 */
public static final int MONTH_COUNT = 6;
/**
* 默认当月
*/
@@ -104,7 +109,7 @@ public class SolarHalfYear {
* @return 半年序号从1开始
*/
public int getIndex(){
return (int)Math.ceil(month/6D);
return (int)Math.ceil(month*1D/MONTH_COUNT);
}
/**
@@ -118,7 +123,7 @@ public class SolarHalfYear {
}
Calendar c = Calendar.getInstance();
c.set(year,month-1,1);
c.add(Calendar.MONTH,6*halfYears);
c.add(Calendar.MONTH,MONTH_COUNT*halfYears);
return new SolarHalfYear(c);
}
@@ -129,12 +134,13 @@ public class SolarHalfYear {
public List<SolarMonth> getMonths(){
List<SolarMonth> l = new ArrayList<SolarMonth>();
int index = getIndex()-1;
for(int i=0;i<6;i++){
l.add(new SolarMonth(year,6*index+i+1));
for(int i=0;i<MONTH_COUNT;i++){
l.add(new SolarMonth(year,MONTH_COUNT*index+i+1));
}
return l;
}
@Override
public String toString(){
return year+"."+getIndex();
}
@@ -142,4 +148,4 @@ public class SolarHalfYear {
public String toFullString(){
return year+""+(getIndex()==1?"":"")+"半年";
}
}
}

View File

@@ -8,7 +8,7 @@ import com.nlf.calendar.util.SolarUtil;
/**
* 阳历月
*
*
* @author 6tail
*
*/
@@ -45,7 +45,7 @@ public class SolarMonth{
/**
* 通过年月初始化
*
*
* @param year 年
* @param month 月
*/
@@ -87,7 +87,7 @@ public class SolarMonth{
/**
* 获取年
*
*
* @return 年
*/
public int getYear(){
@@ -96,7 +96,7 @@ public class SolarMonth{
/**
* 获取月
*
*
* @return 月
*/
public int getMonth(){
@@ -105,7 +105,7 @@ public class SolarMonth{
/**
* 获取本月的阳历日期列表
*
*
* @return 阳历日期列表
*/
public List<Solar> getDays(){
@@ -118,7 +118,7 @@ public class SolarMonth{
}
return l;
}
/**
* 获取往后推几个月的阳历月,如果要往前推,则月数用负数
* @param months 月数
@@ -131,6 +131,7 @@ public class SolarMonth{
return new SolarMonth(c);
}
@Override
public String toString(){
return year+"-"+month;
}
@@ -138,4 +139,4 @@ public class SolarMonth{
public String toFullString(){
return year+""+month+"";
}
}
}

View File

@@ -7,12 +7,16 @@ import java.util.List;
/**
* 阳历季度
*
* @author 6tail
*/
public class SolarSeason {
/** 年 */
private int year;
/** 月 */
private int month;
/** 一个季度的月数 */
public static final int MONTH_COUNT = 3;
/**
* 默认当月
@@ -104,7 +108,7 @@ public class SolarSeason {
* @return 季度序号从1开始
*/
public int getIndex(){
return (int)Math.ceil(month/3D);
return (int)Math.ceil(month*1D/MONTH_COUNT);
}
/**
@@ -118,7 +122,7 @@ public class SolarSeason {
}
Calendar c = Calendar.getInstance();
c.set(year,month-1,1);
c.add(Calendar.MONTH,3*seasons);
c.add(Calendar.MONTH,MONTH_COUNT*seasons);
return new SolarSeason(c);
}
@@ -129,12 +133,13 @@ public class SolarSeason {
public List<SolarMonth> getMonths(){
List<SolarMonth> l = new ArrayList<SolarMonth>();
int index = getIndex()-1;
for(int i=0;i<3;i++){
l.add(new SolarMonth(year,3*index+i+1));
for(int i=0;i<MONTH_COUNT;i++){
l.add(new SolarMonth(year,MONTH_COUNT*index+i+1));
}
return l;
}
@Override
public String toString(){
return year+"."+getIndex();
}
@@ -142,4 +147,4 @@ public class SolarSeason {
public String toFullString(){
return year+""+getIndex()+"季度";
}
}
}

View File

@@ -9,6 +9,8 @@ import java.util.List;
/**
* 阳历周
*
* @author 6tail
*/
public class SolarWeek {
/** 年 */
@@ -266,6 +268,7 @@ public class SolarWeek {
return l;
}
@Override
public String toString(){
return year+"."+month+"."+getIndex();
}
@@ -273,4 +276,4 @@ public class SolarWeek {
public String toFullString(){
return year+""+month+"月第"+getIndex()+"";
}
}
}

View File

@@ -7,7 +7,7 @@ import java.util.List;
/**
* 阳历年
*
*
* @author 6tail
*
*/
@@ -15,6 +15,9 @@ public class SolarYear{
/** 年 */
private int year;
/** 一年的月数 */
public static final int MONTH_COUNT = 12;
/**
* 默认当年
*/
@@ -40,7 +43,7 @@ public class SolarYear{
/**
* 通过年初始化
*
*
* @param year 年
*/
public SolarYear(int year){
@@ -79,7 +82,7 @@ public class SolarYear{
/**
* 获取年
*
*
* @return 年
*/
public int getYear(){
@@ -88,19 +91,19 @@ public class SolarYear{
/**
* 获取本年的阳历月列表
*
*
* @return 阳历月列表
*/
public List<SolarMonth> getMonths(){
List<SolarMonth> l = new ArrayList<SolarMonth>(12);
List<SolarMonth> l = new ArrayList<SolarMonth>(MONTH_COUNT);
SolarMonth m = new SolarMonth(year,1);
l.add(m);
for(int i = 1;i<12;i++){
for(int i = 1;i<MONTH_COUNT;i++){
l.add(m.next(i));
}
return l;
}
/**
* 获取往后推几年的阳历年,如果要往前推,则年数用负数
* @param years 年数
@@ -108,11 +111,12 @@ public class SolarYear{
*/
public SolarYear next(int years){
Calendar c = Calendar.getInstance();
c.set(year,0,1);
c.set(year,Calendar.JANUARY,1);
c.add(Calendar.YEAR,years);
return new SolarYear(c);
}
@Override
public String toString(){
return year+"";
}
@@ -120,4 +124,4 @@ public class SolarYear{
public String toFullString(){
return year+"";
}
}
}

View File

@@ -4,8 +4,8 @@ import java.util.HashMap;
import java.util.Map;
/**
* 农历工具
*
* 农历工具基准日期为1900年十一月十一对应阳历1901年1月1日最远仅支持到2099年
*
* @author 6tail
*
*/
@@ -204,9 +204,9 @@ public class LunarUtil{
/**
* 获取指定年月的下一个月是第几月
* @param y 年
* @param m
* @return 1到12闰月为负
* @param y 农历
* @param m 农历月,闰月为负数
* @return 1到12闰月为负
*/
public static int nextMonth(int y,int m){
int n = Math.abs(m)+1;
@@ -218,19 +218,20 @@ public class LunarUtil{
n = -m;
}
}
if(n==13) n = 1;
if(n==13){
n = 1;
}
return n;
}
/**
* 获取某年某月有多少天
*
* @param year 年
* @param month
*
* @param year 农历
* @param month 农历月,闰月为负数
* @return 天数
*/
public static int getDaysOfMonth(int year,int month){
// 注意:闰月 lunarMonth < 0
int index = year-BASE_YEAR+BASE_INDEX;
int v,l,d=30;
if(1<=month&&month<=8){
@@ -262,4 +263,4 @@ public class LunarUtil{
}
return d;
}
}
}

View File

@@ -5,9 +5,9 @@ import java.util.HashMap;
import java.util.Map;
/**
* 阳历工具
* @author 6tail
* 阳历工具基准日期为1901年1月1日对应农历1900年十一月十一
*
* @author 6tail
*/
public class SolarUtil{
/** 阳历基准年 */
@@ -57,21 +57,27 @@ public class SolarUtil{
/**
* 是否闰年
*
*
* @param year 年
* @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;
if(year%4==0){
leap = true;
}
if(year%100==0){
leap = false;
}
if(year%400==0){
leap = true;
}
return leap;
}
/**
* 获取某年某月有多少天
*
*
* @param year 年
* @param month 月
* @return 天数
@@ -99,6 +105,6 @@ public class SolarUtil{
Calendar c = Calendar.getInstance();
c.set(year,month-1,1);
int week = c.get(Calendar.DAY_OF_WEEK)-1;
return (int)Math.ceil((days+week-start)/7D);
return (int)Math.ceil((days+week-start)*1D/WEEK.length);
}
}
}

View File

@@ -0,0 +1,24 @@
package test;
import com.nlf.calendar.SolarHalfYear;
import org.junit.Assert;
import org.junit.Test;
/**
* 半年测试
*
* @author 6tail
*/
public class HalfYearTest {
@Test
public void test(){
SolarHalfYear halfYear = new SolarHalfYear(2019,5);
Assert.assertEquals("2019.1",halfYear.toString());
Assert.assertEquals("2019年上半年",halfYear.toFullString());
Assert.assertEquals("2019.2",halfYear.next(1).toString());
Assert.assertEquals("2019年下半年",halfYear.next(1).toFullString());
}
}

View File

@@ -0,0 +1,23 @@
package test;
import com.nlf.calendar.Lunar;
import org.junit.Assert;
import org.junit.Test;
/**
* 农历测试
*
* @author 6tail
*/
public class LunarTest {
@Test
public void test(){
Lunar date = new Lunar(2019,3,27);
Assert.assertEquals("己亥年叁月廿七",date.toString());
Assert.assertEquals("己亥年叁月廿七 猪年 西方白虎 娄金狗",date.toFullString());
Assert.assertEquals("2019-05-01",date.getSolar().toString());
Assert.assertEquals("2019-05-01 星期三 (劳动节) 金牛座",date.getSolar().toFullString());
}
}

View File

@@ -0,0 +1,24 @@
package test;
import com.nlf.calendar.SolarMonth;
import org.junit.Assert;
import org.junit.Test;
/**
* 月份测试
*
* @author 6tail
*/
public class MonthTest {
@Test
public void test(){
SolarMonth month = new SolarMonth(2019,5);
Assert.assertEquals("2019-5",month.toString());
Assert.assertEquals("2019年5月",month.toFullString());
Assert.assertEquals("2019-6",month.next(1).toString());
Assert.assertEquals("2019年6月",month.next(1).toFullString());
}
}

View File

@@ -0,0 +1,24 @@
package test;
import com.nlf.calendar.SolarSeason;
import org.junit.Assert;
import org.junit.Test;
/**
* 季度测试
*
* @author 6tail
*/
public class SeasonTest {
@Test
public void test(){
SolarSeason season = new SolarSeason(2019,5);
Assert.assertEquals("2019.2",season.toString());
Assert.assertEquals("2019年2季度",season.toFullString());
Assert.assertEquals("2019.3",season.next(1).toString());
Assert.assertEquals("2019年3季度",season.next(1).toFullString());
}
}

View File

@@ -0,0 +1,23 @@
package test;
import com.nlf.calendar.Solar;
import org.junit.Assert;
import org.junit.Test;
/**
* 阳历测试
*
* @author 6tail
*/
public class SolarTest {
@Test
public void test(){
Solar date = new Solar(2019,5,1);
Assert.assertEquals("2019-05-01",date.toString());
Assert.assertEquals("2019-05-01 星期三 (劳动节) 金牛座",date.toFullString());
Assert.assertEquals("己亥年叁月廿七",date.getLunar().toString());
Assert.assertEquals("己亥年叁月廿七 猪年 西方白虎 娄金狗",date.getLunar().toFullString());
}
}

View File

@@ -0,0 +1,44 @@
package test;
import com.nlf.calendar.SolarWeek;
import com.nlf.calendar.util.SolarUtil;
import org.junit.Assert;
import org.junit.Test;
/**
* 周测试
*
* @author 6tail
*/
public class WeekTest {
@Test
public void testFromMonday(){
//一周的开始从星期一开始计
int start = 1;
SolarWeek week = new SolarWeek(2019,5,1,start);
Assert.assertEquals("2019.5.1",week.toString());
Assert.assertEquals("2019年5月第1周",week.toFullString());
//当月共几周
Assert.assertEquals(5,SolarUtil.getWeeksOfMonth(week.getYear(),week.getMonth(),start));
//当周第一天
Assert.assertEquals("2019-04-29",week.getFirstDay().toString());
//当周第一天(本月)
Assert.assertEquals("2019-05-01",week.getFirstDayInMonth().toString());
}
@Test
public void testFromSunday(){
//一周的开始从星期日开始计
int start = 0;
SolarWeek week = new SolarWeek(2019,5,1,start);
Assert.assertEquals("2019.5.1",week.toString());
Assert.assertEquals("2019年5月第1周",week.toFullString());
//当月共几周
Assert.assertEquals(5,SolarUtil.getWeeksOfMonth(week.getYear(),week.getMonth(),start));
//当周第一天
Assert.assertEquals("2019-04-28",week.getFirstDay().toString());
//当周第一天(本月)
Assert.assertEquals("2019-05-01",week.getFirstDayInMonth().toString());
}
}

View File

@@ -0,0 +1,24 @@
package test;
import com.nlf.calendar.SolarYear;
import org.junit.Assert;
import org.junit.Test;
/**
* 年份测试
*
* @author 6tail
*/
public class YearTest {
@Test
public void test(){
SolarYear year = new SolarYear(2019);
Assert.assertEquals("2019",year.toString());
Assert.assertEquals("2019年",year.toFullString());
Assert.assertEquals("2020",year.next(1).toString());
Assert.assertEquals("2020年",year.next(1).toFullString());
}
}