commit 6db19410ea2b096c906cd7972f4c37291e0ed525
Author: 6tail <6tail@6tail.cn>
Date: Sat Jun 23 16:41:40 2018 +0800
Initial commit
diff --git a/.gitignore b/.gitignore
new file mode 100644
index 0000000..e8ff194
--- /dev/null
+++ b/.gitignore
@@ -0,0 +1,16 @@
+*.class
+target/
+
+#idea
+.idea/
+/idea/
+*.ipr
+*.iml
+*.iws
+
+# temp file
+*.log
+*.cache
+*.diff
+*.patch
+*.tmp
\ No newline at end of file
diff --git a/LICENSE b/LICENSE
new file mode 100644
index 0000000..aef6bcb
--- /dev/null
+++ b/LICENSE
@@ -0,0 +1,21 @@
+MIT License
+
+Copyright (c) 2018 6tail
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in all
+copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+SOFTWARE.
\ No newline at end of file
diff --git a/README.md b/README.md
new file mode 100644
index 0000000..2d39950
--- /dev/null
+++ b/README.md
@@ -0,0 +1,87 @@
+# lunar [](https://github.com/6tail/nlf2/blob/master/LICENSE)
+
+lunar is a calendar library for Solar and Chinese Lunar.
+
+> Support since java 1.5
+
+[简体中文](https://github.com/6tail/lunar-java/blob/master/README_ZH.md)
+
+### Release
+
+```xml
+
+ cn.6tail
+ lunar
+ 1.0.0
+
+```
+
+### Snapshot
+
+```xml
+
+ sonatype
+ https://oss.sonatype.org/content/groups/public/
+
+ true
+ daily
+ warn
+
+
+```
+
+```xml
+
+ cn.6tail
+ lunar
+ 1.0.0-SNAPSHOT
+
+```
+
+### Download
+
+If you will use jars in your projects, I suggest you to download latest snapshot versions with less bugs.
+
+[Download](https://oss.sonatype.org/content/groups/public/cn/6tail/lunar/)
+
+## Example
+
+ import com.nlf.calendar.Lunar;
+
+ /**
+ * 阴历示例
+ *
+ */
+ public class LunarSample{
+ public static void main(String[] args){
+ //今天
+ Lunar date = new Lunar();
+ //输出阴历信息
+ System.out.println(date.toFullString());
+ //输出阳历信息
+ System.out.println(date.getSolar().toFullString());
+ System.out.println();
+ //指定阴历的某一天
+ date = new Lunar(1986,4,21);
+ System.out.println(date.toFullString());
+ System.out.println(date.getSolar().toFullString());
+ }
+ }
+
+Output:
+
+
+ 丙申年捌月初八 猴年 北方玄武 斗木獬
+ 2016-09-08 闰年 星期四 处女座
+
+ 丙寅年肆月廿一 虎年 北方玄武 危月燕
+ 1986-05-29 星期四 双子座
+
+## Documentation
+
+Please visit [http://6tail.cn/calendar/api.html](http://6tail.cn/calendar/api.html "http://6tail.cn/calendar/api.html")
+
+## Contact
+
+
+
diff --git a/README_ZH.md b/README_ZH.md
new file mode 100644
index 0000000..33a66a9
--- /dev/null
+++ b/README_ZH.md
@@ -0,0 +1,87 @@
+# lunar [](https://github.com/6tail/nlf2/blob/master/LICENSE)
+
+lunar是一个无依赖的支持阳历和阴历的日历工具库。
+
+> 支持java 1.5及以上版本。
+
+[English](https://github.com/6tail/lunar-java/blob/master/README.md)
+
+### 稳定版本
+
+```xml
+
+ cn.6tail
+ lunar
+ 1.0.0
+
+```
+
+### 快照版本
+
+```xml
+
+ sonatype
+ https://oss.sonatype.org/content/groups/public/
+
+ true
+ daily
+ warn
+
+
+```
+
+```xml
+
+ cn.6tail
+ lunar
+ 1.0.0-SNAPSHOT
+
+```
+
+### 下载jar
+
+如果使用jar,建议下载最新的SNAPSHOT版本,bug将得到及时的修复。
+
+[Download](https://oss.sonatype.org/content/groups/public/cn/6tail/lunar/)
+
+## 示例
+
+ import com.nlf.calendar.Lunar;
+
+ /**
+ * 阴历示例
+ *
+ */
+ public class LunarSample{
+ public static void main(String[] args){
+ //今天
+ Lunar date = new Lunar();
+ //输出阴历信息
+ System.out.println(date.toFullString());
+ //输出阳历信息
+ System.out.println(date.getSolar().toFullString());
+ System.out.println();
+ //指定阴历的某一天
+ date = new Lunar(1986,4,21);
+ System.out.println(date.toFullString());
+ System.out.println(date.getSolar().toFullString());
+ }
+ }
+
+输出结果:
+
+
+ 丙申年捌月初八 猴年 北方玄武 斗木獬
+ 2016-09-08 闰年 星期四 处女座
+
+ 丙寅年肆月廿一 虎年 北方玄武 危月燕
+ 1986-05-29 星期四 双子座
+
+## 文档
+
+请移步至 [http://6tail.cn/calendar/api.html](http://6tail.cn/calendar/api.html "http://6tail.cn/calendar/api.html")
+
+## 联系
+
+
+
diff --git a/pom.xml b/pom.xml
new file mode 100644
index 0000000..be83dfc
--- /dev/null
+++ b/pom.xml
@@ -0,0 +1,142 @@
+
+
+ 4.0.0
+
+ cn.6tail
+ lunar
+ jar
+ 1.0.0-SNAPSHOT
+ ${project.groupId}:${project.artifactId}
+ https://github.com/6tail/lunar-java
+ calendar util
+
+
+ The MIT License
+ http://opensource.org/licenses/MIT
+
+
+
+
+ 6tail
+ 6tail@6tail.cn
+ +8
+
+
+
+ master
+ scm:git:git@github.com:6tail/lunar-java.git
+ scm:git:git@github.com:6tail/lunar-java.git
+ git@github.com:6tail/lunar-java.git
+
+
+
+ sonatype-nexus-snapshots
+ Sonatype Nexus snapshot repository
+ https://oss.sonatype.org/content/repositories/snapshots
+
+
+ sonatype-nexus-staging
+ Sonatype Nexus release repository
+ https://oss.sonatype.org/service/local/staging/deploy/maven2/
+
+
+
+ UTF-8
+ UTF-8
+
+
+
+
+ junit
+ junit
+ 4.12
+ test
+
+
+
+ src/test/java
+
+
+ src/test/resources
+
+
+ target/test-classes
+
+
+ org.apache.maven.plugins
+ maven-release-plugin
+ 2.2.2
+
+ -Dgpg.passphrase=${gpg.passphrase}
+
+
+
+ org.apache.maven.plugins
+ maven-surefire-plugin
+ 2.5
+
+ true
+
+
+
+ org.apache.maven.plugins
+ maven-compiler-plugin
+ 3.3
+
+ 1.5
+ 1.5
+ UTF-8
+
+
+
+ org.apache.maven.plugins
+ maven-javadoc-plugin
+ 2.9
+
+
+ attach-javadocs
+
+ jar
+
+
+ -Xdoclint:none
+
+
+
+
+
+ org.apache.maven.plugins
+ maven-source-plugin
+ 2.4
+
+
+ attach-sources
+
+ jar-no-fork
+
+
+
+
+
+ org.apache.maven.plugins
+ maven-gpg-plugin
+ 1.6
+
+ ${gpg.passphrase}
+
+
+
+ sign-artifacts
+ verify
+
+ sign
+
+
+
+
+
+ ${project.artifactId}-${project.version}
+
+
\ No newline at end of file
diff --git a/src/main/java/com/nlf/calendar/Lunar.java b/src/main/java/com/nlf/calendar/Lunar.java
new file mode 100644
index 0000000..3eef594
--- /dev/null
+++ b/src/main/java/com/nlf/calendar/Lunar.java
@@ -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;ilastDate){
+ 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 getFestivals(){
+ List l = new ArrayList();
+ 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;
+ }
+}
\ No newline at end of file
diff --git a/src/main/java/com/nlf/calendar/Solar.java b/src/main/java/com/nlf/calendar/Solar.java
new file mode 100644
index 0000000..005b5cf
--- /dev/null
+++ b/src/main/java/com/nlf/calendar/Solar.java
@@ -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 getFestivals(){
+ List l = new ArrayList();
+ //获取几月几日对应的节日
+ 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);
+ }
+
+}
\ No newline at end of file
diff --git a/src/main/java/com/nlf/calendar/SolarHalfYear.java b/src/main/java/com/nlf/calendar/SolarHalfYear.java
new file mode 100644
index 0000000..18811e0
--- /dev/null
+++ b/src/main/java/com/nlf/calendar/SolarHalfYear.java
@@ -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 getMonths(){
+ List l = new ArrayList();
+ 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?"上":"下")+"半年";
+ }
+}
\ No newline at end of file
diff --git a/src/main/java/com/nlf/calendar/SolarMonth.java b/src/main/java/com/nlf/calendar/SolarMonth.java
new file mode 100644
index 0000000..e38673b
--- /dev/null
+++ b/src/main/java/com/nlf/calendar/SolarMonth.java
@@ -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 getDays(){
+ List l = new ArrayList(31);
+ Solar d = new Solar(year,month,1);
+ l.add(d);
+ int days = SolarUtil.getDaysOfMonth(year,month);
+ for(int i = 1;i getMonths(){
+ List l = new ArrayList();
+ 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()+"季度";
+ }
+}
\ No newline at end of file
diff --git a/src/main/java/com/nlf/calendar/SolarWeek.java b/src/main/java/com/nlf/calendar/SolarWeek.java
new file mode 100644
index 0000000..3669e6c
--- /dev/null
+++ b/src/main/java/com/nlf/calendar/SolarWeek.java
@@ -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 days = getDays();
+ for(Solar day:days){
+ if(month==day.getMonth()){
+ return day;
+ }
+ }
+ return null;
+ }
+
+ /**
+ * 获取本周的阳历日期列表(可能跨月)
+ * @return 本周的阳历日期列表
+ */
+ public List getDays(){
+ Solar firstDay = getFirstDay();
+ List l = new ArrayList();
+ l.add(firstDay);
+ for(int i = 1;i<7;i++){
+ l.add(firstDay.next(i));
+ }
+ return l;
+ }
+
+ /**
+ * 获取本周的阳历日期列表(仅限当月)
+ * @return 本周的阳历日期列表(仅限当月)
+ */
+ public List getDaysInMonth(){
+ List days = this.getDays();
+ List l = new ArrayList();
+ 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()+"周";
+ }
+}
\ No newline at end of file
diff --git a/src/main/java/com/nlf/calendar/SolarYear.java b/src/main/java/com/nlf/calendar/SolarYear.java
new file mode 100644
index 0000000..8b713c8
--- /dev/null
+++ b/src/main/java/com/nlf/calendar/SolarYear.java
@@ -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 getMonths(){
+ List l = new ArrayList(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+"年";
+ }
+}
\ No newline at end of file
diff --git a/src/main/java/com/nlf/calendar/util/LunarUtil.java b/src/main/java/com/nlf/calendar/util/LunarUtil.java
new file mode 100644
index 0000000..2a94403
--- /dev/null
+++ b/src/main/java/com/nlf/calendar/util/LunarUtil.java
@@ -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 FESTIVAL = new HashMap(){
+ 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 SHOU = new HashMap(){
+ private static final long serialVersionUID = -1;
+ {
+ put("东","青龙");
+ put("南","朱雀");
+ put("西","白虎");
+ put("北","玄武");
+ }
+ };
+ /** 宫 */
+ public static final Map GONG = new HashMap(){
+ 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 ZHENG = new HashMap(){
+ 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 ANIMAL = new HashMap(){
+ 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;
+ }
+}
\ No newline at end of file
diff --git a/src/main/java/com/nlf/calendar/util/SolarUtil.java b/src/main/java/com/nlf/calendar/util/SolarUtil.java
new file mode 100644
index 0000000..e5c6ab3
--- /dev/null
+++ b/src/main/java/com/nlf/calendar/util/SolarUtil.java
@@ -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 FESTIVAL = new HashMap(){
+ 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 WEEK_FESTIVAL = new HashMap(){
+ 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);
+ }
+}
\ No newline at end of file
diff --git a/src/test/java/sample/HalfYearTest.java b/src/test/java/sample/HalfYearTest.java
new file mode 100644
index 0000000..4eec8d7
--- /dev/null
+++ b/src/test/java/sample/HalfYearTest.java
@@ -0,0 +1,22 @@
+package sample;
+
+import com.nlf.calendar.*;
+import org.junit.Test;
+
+/**
+ * 半年示例
+ */
+public class HalfYearTest {
+
+ @Test
+ public void test(){
+ SolarHalfYear halfYear = new SolarHalfYear();
+ System.out.println(halfYear);
+ System.out.println(halfYear.toFullString());
+
+ for(SolarMonth month:halfYear.getMonths()){
+ System.out.println(month.toFullString());
+ }
+ }
+
+}
diff --git a/src/test/java/sample/LunarTest.java b/src/test/java/sample/LunarTest.java
new file mode 100644
index 0000000..cbf8dae
--- /dev/null
+++ b/src/test/java/sample/LunarTest.java
@@ -0,0 +1,26 @@
+package sample;
+
+import com.nlf.calendar.Lunar;
+import org.junit.Test;
+
+/**
+ * 农历示例
+ */
+public class LunarTest {
+
+ @Test
+ public void test(){
+ //今天
+ Lunar date = new Lunar();
+ //输出阴历信息
+ System.out.println(date.toFullString());
+ //输出阳历信息
+ System.out.println(date.getSolar().toFullString());
+ System.out.println();
+ //指定阴历的某一天
+ date = new Lunar(1986,4,21);
+ System.out.println(date.toFullString());
+ System.out.println(date.getSolar().toFullString());
+ }
+
+}
diff --git a/src/test/java/sample/MonthTest.java b/src/test/java/sample/MonthTest.java
new file mode 100644
index 0000000..53b5589
--- /dev/null
+++ b/src/test/java/sample/MonthTest.java
@@ -0,0 +1,26 @@
+package sample;
+
+import com.nlf.calendar.Solar;
+import com.nlf.calendar.SolarMonth;
+import org.junit.Test;
+
+/**
+ * 月份示例
+ */
+public class MonthTest {
+
+ @Test
+ public void test(){
+ //下个月
+ SolarMonth month = new SolarMonth().next(1);
+ //遍历每一天
+ for(Solar d:month.getDays()){
+ //输出阳历信息
+ System.out.println(d.toFullString());
+ //输出阴历信息
+ System.out.println(d.getLunar().toFullString());
+ System.out.println();
+ }
+ }
+
+}
diff --git a/src/test/java/sample/SeasonTest.java b/src/test/java/sample/SeasonTest.java
new file mode 100644
index 0000000..c82d15e
--- /dev/null
+++ b/src/test/java/sample/SeasonTest.java
@@ -0,0 +1,23 @@
+package sample;
+
+import com.nlf.calendar.SolarMonth;
+import com.nlf.calendar.SolarSeason;
+import org.junit.Test;
+
+/**
+ * 季度示例
+ */
+public class SeasonTest {
+
+ @Test
+ public void test(){
+ SolarSeason season = new SolarSeason();
+ System.out.println(season);
+ System.out.println(season.toFullString());
+
+ for(SolarMonth month:season.getMonths()){
+ System.out.println(month.toFullString());
+ }
+ }
+
+}
diff --git a/src/test/java/sample/SolarTest.java b/src/test/java/sample/SolarTest.java
new file mode 100644
index 0000000..8ca3907
--- /dev/null
+++ b/src/test/java/sample/SolarTest.java
@@ -0,0 +1,26 @@
+package sample;
+
+import com.nlf.calendar.Solar;
+import org.junit.Test;
+
+/**
+ * 阳历示例
+ */
+public class SolarTest {
+
+ @Test
+ public void test(){
+ //阳历今天
+ Solar date = new Solar();
+ //输出阳历信息
+ System.out.println(date.toFullString());
+ //输出阴历信息
+ System.out.println(date.getLunar().toFullString());
+ System.out.println();
+ //指定某个阳历日期
+ date = new Solar(1986,5,29);
+ System.out.println(date.toFullString());
+ System.out.println(date.getLunar().toFullString());
+ }
+
+}
diff --git a/src/test/java/sample/WeekTest.java b/src/test/java/sample/WeekTest.java
new file mode 100644
index 0000000..879fba2
--- /dev/null
+++ b/src/test/java/sample/WeekTest.java
@@ -0,0 +1,28 @@
+package sample;
+
+import com.nlf.calendar.Solar;
+import com.nlf.calendar.SolarWeek;
+import com.nlf.calendar.util.SolarUtil;
+import org.junit.Test;
+
+/**
+ * 周示例
+ */
+public class WeekTest {
+
+ @Test
+ public void test(){
+ //一周的开始从星期一开始计
+ SolarWeek week = new SolarWeek(1);
+ System.out.println(week);
+ System.out.println(week.toFullString());
+
+ System.out.println("本月共几周:"+ SolarUtil.getWeeksOfMonth(week.getYear(),week.getMonth(),1));
+ System.out.println("本周第一天:"+week.getFirstDay());
+ //遍历本周的每一天
+ for(Solar day:week.getDays()){
+ System.out.println(day);
+ }
+ }
+
+}
diff --git a/src/test/java/sample/YearTest.java b/src/test/java/sample/YearTest.java
new file mode 100644
index 0000000..38615c2
--- /dev/null
+++ b/src/test/java/sample/YearTest.java
@@ -0,0 +1,46 @@
+package sample;
+
+import com.nlf.calendar.Lunar;
+import com.nlf.calendar.Solar;
+import com.nlf.calendar.SolarMonth;
+import com.nlf.calendar.SolarYear;
+import org.junit.Test;
+
+/**
+ * 年份示例,我们来做一个日历吧
+ */
+public class YearTest {
+
+ @Test
+ public void test(){
+ //明年
+ SolarYear year = new SolarYear().next(1);
+ System.out.println("==="+year.getYear()+"年===");
+ //遍历明年的每个月
+ for(SolarMonth m:year.getMonths()){
+ System.out.println("---"+m.getMonth()+"月---");
+ //遍历当月的每一天
+ 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());
+ }
+ }
+ }
+
+}