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 [![License](https://img.shields.io/badge/license-MIT-4EB1BA.svg?style=flat-square)](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 + +lunar + 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 [![License](https://img.shields.io/badge/license-MIT-4EB1BA.svg?style=flat-square)](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") + +## 联系 + +lunar + 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()); + } + } + } + +}