1
0
mirror of synced 2026-10-09 00:06:12 +08:00

Compare commits

..

13 Commits

Author SHA1 Message Date
6tail
392ac5b00a v1.1.7 修复值月九星数组下标越界的问题。 2020-10-17 20:05:02 +08:00
6tail
9ec735cd4b Merge branch 'v1.1.0-SNAPSHOT' 2020-10-17 20:03:48 +08:00
6tail
e06c7a0532 修复值月九星数组下标越界的问题。 2020-10-17 20:03:01 +08:00
6tail
bd18254834 v1.1.6 修复阳历年12月底获取下一节气为空的问题。 2020-10-16 09:54:06 +08:00
6tail
28dbf8f45f Merge branch 'v1.1.0-SNAPSHOT' 2020-10-16 09:51:54 +08:00
6tail
0d1f64664e 修复阳历年12月底获取下一节气为空的问题。 2020-10-16 09:51:26 +08:00
6tail
cc2bbb5049 v1.1.5 修复立春至正月初一之间八字年月柱错误的问题;新增支持农历日期的推移。 2020-10-15 19:30:43 +08:00
6tail
9bb808da35 Merge branch 'v1.1.0-SNAPSHOT' 2020-10-15 19:14:57 +08:00
6tail
e29ab49618 修复立春至正月初一之间八字年月柱错误的问题;新增支持农历日期的推移。 2020-10-15 19:14:23 +08:00
6tail
60634d7cd8 v1.1.4 增加获取节气名、上一气令、下一气令、当天节气、当天节令、当天气令的方法;节气对象增加判断是节令还是气令的方法。 2020-10-12 22:58:35 +08:00
6tail
fba9a85135 Merge branch 'v1.1.0-SNAPSHOT' 2020-10-12 22:55:46 +08:00
6tail
913e7b40fb 节气对象增加判断是节令还是气令的方法 2020-10-12 22:54:58 +08:00
6tail
c7738352eb 增加获取节气名、上一气令、下一气令、当天节气、当天节令、当天气令的方法 2020-10-12 22:36:19 +08:00
9 changed files with 367 additions and 31 deletions

View File

