sxtwl_cpp/src/day.cpp
2024-04-14 20:02:01 +08:00

331 lines
5.9 KiB
C++

#include "day.h"
#include "eph.h"
#include "JD.h"
namespace sxtwl
{
GZ getShiGz(uint8_t dayTg, uint8_t hour, bool isZaoWanZiShi = true);
};
void Day::checkSSQ()
{
if (!SSQPtr->ZQ.size() || this->d0 < SSQPtr->ZQ[0] || this->d0 >= SSQPtr->ZQ[24])
{
SSQPtr->calcY(this->d0);
}
}
/**
* 确定已经计算过阴历信息
*/
void Day::checkLunarData()
{
// 已经计算过了
if (this->Ldn != 0)
{
return;
}
this->checkSSQ();
int mk = int2((this->d0 - SSQPtr->HS[0]) / 30);
if (mk < 13 && SSQPtr->HS[mk + 1] <= this->d0)
{
mk++; //农历所在月的序数
}
//if (this.d0 == SSQPtr->HS[mk]) { //月的信息
this->Lmc = SSQPtr->ym[mk]; //月名称
this->Ldn = SSQPtr->dx[mk]; //月大小
this->Lleap = (SSQPtr->leap != 0 && SSQPtr->leap == mk); //闰状况
//}
// 阴历所处的日
this->Ldi = this->d0 - SSQPtr->HS[mk];
}
void Day::checkSolarData()
{
if (this->m != 0)
{
return;
}
Time t = JD::JD2DD(this->d0 + J2000);
this->y = t.Y;
this->d = t.D;
this->m = t.M;
}
/**
* 计算节气数据
*/
void Day::checkJQData()
{
if (this->qk != -2)
{
return;
}
this->qk = -1;
this->getJieQiJD();
//this->checkSSQ();
//int qk = int2((this->d0 - SSQPtr->ZQ[0] - 7) / 15.2184);
//////节气的取值范围是0-23
//if (qk < 23 && this->d0 >= SSQPtr->ZQ[qk + 1])
//{
// qk++;
//}
//this->qk = -1;
//if (this->d0 == SSQPtr->ZQ[qk])
//{
// this->qk = qk;
//}
}
Day *Day::after(int day)
{
return new Day(this->d0 + day);
}
Day *Day::before(int day)
{
return new Day(this->d0 - day);
}
/**
* 获取阴历日期
*/
int Day::getLunarDay()
{
this->checkLunarData();
return this->Ldi + 1;
}
/**
* 获取阴历月
*/
uint8_t Day::getLunarMonth()
{
this->checkLunarData();
static const int yueIndex[12] = { 11, 12, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 };
return yueIndex[this->Lmc];
}
int Day::getLunarYear(bool chineseNewYearBoundary)
{
// 以立春为界
if (chineseNewYearBoundary == false)
{
if (this->Lyear == 0)
{
this->checkSSQ();
long double D = SSQPtr->ZQ[3] + (this->d0 < SSQPtr->ZQ[3] ? -365 : 0) + 365.25 * 16 - 35; //以立春为界定纪年
this->Lyear = int2(D / 365.2422 + 0.5);
}
return this->Lyear + 1984;
}
// 以春节为界
if (this->Lyear0 == 0)
{
this->checkSSQ();
int D = SSQPtr->HS[2]; //一般第3个月为春节
for (int j = 0; j < 14; j++)
{ //找春节
if (SSQPtr->ym[j] != 2 || SSQPtr->leap == j && j)
continue;
D = SSQPtr->HS[j];
if (this->d0 < D)
{
D -= 365;
break;
} //无需再找下一个正月
}
D = D + 5810; //计算该年春节与1984年平均春节(立春附近)相差天数估计
this->Lyear0 = int2(D / 365.2422 + 0.5);
}
return this->Lyear0 + 1984;
}
GZ Day::getYearGZ(bool chineseNewYearBoundary)
{
//以春节为界
if (chineseNewYearBoundary)
{
if (this->Lyear3 == NULL)
{
int year = this->getLunarYear(chineseNewYearBoundary) - 1984;
int D = year + 12000;
this->Lyear3 = new GZ(D % 10, D % 12);
}
return *(this->Lyear3);
}
// 以立春为界
if (this->Lyear2 == NULL)
{
int year = this->getLunarYear(false) - 1984;
int D = year + 12000;
this->Lyear2 = new GZ(D % 10, D % 12);
}
return *(this->Lyear2);
}
GZ Day::getMonthGZ()
{
if (this->Lmonth2 == NULL)
{
this->checkSSQ();
int mk = int2((this->d0 - SSQPtr->ZQ[0]) / 30.43685);
//相对大雪的月数计算,mk的取值范围0-12
if (mk < 12 && this->d0 >= SSQPtr->ZQ[2 * mk + 1])
mk++;
//相对于1998年12月7(大雪)的月数,900000为正数基数
int D = mk + int2((SSQPtr->ZQ[12] + 390) / 365.2422) * 12 + 900000;
this->Lmonth2 = new GZ(D % 10, D % 12);
}
return *(this->Lmonth2);
}
GZ Day::getDayGZ()
{
if (this->Lday2 == NULL)
{
int D = this->d0 - 6 + 9000000;
this->Lday2 = new GZ(D % 10, D % 12);
}
return *(this->Lday2);
}
GZ Day::getHourGZ(uint8_t hour, bool isZaoWanZiShi)
{
GZ dayGZ = this->getDayGZ();
return sxtwl::getShiGz(dayGZ.tg, hour, isZaoWanZiShi);
}
bool Day::isLunarLeap()
{
this->checkLunarData();
return this->Lleap;
}
int Day::getSolarYear()
{
this->checkSolarData();
return this->y;
}
uint8_t Day::getSolarMonth()
{
this->checkSolarData();
return this->m;
}
int Day::getSolarDay()
{
this->checkSolarData();
return this->d;
}
uint8_t Day::getWeek()
{
if (this->week == 0xFF)
{
this->week = (this->d0 + J2000 + 1 + 7000000) % 7;
}
return this->week;
}
// 处于该月的第几周
uint8_t Day::getWeekIndex()
{
int i = (this->getSolarDay() - 1) % 7;
int w0 = 0;
if (this->getWeek() >= i)
{
w0 = this->getWeek() - i;
}
else
{
w0 = this->getWeek() + 7 - i;
}
return int2((w0 + this->getSolarDay() - 1) / 7) + 1;
}
//是否有节气
bool Day::hasJieQi()
{
this->checkJQData();
return this->qk != -1;
}
// 获取节气
uint8_t Day::getJieQi()
{
this->checkJQData();
return this->qk;
}
double Day::getJieQiJD()
{
if (this->jqjd != 0)
{
return this->jqjd;
}
long double d, xn, jd2 = this->d0 + dt_T(this->d0) - (long double)8 / (long double)24;
long double w = XL::S_aLon(jd2 / 36525, 3);
w = int2((w - 0.13) / pi2 * 24) * pi2 / 24;
int D = 0;
do
{
d = qi_accurate(w);
D = int2(d + 0.5);
// 计算出的节令值
xn = int2(w / pi2 * 24 + 24000006.01) % 24;
w += pi2 / 24;
if (D > this->d0)
break;
if (D < this->d0)
continue;
if (D == this->d0)
{
Time t1 = JD::JD2DD(d);
Time t2 = JD::JD2DD(D + J2000);
t2.h = t1.h;
t2.m = t1.m;
t2.s = t1.s;
auto jd = JD::toJD(t2);
this->jqjd = jd;
this->qk = xn;
break;
}
} while (D + 12 < this->d0);
return this->jqjd; //+ J2000;
}
// 获取星座
uint8_t Day::getConstellation()
{
if (this->XiZ == 0xFF)
{
this->checkSSQ();
int mk = int2((this->d0 - SSQPtr->ZQ[0] - 15) / 30.43685);
//星座所在月的序数,(如果j=13,ob.d0不会超过第14号中气)
if (mk < 11 && this->d0 >= SSQPtr->ZQ[2 * mk + 2])
{
mk++;
}
this->XiZ = (mk + 12) % 12;
}
return this->XiZ;
}