1
0
mirror of synced 2026-10-18 04:26:12 +08:00

Initial commit

This commit is contained in:
6tail
2018-06-23 16:41:40 +08:00
commit 6db19410ea
21 changed files with 2151 additions and 0 deletions

View File

@@ -0,0 +1,336 @@
package com.nlf.calendar;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date;
import java.util.List;
import com.nlf.calendar.util.LunarUtil;
import com.nlf.calendar.util.SolarUtil;
/**
* 农历日期
*
* @author 6tail
*
*/
public class Lunar{
/** 农历年 */
private int year;
/** 农历月,闰月为负,即闰2月=-2 */
private int month;
/** 农历日 */
private int day;
/** 对应阳历 */
private Solar solar;
/**
* 默认使用当前日期初始化
*/
public Lunar(){
this(new Date());
}
/**
* 通过农历年月日初始化
*
* @param year 年
* @param month 月
* @param day 日
*/
public Lunar(int year,int month,int day){
this.year = year;
this.month = month;
this.day = day;
this.solar = toSolar();
}
/**
* 通过日期初始化
* @param date 日期
*/
public Lunar(Date date){
solar = new Solar(date);
int y = solar.getYear();
int m = solar.getMonth();
int d = solar.getDay();
int startY,startM,startD;
int lunarY,lunarM,lunarD;
if(y<2000){
startY = SolarUtil.BASE_YEAR;
startM = SolarUtil.BASE_MONTH;
startD = SolarUtil.BASE_DAY;
lunarY = LunarUtil.BASE_YEAR;
lunarM = LunarUtil.BASE_MONTH;
lunarD = LunarUtil.BASE_DAY;
}else{
startY = SolarUtil.BASE_YEAR+99;
startM = 1;
startD = 1;
lunarY = LunarUtil.BASE_YEAR+99;
lunarM = 11;
lunarD = 25;
}
int diff = 0;
for(int i=startY;i<y;i++){
diff += 365;
if(SolarUtil.isLeapYear(i)) diff += 1;
}
for(int i=startM;i<m;i++){
diff += SolarUtil.getDaysOfMonth(y,i);
}
diff += d-startD;
lunarD += diff;
int lastDate = LunarUtil.getDaysOfMonth(lunarY,lunarM);
while(lunarD>lastDate){
lunarD -= lastDate;
lunarM = LunarUtil.nextMonth(lunarY,lunarM);
if(lunarM==1) lunarY++;
lastDate = LunarUtil.getDaysOfMonth(lunarY,lunarM);
}
year = lunarY;
month = lunarM;
day = lunarD;
}
/**
* 获取干
*
* @return 干,如辛
*/
public String getGan(){
return LunarUtil.GAN[(year-4)%10+1];
}
/**
* 获取支
*
* @return 支,如亥
*/
public String getZhi(){
return LunarUtil.ZHI[(year-4)%12+1];
}
/**
* 获取生肖
*
* @return 生肖,如虎
*/
public String getShengxiao(){
return LunarUtil.SHENGXIAO[(year-4)%12+1];
}
/**
* 获取中文的月
*
* @return 中文月,如正月
*/
public String getMonthInChinese(){
if(month>0) return LunarUtil.MONTH[month];
else return "闰"+LunarUtil.MONTH[-month];
}
/**
* 获取季节
* @return 农历季节
*/
public String getSeason(){
return LunarUtil.SEASON[Math.abs(month)];
}
/**
* 获取中文日
*
* @return 中文日,如初一
*/
public String getDayInChinese(){
return LunarUtil.DAY[day];
}
/**
* 获取节
*
* @return 节
*/
public String getJie(){
String s = "";
int solarYear = solar.getYear();
int solarMonth = solar.getMonth();
int solarDay = solar.getDay();
int index = 0;
int ry = solarYear-SolarUtil.BASE_YEAR+1;
while(ry>=LunarUtil.JIE_YEAR[solarMonth-1][index]){
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];
return s;
}
/**
* 获取气
*
* @return 气
*/
public String getQi(){
String s = "";
int solarYear = solar.getYear();
int solarMonth = solar.getMonth();
int solarDay = solar.getDay();
int index = 0;
int ry = solarYear-SolarUtil.BASE_YEAR+1;
while(ry>=LunarUtil.QI_YEAR[solarMonth-1][index]){
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];
return s;
}
/**
* 获取宿
*
* @return 宿
*/
public String getXiu(){
return LunarUtil.XIU[day-1][month-1];
}
/**
* 获取政
*
* @return 政
*/
public String getZheng(){
return LunarUtil.ZHENG.get(getXiu());
}
/**
* 获取动物
* @return 动物
*/
public String getAnimal(){
return LunarUtil.ANIMAL.get(getXiu());
}
/**
* 获取宫
* @return 宫
*/
public String getGong(){
return LunarUtil.GONG.get(getXiu());
}
/**
* 获取兽
* @return 兽
*/
public String getShou(){
return LunarUtil.SHOU.get(getGong());
}
/**
* 获取节日,有可能一天会有多个节日
*
* @return 春节等
*/
public List<String> getFestivals(){
List<String> l = new ArrayList<String>();
String f = LunarUtil.FESTIVAL.get(month+"-"+day);
if(null!=f) l.add(f);
return l;
}
/**
* 转换为阳历日期
*
* @return 阳历日期
*/
private Solar toSolar(){
int y = LunarUtil.BASE_YEAR;
int m = LunarUtil.BASE_MONTH;
int d = LunarUtil.BASE_DAY;
int diff = LunarUtil.getDaysOfMonth(y,m)-d;
m = LunarUtil.nextMonth(y,m);
while(true){
diff += LunarUtil.getDaysOfMonth(y,m);
m = LunarUtil.nextMonth(y,m);
if(m==1) y++;
if(y==year&&m==month){
diff += day;
break;
}
}
Calendar c = Calendar.getInstance();
c.set(SolarUtil.BASE_YEAR,SolarUtil.BASE_MONTH-1,SolarUtil.BASE_DAY);
c.add(Calendar.DATE,diff);
return new Solar(c);
}
public String toFullString(){
StringBuilder s = new StringBuilder();
s.append(toString());
s.append(" ");
s.append(getShengxiao());
s.append("年");
for(String f:getFestivals()){
s.append(" (");
s.append(f);
s.append(")");
}
String jq = getJie()+getQi();
if(jq.length()>0){
s.append(" [");
s.append(jq);
s.append("]");
}
s.append(" ");
s.append(getGong());
s.append("方");
s.append(getShou());
s.append(" ");
s.append(getXiu());
s.append(getZheng());
s.append(getAnimal());
return s.toString();
}
public String toString(){
return getGan()+getZhi()+"年"+getMonthInChinese()+"月"+getDayInChinese();
}
/**
* 获取年份
*
* @return 如2015
*/
public int getYear(){
return year;
}
/**
* 获取月份
*
* @return 1到12,负数为闰月
*/
public int getMonth(){
return month;
}
/**
* 获取日期
*
* @return 日期
*/
public int getDay(){
return day;
}
public Solar getSolar(){
return solar;
}
}

