优化儒略日计算;使用最新寿星天文历算法修复节气误差。
This commit is contained in:
File diff suppressed because one or more lines are too long
@@ -105,55 +105,46 @@ public class Solar{
|
|||||||
* @param julianDay 儒略日
|
* @param julianDay 儒略日
|
||||||
*/
|
*/
|
||||||
public Solar(double julianDay){
|
public Solar(double julianDay){
|
||||||
julianDay += 0.5;
|
int d = (int)(julianDay + 0.5);
|
||||||
|
double f = julianDay + 0.5 - d;
|
||||||
|
int c;
|
||||||
|
|
||||||
// 日数的整数部份
|
if (d >= 2299161) {
|
||||||
double a = int2(julianDay);
|
c = (int)((d - 1867216.25) / 36524.25);
|
||||||
// 日数的小数部分
|
d += 1 + c - (int)(c * 1D / 4);
|
||||||
double f = julianDay - a;
|
|
||||||
double jd;
|
|
||||||
|
|
||||||
if (a > 2299161) {
|
|
||||||
jd = int2((a - 1867216.25) / 36524.25);
|
|
||||||
a += 1 + jd - int2(jd / 4);
|
|
||||||
}
|
}
|
||||||
// 向前移4年零2个月
|
d += 1524;
|
||||||
a += 1524;
|
int year = (int)((d - 122.1) / 365.25);
|
||||||
double y = int2((a - 122.1) / 365.25);
|
d -= (int)(365.25 * year);
|
||||||
// 去除整年日数后余下日数
|
int month = (int)(d * 1D / 30.601);
|
||||||
jd = a - int2(365.25 * y);
|
d -= (int)(30.601 * month);
|
||||||
double m = (int)int2(jd / 30.6001);
|
int day = d;
|
||||||
// 去除整月日数后余下日数
|
if (month > 13) {
|
||||||
double d = (int)int2(jd - int2(m * 30.6001));
|
month -= 13;
|
||||||
y -= 4716;
|
year -= 4715;
|
||||||
m--;
|
} else {
|
||||||
if (m > 12) {
|
month -= 1;
|
||||||
m -= 12;
|
year -= 4716;
|
||||||
}
|
}
|
||||||
if (m <= 2) {
|
|
||||||
y++;
|
|
||||||
}
|
|
||||||
|
|
||||||
// 日的小数转为时分秒
|
|
||||||
f *= 24;
|
f *= 24;
|
||||||
double h = (int)int2(f);
|
int hour = (int)f;
|
||||||
|
|
||||||
f -= h;
|
f -= hour;
|
||||||
f *= 60;
|
f *= 60;
|
||||||
double mi = int2(f);
|
int minute = (int)f;
|
||||||
|
|
||||||
f -= mi;
|
f -= minute;
|
||||||
f *= 60;
|
f *= 60;
|
||||||
double s = int2(f);
|
int second = (int)Math.round(f);
|
||||||
|
|
||||||
calendar = Calendar.getInstance();
|
calendar = Calendar.getInstance();
|
||||||
calendar.set((int)y,(int)m-1,(int)d,(int)h,(int)mi,(int)s);
|
calendar.set(year,month-1,day,hour,minute,second);
|
||||||
year = calendar.get(Calendar.YEAR);
|
this.year = year;
|
||||||
month = calendar.get(Calendar.MONTH)+1;
|
this.month = month;
|
||||||
day = calendar.get(Calendar.DATE);
|
this.day = day;
|
||||||
hour = calendar.get(Calendar.HOUR_OF_DAY);
|
this.hour = hour;
|
||||||
minute = calendar.get(Calendar.MINUTE);
|
this.minute = minute;
|
||||||
second = calendar.get(Calendar.SECOND);
|
this.second = second;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -388,38 +379,28 @@ public class Solar{
|
|||||||
return new Lunar(calendar.getTime());
|
return new Lunar(calendar.getTime());
|
||||||
}
|
}
|
||||||
|
|
||||||
private double int2(double v){
|
|
||||||
v = Math.floor(v);
|
|
||||||
return v<0?v+1:v;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 获取儒略日
|
* 获取儒略日
|
||||||
* @return 儒略日
|
* @return 儒略日
|
||||||
*/
|
*/
|
||||||
public double getJulianDay(){
|
public double getJulianDay(){
|
||||||
double y = this.year;
|
int y = this.year;
|
||||||
double m = this.month;
|
int m = this.month;
|
||||||
double n = 0;
|
double d = this.day + ((this.second *1D / 60 + this.minute) / 60 + this.hour) / 24;
|
||||||
|
int n = 0;
|
||||||
|
boolean g = false;
|
||||||
|
if (y * 372 + m * 31 + (int)d >= 588829) {
|
||||||
|
g = true;
|
||||||
|
}
|
||||||
if (m <= 2) {
|
if (m <= 2) {
|
||||||
m += 12;
|
m += 12;
|
||||||
y--;
|
y--;
|
||||||
}
|
}
|
||||||
|
if (g) {
|
||||||
// 判断是否为UTC日1582*372+10*31+15
|
n = (int)(y * 1D / 100);
|
||||||
if (this.year * 372 + this.month * 31 + this.day >= 588829) {
|
n = 2 - n + (int)(n * 1D / 4);
|
||||||
n = int2(y / 100);
|
|
||||||
// 加百年闰
|
|
||||||
n = 2 - n + int2(n / 4);
|
|
||||||
}
|
}
|
||||||
|
return (int)(365.25 * (y + 4716)) + (int)(30.6001 * (m + 1)) + d + n - 1524.5;
|
||||||
// 加上年引起的偏移日数
|
|
||||||
n += int2(365.2500001 * (y + 4716));
|
|
||||||
// 加上月引起的偏移日数及日偏移数
|
|
||||||
n += int2(30.6 * (m + 1)) + this.day;
|
|
||||||
n += ((this.second *1D / 60 + this.minute) / 60 + this.hour) / 24 - 1524.5;
|
|
||||||
return n;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
98
src/test/java/test/JiQiTest.java
Normal file
98
src/test/java/test/JiQiTest.java
Normal file
@@ -0,0 +1,98 @@
|
|||||||
|
package test;
|
||||||
|
|
||||||
|
import com.nlf.calendar.Solar;
|
||||||
|
import org.junit.Assert;
|
||||||
|
import org.junit.Test;
|
||||||
|
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 节气测试
|
||||||
|
*
|
||||||
|
* @author 6tail
|
||||||
|
*/
|
||||||
|
public class JiQiTest {
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void test2022() {
|
||||||
|
|
||||||
|
Map<String,String> jieQi = new HashMap<String, String>(){
|
||||||
|
private static final long serialVersionUID = 1L;
|
||||||
|
{
|
||||||
|
put("冬至","2021-12-21 23:59:09");
|
||||||
|
put("小寒","2022-01-05 17:13:54");
|
||||||
|
put("大寒","2022-01-20 10:38:56");
|
||||||
|
put("立春","2022-02-04 04:50:36");
|
||||||
|
put("雨水","2022-02-19 00:42:50");
|
||||||
|
put("惊蛰","2022-03-05 22:43:34");
|
||||||
|
put("春分","2022-03-20 23:33:15");
|
||||||
|
put("清明","2022-04-05 03:20:03");
|
||||||
|
put("谷雨","2022-04-20 10:24:07");
|
||||||
|
put("立夏","2022-05-05 20:25:46");
|
||||||
|
put("小满","2022-05-21 09:22:25");
|
||||||
|
put("芒种","2022-06-06 00:25:37");
|
||||||
|
put("夏至","2022-06-21 17:13:40");
|
||||||
|
put("小暑","2022-07-07 10:37:49");
|
||||||
|
put("大暑","2022-07-23 04:06:49");
|
||||||
|
put("立秋","2022-08-07 20:28:57");
|
||||||
|
put("处暑","2022-08-23 11:15:59");
|
||||||
|
put("白露","2022-09-07 23:32:07");
|
||||||
|
put("秋分","2022-09-23 09:03:31");
|
||||||
|
put("寒露","2022-10-08 15:22:16");
|
||||||
|
put("霜降","2022-10-23 18:35:31");
|
||||||
|
put("立冬","2022-11-07 18:45:18");
|
||||||
|
put("小雪","2022-11-22 16:20:18");
|
||||||
|
put("大雪","2022-12-07 11:46:04");
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
Solar solar = Solar.fromYmd(2022, 7, 15);
|
||||||
|
Map<String,Solar> result = solar.getLunar().getJieQiTable();
|
||||||
|
for(Map.Entry<String,String> entry:jieQi.entrySet()){
|
||||||
|
String name = entry.getKey();
|
||||||
|
Assert.assertEquals(name, entry.getValue(), result.get(name).toYmdHms());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void test1986() {
|
||||||
|
|
||||||
|
Map<String,String> jieQi = new HashMap<String, String>(){
|
||||||
|
private static final long serialVersionUID = 1L;
|
||||||
|
{
|
||||||
|
put("冬至","1985-12-22 06:07:40");
|
||||||
|
put("小寒","1986-01-05 23:28:02");
|
||||||
|
put("大寒","1986-01-20 16:46:12");
|
||||||
|
put("立春","1986-02-04 11:07:42");
|
||||||
|
put("雨水","1986-02-19 06:57:31");
|
||||||
|
put("惊蛰","1986-03-06 05:12:08");
|
||||||
|
put("春分","1986-03-21 06:02:41");
|
||||||
|
put("清明","1986-04-05 10:06:07");
|
||||||
|
put("谷雨","1986-04-20 17:12:08");
|
||||||
|
put("立夏","1986-05-06 03:30:36");
|
||||||
|
put("小满","1986-05-21 16:27:55");
|
||||||
|
put("芒种","1986-06-06 07:44:23");
|
||||||
|
put("夏至","1986-06-22 00:29:57");
|
||||||
|
put("小暑","1986-07-07 18:00:45");
|
||||||
|
put("大暑","1986-07-23 11:24:23");
|
||||||
|
put("立秋","1986-08-08 03:45:36");
|
||||||
|
put("处暑","1986-08-23 18:25:47");
|
||||||
|
put("白露","1986-09-08 06:34:37");
|
||||||
|
put("秋分","1986-09-23 15:58:52");
|
||||||
|
put("寒露","1986-10-08 22:06:45");
|
||||||
|
put("霜降","1986-10-24 01:14:11");
|
||||||
|
put("立冬","1986-11-08 01:12:49");
|
||||||
|
put("小雪","1986-11-22 22:44:20");
|
||||||
|
put("大雪","1986-12-07 18:00:56");
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
Solar solar = Solar.fromYmd(1986, 7, 15);
|
||||||
|
Map<String,Solar> result = solar.getLunar().getJieQiTable();
|
||||||
|
for(Map.Entry<String,String> entry:jieQi.entrySet()){
|
||||||
|
String name = entry.getKey();
|
||||||
|
Assert.assertEquals(name, entry.getValue(), result.get(name).toYmdHms());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
25
src/test/java/test/JulianDayTest.java
Normal file
25
src/test/java/test/JulianDayTest.java
Normal file
@@ -0,0 +1,25 @@
|
|||||||
|
package test;
|
||||||
|
|
||||||
|
import com.nlf.calendar.Solar;
|
||||||
|
import org.junit.Assert;
|
||||||
|
import org.junit.Test;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 儒略日测试
|
||||||
|
*
|
||||||
|
* @author 6tail
|
||||||
|
*/
|
||||||
|
public class JulianDayTest {
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testSolar2JD() {
|
||||||
|
Solar solar = Solar.fromYmd(2020, 7, 15);
|
||||||
|
Assert.assertEquals(2459045.5, solar.getJulianDay(), 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testJD2Solar() {
|
||||||
|
Solar solar = Solar.fromJulianDay(2459045.5);
|
||||||
|
Assert.assertEquals("2020-07-15 00:00:00", solar.toYmdHms());
|
||||||
|
}
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user