@@ -16,7 +16,7 @@ lunar是一款无第三方依赖的公历(阳历)和农历(阴历、老黄历)
<dependency>
<groupId>cn.6tail</groupId>
<artifactId>lunar</artifactId>
<version>1.1.3</version>
<version>1.1.7</version>
</dependency>
```
@@ -44,7 +44,7 @@ lunar是一款无第三方依赖的公历(阳历)和农历(阴历、老黄历)
### 下载jar
如果使用jar,建议下载最新的SNAPSHOT版本,bug将得到及时的修复。
如果使用jar,建议下载最新的版本,bug将得到及时的修复。
[Download](https://github.com/6tail/lunar-java/releases)

View File

@@ -12,7 +12,7 @@ lunar is a calendar library for Solar and Chinese Lunar.
<dependency>
<groupId>cn.6tail</groupId>
<artifactId>lunar</artifactId>
<version>1.1.3</version>
<version>1.1.7</version>
</dependency>
```
@@ -40,7 +40,7 @@ lunar is a calendar library for Solar and Chinese Lunar.
### Download
If you will use jars in your projects, I suggest you to download latest snapshot versions with less bugs.
If you will use jars in your projects, I suggest you to download latest versions with less bugs.
[Download](https://github.com/6tail/lunar-java/releases)

View File

@@ -7,7 +7,7 @@
<groupId>cn.6tail</groupId>
<artifactId>lunar</artifactId>
<packaging>jar</packaging>
<version>1.1.3</version>
<version>1.1.7</version>
<name>${project.groupId}:${project.artifactId}</name>
<url>https://github.com/6tail/lunar-java</url>
<description>a calendar library for Solar and Chinese Lunar</description>
@@ -60,7 +60,7 @@
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.12</version>
<version>4.13.1</version>
<scope>test</scope>
</dependency>
</dependencies>

View File

@@ -1,5 +1,7 @@
package com.nlf.calendar;
import com.nlf.calendar.util.LunarUtil;
/**
* 节气
*
@@ -13,11 +15,22 @@ public class JieQi {
/** 阳历日期 */
private Solar solar;
/** 是否节令 */
private boolean jie;
/** 是否气令 */
private boolean qi;
public JieQi() {
}
/**
* 初始化
* @param name 名称
* @param solar 阳历日期
*/
public JieQi(String name, Solar solar) {
this.name = name;
setName(name);
this.solar = solar;
}
@@ -35,6 +48,18 @@ public class JieQi {
*/
public void setName(String name) {
this.name = name;
for(String key: LunarUtil.JIE){
if(key.equals(name)){
this.jie = true;
return;
}
}
for(String key: LunarUtil.QI){
if(key.equals(name)){
this.qi = true;
return;
}
}
}
/**
@@ -53,4 +78,24 @@ public class JieQi {
this.solar = solar;
}
/**
* 是否节令
* @return true/false
*/
public boolean isJie(){
return jie;
}
/**
* 是否气令
* @return true/false
*/
public boolean isQi() {
return qi;
}
@Override
public String toString(){
return name;
}
}

View File

@@ -20,6 +20,14 @@ public class Lunar{
public static final String JIE_QI_FIRST = "冬至";
/** 农历年末节气名(节令:大雪) */
public static final String JIE_QI_LAST = "大雪";
/** 节气表尾部追加阳历下年初的第一个节气名(节令:小寒),以示区分 */
public static final String JIE_APPEND_SOLAR_FIRST = "XIAO_HAN";
/** 节气表尾部追加阳历下年初的第二个节气名(气令:大寒),以示区分 */
public static final String QI_APPEND_SOLAR_SECOND = "DA_HAN";
/** 阳历下年初的第一个节气名(节令:小寒) */
public static final String JIE_SOLAR_FIRST = "小寒";
/** 阳历下年初的第二个节气名(气令:大寒) */
public static final String QI_SOLAR_SECOND = "大寒";
/** 1弧度对应的角秒 */
private static final double SECOND_PER_RAD = 180 * 3600 / Math.PI;
/** 节气表,国标以冬至为首个节气 */
@@ -408,12 +416,23 @@ public class Lunar{
//追加下一农历年初的冬至
q = calcJieQi(w + 15.2184 * size);
jieQi.put(JIE_QI_APPEND, Solar.fromJulianDay(qiAccurate2(q) + Solar.J2000));
//追加下一阳历年初的小寒
size++;
q = calcJieQi(w + 15.2184 * size);
jieQi.put(JIE_APPEND_SOLAR_FIRST, Solar.fromJulianDay(qiAccurate2(q) + Solar.J2000));
//追加下一阳历年初的大寒
size++;
q = calcJieQi(w + 15.2184 * size);
jieQi.put(QI_APPEND_SOLAR_SECOND, Solar.fromJulianDay(qiAccurate2(q) + Solar.J2000));
}
/**
* 计算干支纪年
*/
private void computeYear(){
//以正月初一开始
yearGanIndex = (year+LunarUtil.BASE_YEAR_GANZHI_INDEX)%10;
yearZhiIndex = (year+LunarUtil.BASE_YEAR_GANZHI_INDEX)%12;
@@ -425,32 +444,57 @@ public class Lunar{
int gExact = yearGanIndex;
int zExact = yearZhiIndex;
//获取立春的阳历时刻
Solar liChun = jieQi.get("立春");
//阳历和阴历年份相同代表正月初一及以后
if(year==solar.getYear()){
//获取立春的阳历时刻
Solar liChun = jieQi.get("立春");
//立春日期判断
if(solar.toYmd().compareTo(liChun.toYmd())<0) {
g--;
if(g<0){
g += 10;
}
z--;
if(z<0){
z += 12;
}
}
//立春交接时刻判断
if(solar.toYmdHms().compareTo(liChun.toYmdHms())<0) {
gExact--;
if(gExact<0){
gExact += 10;
}
zExact--;
if(zExact<0){
zExact += 12;
}
}
}else{
if(solar.toYmd().compareTo(liChun.toYmd())>=0) {
g++;
z++;
}
if(solar.toYmdHms().compareTo(liChun.toYmdHms())>=0) {
gExact++;
zExact++;
}
}
if(g<0){
g += 10;
}
if(g>=10){
g-=10;
}
if(z<0){
z += 12;
}
if(z>=12){
z-=12;
}
if(gExact<0){
gExact += 10;
}
if(gExact>=10){
gExact-=10;
}
if(zExact<0){
zExact += 12;
}
if(zExact>=12){
zExact-=12;
}
yearGanIndexByLiChun = g;
yearZhiIndexByLiChun = z;
@@ -953,6 +997,11 @@ public class Lunar{
if(d.getYear()==solar.getYear()&&d.getMonth()==solar.getMonth()&&d.getDay()==solar.getDay()){
return JIE_QI_LAST;
}
// 追加的节令:小寒
d = jieQi.get(JIE_APPEND_SOLAR_FIRST);
if(d.getYear()==solar.getYear()&&d.getMonth()==solar.getMonth()&&d.getDay()==solar.getDay()){
return JIE_SOLAR_FIRST;
}
return "";
}
@@ -973,6 +1022,11 @@ public class Lunar{
if(d.getYear()==solar.getYear()&&d.getMonth()==solar.getMonth()&&d.getDay()==solar.getDay()){
return JIE_QI_FIRST;
}
// 追加的气令:大寒
d = jieQi.get(QI_APPEND_SOLAR_SECOND);
if(d.getYear()==solar.getYear()&&d.getMonth()==solar.getMonth()&&d.getDay()==solar.getDay()){
return QI_SOLAR_SECOND;
}
return "";
}
@@ -1849,8 +1903,11 @@ public class Lunar{
}
// 寅月起,所以需要-2
int monthIndex = monthZhiIndex-2;
if(monthIndex<0){
monthIndex += 12;
}
int index = start-monthIndex-1;
if(index<0){
while(index<0){
index += 9;
}
return new NineStar(index);
@@ -1949,6 +2006,22 @@ public class Lunar{
return getNearJieQi(false,LunarUtil.JIE);
}
/**
* 获取下一气令(顺推的第一个气令)
* @return 节气
*/
public JieQi getNextQi(){
return getNearJieQi(true,LunarUtil.QI);
}
/**
* 获取上一气令(逆推的第一个气令)
* @return 节气
*/
public JieQi getPrevQi(){
return getNearJieQi(false,LunarUtil.QI);
}
/**
* 获取下一节气(顺推的第一个节气)
* @return 节气
@@ -1988,6 +2061,12 @@ public class Lunar{
if(JIE_QI_PREPEND.equals(jq)){
jq = JIE_QI_LAST;
}
if(JIE_APPEND_SOLAR_FIRST.equals(jq)){
jq = JIE_SOLAR_FIRST;
}
if(QI_APPEND_SOLAR_SECOND.equals(jq)){
jq = QI_SOLAR_SECOND;
}
if(filter){
if(!filters.contains(jq)){
continue;
@@ -2019,6 +2098,58 @@ public class Lunar{
return new JieQi(name, near);
}
/**
* 获取节气名称,如果无节气,返回空字符串
* @return 节气名称
*/
public String getJieQi(){
String name = "";
for(Map.Entry<String,Solar> jq:jieQi.entrySet()){
Solar d = jq.getValue();
if(d.getYear()==solar.getYear()&&d.getMonth()==solar.getMonth()&&d.getDay()==solar.getDay()){
name = jq.getKey();
break;
}
}
if(JIE_QI_APPEND.equals(name)){
name = JIE_QI_FIRST;
}else if(JIE_QI_PREPEND.equals(name)){
name = JIE_QI_LAST;
}else if(JIE_APPEND_SOLAR_FIRST.equals(name)){
name = JIE_SOLAR_FIRST;
}else if(QI_APPEND_SOLAR_SECOND.equals(name)){
name = QI_SOLAR_SECOND;
}
return name;
}
/**
* 获取当天节气对象,如果无节气,返回null
* @return 节气对象
*/
public JieQi getCurrentJieQi(){
String name = getJieQi();
return name.length()>0 ? new JieQi(name,solar) : null;
}
/**
* 获取当天节令对象,如果无节令,返回null
* @return 节气对象
*/
public JieQi getCurrentJie(){
String name = getJie();
return name.length()>0 ? new JieQi(name,solar) : null;
}
/**
* 获取当天气令对象,如果无气令,返回null
* @return 节气对象
*/
public JieQi getCurrentQi(){
String name = getQi();
return name.length()>0 ? new JieQi(name,solar) : null;
}
public String toFullString(){
StringBuilder s = new StringBuilder();
s.append(toString());
@@ -2058,7 +2189,7 @@ public class Lunar{
s.append(f);
s.append(")");
}
String jq = getJie()+getQi();
String jq = getJieQi();
if(jq.length()>0){
s.append(" [");
s.append(jq);
@@ -2207,4 +2338,55 @@ public class Lunar{
}
return eightChar;
}
/**
* 获取往后推几天的农历日期,如果要往前推,则天数用负数
* @param days 天数
* @return 农历日期
*/
public Lunar next(int days){
int y = year;
int m = month;
int d = day;
if(days>0){
int daysInMonth = LunarUtil.getDaysOfMonth(y,m);
int rest = day+days;
while(daysInMonth < rest) {
if(m>0){
if(LunarUtil.getLeapMonth(y)!=m){
m++;
}else{
m = -m;
}
}else{
m = 1-m;
}
if(13==m){
y++;
m=1;
}
rest -= daysInMonth;
daysInMonth = LunarUtil.getDaysOfMonth(y,m);
}
d = rest;
}else if(days<0){
int daysInMonth = day;
int rest = -days;
while(daysInMonth <= rest) {
if(m>0){
m--;
if(0==m){
y--;
m = LunarUtil.getLeapMonth(y)!=12?12:-12;
}
}else{
m = -m;
}
rest -= daysInMonth;
daysInMonth = LunarUtil.getDaysOfMonth(y,m);
}
d = daysInMonth - rest;
}
return new Lunar(y,m,d,hour,minute,second);
}
}

View File

@@ -1142,17 +1142,11 @@ public class LunarUtil{
public static int nextMonth(int y,int m){
int n = Math.abs(m)+1;
if(m>0){
int index = y-BASE_YEAR+BASE_INDEX;
int v = LUNAR_MONTH[2*index+1];
v = (v>>4)&0x0F;
if(v==m){
if(m==getLeapMonth(y)){
n = -m;
}
}
if(n==13){
n = 1;
}
return n;
return 13!=n?n:1;
}
/**

View File

@@ -22,6 +22,33 @@ public class BaZiTest {
Assert.assertEquals("时柱", "壬辰", eightChar.getTime());
}
@Test
public void testGanZhi2() {
Solar solar = new Solar(1988, 2, 15, 23, 30, 0);
Lunar lunar = solar.getLunar();
EightChar eightChar = lunar.getEightChar();
Assert.assertEquals("年柱", "戊辰", eightChar.getYear());
Assert.assertEquals("月柱", "甲寅", eightChar.getMonth());
Assert.assertEquals("日柱", "辛丑", eightChar.getDay());
Assert.assertEquals("时柱", "戊子", eightChar.getTime());
solar = new Solar(1988, 2, 15, 22, 30, 0);
lunar = solar.getLunar();
eightChar = lunar.getEightChar();
Assert.assertEquals("年柱", "戊辰", eightChar.getYear());
Assert.assertEquals("月柱", "甲寅", eightChar.getMonth());
Assert.assertEquals("日柱", "庚子", eightChar.getDay());
Assert.assertEquals("时柱", "丁亥", eightChar.getTime());
solar = new Solar(1988, 2, 2, 22, 30, 0);
lunar = solar.getLunar();
eightChar = lunar.getEightChar();
Assert.assertEquals("年柱", "丁卯", eightChar.getYear());
Assert.assertEquals("月柱", "癸丑", eightChar.getMonth());
Assert.assertEquals("日柱", "丁亥", eightChar.getDay());
Assert.assertEquals("时柱", "辛亥", eightChar.getTime());
}
@Test
public void testHideGan() {
Solar solar = new Solar(2005, 12, 23, 8, 37, 0);

View File

@@ -1,5 +1,6 @@
package test;
import com.nlf.calendar.Lunar;
import com.nlf.calendar.Solar;
import org.junit.Assert;
import org.junit.Test;
@@ -95,4 +96,81 @@ public class JieQiTest {
Assert.assertEquals(name, entry.getValue(), result.get(name).toYmdHms());
}
}
@Test
public void test() {
Solar solar = Solar.fromYmd(1986,1,5);
Lunar lunar = solar.getLunar();
Assert.assertEquals("小寒", lunar.getJie());
Assert.assertEquals("小寒", lunar.getJieQi());
Assert.assertEquals("小寒", lunar.getCurrentJieQi().getName());
Assert.assertEquals("小寒", lunar.getCurrentJie().getName());
Assert.assertNull(lunar.getCurrentQi());
Assert.assertEquals("", lunar.getQi());
Assert.assertEquals("大雪", lunar.getPrevJie().getName());
Assert.assertEquals("冬至", lunar.getPrevQi().getName());
Assert.assertEquals("冬至", lunar.getPrevJieQi().getName());
solar = Solar.fromYmdHms(1986,1,20,17,0,0);
lunar = solar.getLunar();
Assert.assertEquals("大寒", lunar.getQi());
Assert.assertEquals("大寒", lunar.getJieQi());
Assert.assertEquals("大寒", lunar.getCurrentJieQi().getName());
Assert.assertEquals("大寒", lunar.getCurrentQi().getName());
Assert.assertNull(lunar.getCurrentJie());
Assert.assertEquals("", lunar.getJie());
Assert.assertEquals("立春", lunar.getNextJie().getName());
Assert.assertEquals("雨水", lunar.getNextQi().getName());
Assert.assertEquals("立春", lunar.getNextJieQi().getName());
solar = Solar.fromYmdHms(1986,1,20,14,0,0);
lunar = solar.getLunar();
Assert.assertEquals("小寒", lunar.getPrevJie().getName());
Assert.assertEquals("冬至", lunar.getPrevQi().getName());
Assert.assertEquals("小寒", lunar.getPrevJieQi().getName());
solar = Solar.fromYmd(1986,12,7);
lunar = solar.getLunar();
Assert.assertEquals("大雪", lunar.getJie());
Assert.assertEquals("大雪", lunar.getJieQi());
Assert.assertEquals("大雪", lunar.getCurrentJieQi().getName());
Assert.assertEquals("大雪", lunar.getCurrentJie().getName());
Assert.assertNull(lunar.getCurrentQi());
Assert.assertEquals("", lunar.getQi());
Assert.assertEquals("大雪", lunar.getNextJie().getName());
Assert.assertEquals("冬至", lunar.getNextQi().getName());
Assert.assertEquals("大雪", lunar.getNextJieQi().getName());
solar = Solar.fromYmd(1986,1,1);
lunar = solar.getLunar();
Assert.assertEquals("", lunar.getJie());
Assert.assertEquals("", lunar.getQi());
Assert.assertEquals("", lunar.getJieQi());
Assert.assertNull(lunar.getCurrentJieQi());
Assert.assertNull(lunar.getCurrentJie());
Assert.assertNull(lunar.getCurrentQi());
Assert.assertEquals("大雪", lunar.getPrevJie().getName());
Assert.assertEquals("冬至", lunar.getPrevQi().getName());
Assert.assertEquals("冬至", lunar.getPrevJieQi().getName());
Assert.assertEquals("小寒", lunar.getNextJie().getName());
Assert.assertEquals("大寒", lunar.getNextQi().getName());
Assert.assertEquals("小寒", lunar.getNextJieQi().getName());
solar = Solar.fromYmd(2012,12,25);
lunar = solar.getLunar();
Assert.assertEquals("", lunar.getJie());
Assert.assertEquals("", lunar.getQi());
Assert.assertEquals("", lunar.getJieQi());
Assert.assertNull(lunar.getCurrentJie());
Assert.assertNull(lunar.getCurrentQi());
Assert.assertNull(lunar.getCurrentJieQi());
Assert.assertEquals("小寒", lunar.getNextJie().getName());
Assert.assertEquals("大寒", lunar.getNextQi().getName());
Assert.assertEquals("小寒", lunar.getNextJieQi().getName());
Assert.assertEquals("大雪", lunar.getPrevJie().getName());
Assert.assertEquals("冬至", lunar.getPrevQi().getName());
Assert.assertEquals("冬至", lunar.getPrevJieQi().getName());
}
}

View File

@@ -1,6 +1,7 @@
package test;
import com.nlf.calendar.Lunar;
import com.nlf.calendar.Solar;
import org.junit.Assert;
import org.junit.Test;
@@ -20,4 +21,13 @@ public class LunarTest {
Assert.assertEquals("2019-05-01 00:00:00 星期三 (劳动节) 金牛座",date.getSolar().toFullString());
}
@Test
public void testNext(){
Solar solar = new Solar(2020,1,10,12,0,0);
Lunar lunar = solar.getLunar();
for(int i=-500;i<500;i++){
Assert.assertEquals("推移天数:"+i,solar.next(i).getLunar().toFullString(),lunar.next(i).toFullString());
}
}
}