View File

@@ -0,0 +1,224 @@
package com.nlf.calendar;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date;
import java.util.List;
import com.nlf.calendar.util.SolarUtil;
/**
* 阳历日期
*
* @author 6tail
*
*/
public class Solar{
/** 年 */
private int year;
/** 月 */
private int month;
/** 日 */
private int day;
/** 日历 */
private Calendar calendar;
/**
* 默认使用当前日期初始化
*/
public Solar(){
this(new Date());
}
/**
* 通过年月日初始化
*
* @param year 年
* @param month 月,1到12
* @param day 日,1到31
*/
public Solar(int year,int month,int day){
calendar = Calendar.getInstance();
calendar.set(year,month-1,day);
this.year = year;
this.month = month;
this.day = day;
}
/**
* 通过日期初始化
*
* @param date 日期
*/
public Solar(Date date){
calendar = Calendar.getInstance();
calendar.setTime(date);
year = calendar.get(Calendar.YEAR);
month = calendar.get(Calendar.MONTH)+1;
day = calendar.get(Calendar.DATE);
}
/**
* 通过日历初始化
*
* @param calendar 日历
*/
public Solar(Calendar calendar){
this.calendar = calendar;
year = calendar.get(Calendar.YEAR);
month = calendar.get(Calendar.MONTH)+1;
day = calendar.get(Calendar.DATE);
}
/**
* 是否闰年
*
* @return true/false 闰年/非闰年
*/
public boolean isLeapYear(){
return SolarUtil.isLeapYear(year);
}
/**
* 获取星期,0代表周日,1代表周一
*
* @return 0123456
*/
public int getWeek(){
return calendar.get(Calendar.DAY_OF_WEEK)-1;
}
/**
* 获取星期的中文
*
* @return 日一二三四五六
*/
public String getWeekInChinese(){
return SolarUtil.WEEK[getWeek()];
}
/**
* 获取节日,有可能一天会有多个节日
*
* @return 劳动节等
*/
public List<String> getFestivals(){
List<String> l = new ArrayList<String>();
//获取几月几日对应的节日
String f = SolarUtil.FESTIVAL.get(month+"-"+day);
if(null!=f) l.add(f);
//计算几月第几个星期几对应的节日
//第几周
int weekInMonth = calendar.get(Calendar.WEEK_OF_MONTH);
//星期几,0代表星期天
int week = getWeek();
//星期天很奇葩,会多算一周,需要减掉
if(0==week) weekInMonth--;
f = SolarUtil.WEEK_FESTIVAL.get(month+"-"+weekInMonth+"-"+week);
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;
return SolarUtil.XINGZUO[index];
}
/**
* 获取年份
*
* @return 如2015
*/
public int getYear(){
return year;
}
/**
* 获取月份
*
* @return 1到12
*/
public int getMonth(){
return month;
}
/**
* 获取日期
*
* @return 1到31之间的数字
*/
public int getDay(){
return day;
}
/**
* 获取农历
* @return 农历
*/
public Lunar getLunar(){
return new Lunar(calendar.getTime());
}
/**
* 获取日历
*
* @return 日历
*/
public Calendar getCalendar(){
return calendar;
}
public String toString(){
return year+"-"+(month<10?"0":"")+month+"-"+(day<10?"0":"")+day;
}
public String toFullString(){
StringBuilder s = new StringBuilder();
s.append(toString());
if(isLeapYear()){
s.append(" ");
s.append("闰年");
}
s.append(" ");
s.append("星期");
s.append(getWeekInChinese());
for(String f:getFestivals()){
s.append(" (");
s.append(f);
s.append(")");
}
s.append(" ");
s.append(getXingzuo());
s.append("座");
return s.toString();
}
/**
* 获取往后推几天的阳历日期,如果要往前推,则天数用负数
* @param days 天数
* @return 阳历日期
*/
public Solar next(int days){
Calendar c = Calendar.getInstance();
c.set(year,month-1,day);
c.add(Calendar.DATE,days);
return new Solar(c);
}
}

View File

@@ -0,0 +1,114 @@
package com.nlf.calendar;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date;
import java.util.List;
/**
* 阳历半年
*/
public class SolarHalfYear {
/** 年 */
private int year;
/** 月 */
private int month;
/**
* 默认当月
*/
public SolarHalfYear(){
this(new Date());
}
/**
* 通过日期初始化
*/
public SolarHalfYear(Date date){
Calendar c = Calendar.getInstance();
c.setTime(date);
year = c.get(Calendar.YEAR);
month = c.get(Calendar.MONTH)+1;
}
/**
* 通过日历初始化
*/
public SolarHalfYear(Calendar calendar){
year = calendar.get(Calendar.YEAR);
month = calendar.get(Calendar.MONTH)+1;
}
/**
* 通过年月初始化
*
* @param year 年
* @param month 月
*/
public SolarHalfYear(int year,int month){
this.year = year;
this.month = month;
}
/**
* 获取年
*
* @return 年
*/
public int getYear(){
return year;
}
/**
* 获取月
*
* @return 月
*/
public int getMonth(){
return month;
}
/**
* 获取当月是第几半年
* @return 半年序号,从1开始
*/
public int getIndex(){
return (int)Math.ceil(month/6D);
}
/**
* 半年推移
* @param halfYears 推移的半年数,负数为倒推
* @return 推移后的半年
*/
public SolarHalfYear next(int halfYears){
if(0==halfYears){
return new SolarHalfYear(year,month);
}
Calendar c = Calendar.getInstance();
c.set(year,month-1,1);
c.add(Calendar.MONTH,6*halfYears);
return new SolarHalfYear(c);
}
/**
* 获取本半年的月份
* @return 本半年的月份列表
*/
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));
}
return l;
}
public String toString(){
return year+"."+getIndex();
}
public String toFullString(){
return year+"年"+(getIndex()==1?"上":"下")+"半年";
}
}

View File

@@ -0,0 +1,110 @@
package com.nlf.calendar;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date;
import java.util.List;
import com.nlf.calendar.util.SolarUtil;
/**
* 阳历月
*
* @author 6tail
*
*/
public class SolarMonth{
/** 年 */
private int year;
/** 月 */
private int month;
/**
* 默认当月
*/
public SolarMonth(){
this(new Date());
}
/**
* 通过日期初始化
*/
public SolarMonth(Date date){
Calendar c = Calendar.getInstance();
c.setTime(date);
year = c.get(Calendar.YEAR);
month = c.get(Calendar.MONTH)+1;
}
/**
* 通过日历初始化
*/
public SolarMonth(Calendar calendar){
year = calendar.get(Calendar.YEAR);
month = calendar.get(Calendar.MONTH)+1;
}
/**
* 通过年月初始化
*
* @param year 年
* @param month 月
*/
public SolarMonth(int year,int month){
this.year = year;
this.month = month;
}
/**
* 获取年
*
* @return 年
*/
public int getYear(){
return year;
}
/**
* 获取月
*
* @return 月
*/
public int getMonth(){
return month;
}
/**
* 获取本月的阳历日期列表
*
* @return 阳历日期列表
*/
public List<Solar> getDays(){
List<Solar> l = new ArrayList<Solar>(31);
Solar d = new Solar(year,month,1);
l.add(d);
int days = SolarUtil.getDaysOfMonth(year,month);
for(int i = 1;i<days;i++){
l.add(d.next(i));
}
return l;
}
/**
* 获取往后推几个月的阳历月,如果要往前推,则月数用负数
* @param months 月数
* @return 阳历月
*/
public SolarMonth next(int months){
Calendar c = Calendar.getInstance();
c.set(year,month-1,1);
c.add(Calendar.MONTH,months);
return new SolarMonth(c);
}
public String toString(){
return year+"-"+month;
}
public String toFullString(){
return year+"年"+month+"月";
}
}

View File

@@ -0,0 +1,114 @@
package com.nlf.calendar;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date;
import java.util.List;
/**
* 阳历季度
*/
public class SolarSeason {
/** 年 */
private int year;
/** 月 */
private int month;
/**
* 默认当月
*/
public SolarSeason(){
this(new Date());
}
/**
* 通过日期初始化
*/
public SolarSeason(Date date){
Calendar c = Calendar.getInstance();
c.setTime(date);
year = c.get(Calendar.YEAR);
month = c.get(Calendar.MONTH)+1;
}
/**
* 通过日历初始化
*/
public SolarSeason(Calendar calendar){
year = calendar.get(Calendar.YEAR);
month = calendar.get(Calendar.MONTH)+1;
}
/**
* 通过年月初始化
*
* @param year 年
* @param month 月
*/
public SolarSeason(int year, int month){
this.year = year;
this.month = month;
}
/**
* 获取年
*
* @return 年
*/
public int getYear(){
return year;
}
/**
* 获取月
*
* @return 月
*/
public int getMonth(){
return month;
}
/**
* 获取当月是第几季度
* @return 季度序号,从1开始
*/
public int getIndex(){
return (int)Math.ceil(month/3D);
}
/**
* 季度推移
* @param seasons 推移的季度数,负数为倒推
* @return 推移后的季度
*/
public SolarSeason next(int seasons){
if(0==seasons){
return new SolarSeason(year,month);
}
Calendar c = Calendar.getInstance();
c.set(year,month-1,1);
c.add(Calendar.MONTH,3*seasons);
return new SolarSeason(c);
}
/**
* 获取本季度的月份
* @return 本季度的月份列表
*/
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));
}
return l;
}
public String toString(){
return year+"."+getIndex();
}
public String toFullString(){
return year+"年"+getIndex()+"季度";
}
}

View File

@@ -0,0 +1,241 @@
package com.nlf.calendar;
import com.nlf.calendar.util.SolarUtil;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date;
import java.util.List;
/**
* 阳历周
*/
public class SolarWeek {
/** 年 */
private int year;
/** 月 */
private int month;
/** 日 */
private int day;
/** 星期几作为一周的开始,1234560分别代表星期一至星期天 */
private int start;
/**
* 默认当月
* @param start 星期几作为一周的开始,1234560分别代表星期一至星期天
*/
public SolarWeek(int start){
this(new Date(),start);
}
/**
* 通过日期初始化
* @param start 星期几作为一周的开始,1234560分别代表星期一至星期天
*/
public SolarWeek(Date date,int start){
Calendar c = Calendar.getInstance();
c.setTime(date);
year = c.get(Calendar.YEAR);
month = c.get(Calendar.MONTH)+1;
day = c.get(Calendar.DATE);
this.start = start;
}
/**
* 通过日历初始化
* @param start 星期几作为一周的开始,1234560分别代表星期一至星期天
*/
public SolarWeek(Calendar calendar,int start){
year = calendar.get(Calendar.YEAR);
month = calendar.get(Calendar.MONTH)+1;
day = calendar.get(Calendar.DATE);
this.start = start;
}
/**
* 通过年月初始化
*
* @param year 年
* @param month 月,1到12
* @param day 日,1到31
* @param start 星期几作为一周的开始,1234560分别代表星期一至星期天
*/
public SolarWeek(int year, int month ,int day,int start){
this.year = year;
this.month = month;
this.day = day;
this.start = start;
}
/**
* 获取年
*
* @return 年
*/
public int getYear(){
return year;
}
/**
* 获取月
*
* @return 1到12
*/
public int getMonth(){
return month;
}
/**
* 获取日期
*
* @return 1到31之间的数字
*/
public int getDay(){
return day;
}
/**
* 获取星期几作为一周的开始,1234560分别代表星期一至星期天
*
* @return 1234560分别代表星期一至星期天
*/
public int getStart(){
return start;
}
/**
* 获取当前日期是在当月第几周
* @return 周序号,从1开始
*/
public int getIndex(){
Calendar c = Calendar.getInstance();
c.set(year,month-1,1);
int firstDayWeek = c.get(Calendar.DAY_OF_WEEK)-1;
return (int)Math.ceil((day+firstDayWeek-start)/7D);
}
/**
* 周推移
* @param weeks 推移的周数,负数为倒推
* @param separateMonth 是否按月单独计算
* @return 推移后的阳历周
*/
public SolarWeek next(int weeks,boolean separateMonth){
if(0==weeks){
return new SolarWeek(year,month,day,start);
}
if(separateMonth){
int n = weeks;
Calendar c = Calendar.getInstance();
c.set(year,month-1,day);
SolarWeek week = new SolarWeek(c,start);
int month = this.month;
boolean plus = n>0;
while(0!=n){
c.add(Calendar.DATE,plus?7:-7);
week = new SolarWeek(c,start);
int weekMonth = week.getMonth();
if(month!=weekMonth){
int index = week.getIndex();
if(plus){
if(1==index){
Solar firstDay = week.getFirstDay();
week = new SolarWeek(firstDay.getYear(),firstDay.getMonth(),firstDay.getDay(),start);
weekMonth = week.getMonth();
}else{
c.set(week.getYear(),week.getMonth()-1,1);
week = new SolarWeek(c,start);
}
}else{
int size = SolarUtil.getWeeksOfMonth(week.getYear(),week.getMonth(),start);
if(size==index){
Solar firstDay = week.getFirstDay();
Solar lastDay = firstDay.next(6);
week = new SolarWeek(lastDay.getYear(),lastDay.getMonth(),lastDay.getDay(),start);
weekMonth = week.getMonth();
}else{
c.set(week.getYear(),week.getMonth()-1,SolarUtil.getDaysOfMonth(week.getYear(),week.getMonth()));
week = new SolarWeek(c,start);
}
}
month = weekMonth;
}
n-=plus?1:-1;
}
return week;
}else{
Calendar c = Calendar.getInstance();
c.set(year,month-1,day);
c.add(Calendar.DATE,weeks*7);
return new SolarWeek(c,start);
}
}
/**
* 获取本周第一天的阳历日期(可能跨月)
* @return 本周第一天的阳历日期
*/
public Solar getFirstDay(){
Calendar c = Calendar.getInstance();
c.set(year,month-1,day);
int week = c.get(Calendar.DAY_OF_WEEK)-1;
int prev = week - start;
if(prev<0){
prev += 7;
}
c.add(Calendar.DATE,-prev);
return new Solar(c);
}
/**
* 获取本周第一天的阳历日期(仅限当月)
* @return 本周第一天的阳历日期
*/
public Solar getFirstDayInMonth(){
List<Solar> days = getDays();
for(Solar day:days){
if(month==day.getMonth()){
return day;
}
}
return null;
}
/**
* 获取本周的阳历日期列表(可能跨月)
* @return 本周的阳历日期列表
*/
public List<Solar> getDays(){
Solar firstDay = getFirstDay();
List<Solar> l = new ArrayList<Solar>();
l.add(firstDay);
for(int i = 1;i<7;i++){
l.add(firstDay.next(i));
}
return l;
}
/**
* 获取本周的阳历日期列表(仅限当月)
* @return 本周的阳历日期列表(仅限当月)
*/
public List<Solar> getDaysInMonth(){
List<Solar> days = this.getDays();
List<Solar> l = new ArrayList<Solar>();
for(Solar day:days){
if(month!=day.getMonth()){
continue;
}
l.add(day);
}
return l;
}
public String toString(){
return year+"."+month+"."+getIndex();
}
public String toFullString(){
return year+"年"+month+"月第"+getIndex()+"周";
}
}

View File

@@ -0,0 +1,93 @@
package com.nlf.calendar;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date;
import java.util.List;
/**
* 阳历年
*
* @author 6tail
*
*/
public class SolarYear{
/** 年 */
private int year;
/**
* 默认当年
*/
public SolarYear(){
this(new Date());
}
/**
* 通过日期初始化
*/
public SolarYear(Date date){
Calendar c = Calendar.getInstance();
c.setTime(date);
year = c.get(Calendar.YEAR);
}
/**
* 通过日历初始化
*/
public SolarYear(Calendar calendar){
year = calendar.get(Calendar.YEAR);
}
/**
* 通过年
*
* @param year 年
*/
public SolarYear(int year){
this.year = year;
}
/**
* 获取年
*
* @return 年
*/
public int getYear(){
return year;
}
/**
* 获取本年的阳历月列表
*
* @return 阳历月列表
*/
public List<SolarMonth> getMonths(){
List<SolarMonth> l = new ArrayList<SolarMonth>(12);
SolarMonth m = new SolarMonth(year,1);
l.add(m);
for(int i = 1;i<12;i++){
l.add(m.next(i));
}
return l;
}
/**
* 获取往后推几年的阳历年,如果要往前推,则年数用负数
* @param years 年数
* @return 阳历年
*/
public SolarYear next(int years){
Calendar c = Calendar.getInstance();
c.set(year,0,1);
c.add(Calendar.YEAR,years);
return new SolarYear(c);
}
public String toString(){
return year+"";
}
public String toFullString(){
return year+"年";
}
}

View File

@@ -0,0 +1,265 @@
package com.nlf.calendar.util;
import java.util.HashMap;
import java.util.Map;
/**
* 农历工具
*
* @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[] LEAP_MONTH_YEAR = {6,14,19,25,33,36,38,41,44,52,55,79,117,136,147,150,155,158,185,193};
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 int[][] JIE_YEAR = {{13,49,85,117,149,185,201,250,250},{13,45,81,117,149,185,201,250,250},{13,48,84,112,148,184,200,201,250},{13,45,76,108,140,172,200,201,250},{13,44,72,104,132,168,200,201,250},{5,33,68,96,124,152,188,200,201},{29,57,85,120,148,176,200,201,250},{13,48,76,104,132,168,196,200,201},{25,60,88,120,148,184,200,201,250},{16,44,76,108,144,172,200,201,250},{28,60,92,124,160,192,200,201,250},{17,53,85,124,156,188,200,201,250}};
public static final int[][] JIE_MAP = {{7,6,6,6,6,6,6,6,6,5,6,6,6,5,5,6,6,5,5,5,5,5,5,5,5,4,5,5},{5,4,5,5,5,4,4,5,5,4,4,4,4,4,4,4,4,3,4,4,4,3,3,4,4,3,3,3},{6,6,6,7,6,6,6,6,5,6,6,6,5,5,6,6,5,5,5,6,5,5,5,5,4,5,5,5,5},{5,5,6,6,5,5,5,6,5,5,5,5,4,5,5,5,4,4,5,5,4,4,4,5,4,4,4,4,5},{6,6,6,7,6,6,6,6,5,6,6,6,5,5,6,6,5,5,5,6,5,5,5,5,4,5,5,5,5},{6,6,7,7,6,6,6,7,6,6,6,6,5,6,6,6,5,5,6,6,5,5,5,6,5,5,5,5,4,5,5,5,5},{7,8,8,8,7,7,8,8,7,7,7,8,7,7,7,7,6,7,7,7,6,6,7,7,6,6,6,7,7},{8,8,8,9,8,8,8,8,7,8,8,8,7,7,8,8,7,7,7,8,7,7,7,7,6,7,7,7,6,6,7,7,7},{8,8,8,9,8,8,8,8,7,8,8,8,7,7,8,8,7,7,7,8,7,7,7,7,6,7,7,7,7},{9,9,9,9,8,9,9,9,8,8,9,9,8,8,8,9,8,8,8,8,7,8,8,8,7,7,8,8,8},{8,8,8,8,7,8,8,8,7,7,8,8,7,7,7,8,7,7,7,7,6,7,7,7,6,6,7,7,7},{7,8,8,8,7,7,8,8,7,7,7,8,7,7,7,7,6,7,7,7,6,6,7,7,6,6,6,7,7}};
public static final int[][] QI_YEAR = {{13,45,81,113,149,185,201},{21,57,93,125,161,193,201},{21,56,88,120,152,188,200,201},{21,49,81,116,144,176,200,201},{17,49,77,112,140,168,200,201},{28,60,88,116,148,180,200,201},{25,53,84,112,144,172,200,201},{29,57,89,120,148,180,200,201},{17,45,73,108,140,168,200,201},{28,60,92,124,160,192,200,201},{16,44,80,112,148,180,200,201},{17,53,88,120,156,188,200,201}};
public static final int[][] QI_MAP = {{21,21,21,21,21,20,21,21,21,20,20,21,21,20,20,20,20,20,20,20,20,19,20,20,20,19,19,20},{20,19,19,20,20,19,19,19,19,19,19,19,19,18,19,19,19,18,18,19,19,18,18,18,18,18,18,18},{21,21,21,22,21,21,21,21,20,21,21,21,20,20,21,21,20,20,20,21,20,20,20,20,19,20,20,20,20},{20,21,21,21,20,20,21,21,20,20,20,21,20,20,20,20,19,20,20,20,19,19,20,20,19,19,19,20,20},{21,22,22,22,21,21,22,22,21,21,21,22,21,21,21,21,20,21,21,21,20,20,21,21,20,20,20,21,21},{22,22,22,22,21,22,22,22,21,21,22,22,21,21,21,22,21,21,21,21,20,21,21,21,20,20,21,21,21},{23,23,24,24,23,23,23,24,23,23,23,23,22,23,23,23,22,22,23,23,22,22,22,23,22,22,22,22,23},{23,24,24,24,23,23,24,24,23,23,23,24,23,23,23,23,22,23,23,23,22,22,23,23,22,22,22,23,23},{23,24,24,24,23,23,24,24,23,23,23,24,23,23,23,23,22,23,23,23,22,22,23,23,22,22,22,23,23},{24,24,24,24,23,24,24,24,23,23,24,24,23,23,23,24,23,23,23,23,22,23,23,23,22,22,23,23,23},{23,23,23,23,22,23,23,23,22,22,23,23,22,22,22,23,22,22,22,22,21,22,22,22,21,21,22,22,22},{22,22,23,23,22,22,22,23,22,22,22,22,21,22,22,22,21,21,22,22,21,21,21,22,21,21,21,21,22}};
/** 干 */
public static final String[] GAN = {"","甲","乙","丙","丁","戊","己","庚","辛","壬","癸"};
/** 支 */
public static final String[] ZHI = {"","子","丑","寅","卯","辰","巳","午","未","申","酉","戌","亥"};
/** 月 */
public static final String[] MONTH = {"","正","贰","叁","肆","伍","陆","柒","捌","玖","拾","冬","腊"};
/** 季节 */
public static final String[] SEASON = {"","孟春","仲春","季春","孟夏","仲夏","季夏","孟秋","仲秋","季秋","孟冬","仲冬","季冬"};
/** 生肖 */
public static final String[] SHENGXIAO = {"","鼠","牛","虎","兔","龙","蛇","马","羊","猴","鸡","狗","猪"};
/** 气 */
public static final String[] QI = {"大寒","雨水","春分","谷雨","夏满","夏至","大暑","处暑","秋分","霜降","小雪","冬至"};
/** 节 */
public static final String[] JIE = {"小寒","立春","惊蛰","清明","立夏","芒种","小暑","立秋","白露","寒露","立冬","大雪"};
/** 日 */
public static final String[] DAY = {"","初一","初二","初三","初四","初五","初六","初七","初八","初九","初十","十一","十二","十三","十四","十五","十六","十七","十八","十九","二十","廿一","廿二","廿三","廿四","廿五","廿六","廿七","廿八","廿九","三十"};
/** 农历日期对应的节日 */
public static final Map<String,String> FESTIVAL = new HashMap<String,String>(){
private static final long serialVersionUID = -1;
{
put("1-1","春节");
put("1-15","元宵节");
put("2-2","龙头节");
put("5-5","端午节");
put("7-7","七夕节");
put("8-15","中秋节");
put("9-9","重阳节");
put("12-8","腊八节");
}
};
/** 宿 */
public static final String[][] XIU = {
{"室","奎","胃","毕","参","鬼","张","角","氐","心","斗","虚"},
{"壁","娄","昴","觜","井","柳","翼","亢","房","尾","女","危"},
{"奎","胃","毕","参","鬼","星","轸","氐","心","箕","虚","室"},
{"娄","昴","觜","井","柳","张","角","房","尾","斗","危","壁"},
{"胃","毕","参","鬼","星","翼","亢","心","箕","女","室","奎"},
{"昴","觜","井","柳","张","轸","氐","尾","斗","虚","壁","娄"},
{"毕","参","鬼","星","翼","角","房","箕","女","危","奎","胃"},
{"觜","井","柳","张","轸","亢","心","斗","虚","室","娄","昴"},
{"参","鬼","星","翼","角","氐","尾","女","危","壁","胃","毕"},
{"井","柳","张","轸","亢","房","箕","虚","室","奎","昴","觜"},
{"鬼","星","翼","角","氐","心","斗","危","壁","娄","毕","参"},
{"柳","张","轸","亢","房","尾","女","室","奎","胃","觜","井"},
{"星","翼","角","氐","心","箕","虚","壁","娄","昴","参","鬼"},
{"张","轸","亢","房","尾","斗","危","奎","胃","毕","井","柳"},
{"翼","角","氐","心","箕","女","室","娄","昴","觜","鬼","星"},
{"轸","亢","房","尾","斗","虚","壁","胃","毕","参","柳","张"},
{"角","氐","心","箕","女","危","奎","昴","觜","井","星","翼"},
{"亢","房","尾","斗","虚","室","娄","毕","参","鬼","张","轸"},
{"氐","心","箕","女","危","壁","胃","觜","井","柳","翼","角"},
{"房","尾","斗","虚","室","奎","昴","参","鬼","星","轸","亢"},
{"心","箕","女","危","壁","娄","毕","井","柳","张","角","氐"},
{"尾","斗","虚","室","奎","胃","觜","鬼","星","翼","亢","房"},
{"箕","女","危","壁","娄","昴","参","柳","张","轸","氐","心"},
{"斗","虚","室","奎","胃","毕","井","星","翼","角","房","尾"},
{"女","危","壁","娄","昴","觜","鬼","张","轸","亢","心","箕"},
{"虚","室","奎","胃","毕","参","柳","翼","角","氐","尾","斗"},
{"危","壁","娄","昴","觜","井","星","轸","亢","房","箕","女"},
{"室","奎","胃","毕","参","鬼","张","角","氐","心","斗","虚"},
{"壁","娄","昴","觜","井","柳","翼","亢","房","尾","女","危"},
{"胃","鬼","氐","心","虚","星","轸","氐","心","箕","虚","室"}
};
/** 兽 */
public static final Map<String,String> SHOU = new HashMap<String,String>(){
private static final long serialVersionUID = -1;
{
put("东","青龙");
put("南","朱雀");
put("西","白虎");
put("北","玄武");
}
};
/** 宫 */
public static final Map<String,String> GONG = new HashMap<String,String>(){
private static final long serialVersionUID = -1;
{
put("角","东");
put("井","南");
put("奎","西");
put("斗","北");
put("亢","东");
put("鬼","南");
put("娄","西");
put("牛","北");
put("氐","南");
put("柳","南");
put("胃","西");
put("女","北");
put("房","东");
put("星","南");
put("昴","西");
put("虚","北");
put("心","东");
put("张","南");
put("毕","西");
put("危","北");
put("尾","东");
put("翼","南");
put("觜","西");
put("室","北");
put("箕","东");
put("轸","南");
put("参","西");
put("壁","北");
}
};
/** 政 */
public static final Map<String,String> ZHENG = new HashMap<String,String>(){
private static final long serialVersionUID = -1;
{
put("角","木");
put("井","木");
put("奎","木");
put("斗","木");
put("亢","金");
put("鬼","金");
put("娄","金");
put("牛","金");
put("氐","土");
put("柳","土");
put("胃","土");
put("女","土");
put("房","日");
put("星","日");
put("昴","日");
put("虚","日");
put("心","月");
put("张","月");
put("毕","月");
put("危","月");
put("尾","火");
put("翼","火");
put("觜","火");
put("室","火");
put("箕","水");
put("轸","水");
put("参","水");
put("壁","水");
}
};
/** 动物 */
public static final Map<String,String> ANIMAL = new HashMap<String,String>(){
private static final long serialVersionUID = -1;
{
put("角","蛟");
put("斗","獬");
put("奎","狼");
put("井","犴");
put("亢","龙");
put("牛","牛");
put("娄","狗");
put("鬼","羊");
put("女","蝠");
put("氐","貉");
put("胃","彘");
put("柳","獐");
put("房","兔");
put("虚","鼠");
put("昴","鸡");
put("星","马");
put("心","狐");
put("危","燕");
put("毕","乌");
put("张","鹿");
put("尾","虎");
put("室","猪");
put("觜","猴");
put("翼","蛇");
put("箕","豹");
put("壁","獝");
put("参","猿");
put("轸","蚓");
}
};
protected LunarUtil(){}
/**
* 获取指定年月的下一个月是第几月
* @param y 年
* @param m 月
* @return 1到12,闰月为负
*/
public static int nextMonth(int y,int m){
int n = Math.abs(m)+1;
if(m>0){
int index = y-LunarUtil.BASE_YEAR+LunarUtil.BASE_INDEX;
int v = LunarUtil.LUNAR_MONTH[2*index+1];
v = (v>>4)&0x0F;
if(v==m){
n = -m;
}
}
if(n==13) n = 1;
return n;
}
/**
* 获取某年某月有多少天
*
* @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){
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;
}
}

View File

@@ -0,0 +1,104 @@
package com.nlf.calendar.util;
import java.util.Calendar;
import java.util.HashMap;
import java.util.Map;
/**
* 阳历工具
* @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 = {"日","一","二","三","四","五","六"};
/** 每月天数 */
public static final int[] DAYS_OF_MONTH = {31,28,31,30,31,30,31,31,30,31,30,31};
/** 星座 */
public static final String[] XINGZUO = {"白羊","金牛","双子","巨蟹","狮子","处女","天秤","天蝎","射手","摩羯","水瓶","双鱼"};
/** 日期对应的节日 */
public static final Map<String,String> FESTIVAL = new HashMap<String,String>(){
private static final long serialVersionUID = -1;
{
put("1-1","元旦节");
put("2-14","情人节");
put("3-8","妇女节");
put("3-12","植树节");
put("3-15","消费者权益日");
put("4-1","愚人节");
put("5-1","劳动节");
put("5-4","青年节");
put("6-1","儿童节");
put("7-1","建党节");
put("8-1","建军节");
put("9-10","教师节");
put("10-1","国庆节");
put("12-24","平安夜");
put("12-25","圣诞节");
}
};
/** 几月第几个星期几对应的节日 */
public static final Map<String,String> WEEK_FESTIVAL = new HashMap<String,String>(){
private static final long serialVersionUID = -1;
{
put("5-2-0","母亲节");
put("6-3-0","父亲节");
put("11-4-4","感恩节");
}
};
protected 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;
return leap;
}
/**
* 获取某年某月有多少天
*
* @param year 年
* @param month 月
* @return 天数
*/
public static int getDaysOfMonth(int year,int month){
int m = month-1;
int d = DAYS_OF_MONTH[m];
//公历闰年2月多一天
if(m==Calendar.FEBRUARY&&isLeapYear(year)){
d++;
}
return d;
}
/**
* 获取某年某月有多少周
*
* @param year 年
* @param month 月
* @param start 星期几作为一周的开始,1234560分别代表星期一至星期天
* @return 周数
*/
public static int getWeeksOfMonth(int year,int month,int start){
int days = getDaysOfMonth(year,month);
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);
}
}