#include #include using namespace std; int main() { ////////////////////////////////////////////////////////////////////////////////////////////////////////////////// ///初始化数据 //天干表 const char TianGan[10][3] = {"甲", "乙", "丙", "丁", "戊" , "己", "庚", "辛", "壬", "癸"}; //地支表 const char DiZhi[12][3] = {"子", "丑", "寅", "卯", "辰", "巳" , "午", "未", "申", "酉", "戌", "亥"}; const char ShuXiang[12][3] = {"鼠", "牛", "虎", "兔", "龙", "蛇" , "马", "羊", "猴", "鸡", "狗", "猪"}; const char DayName[30][5] = {"初一", "初二", "初三", "初四", "初五", "初六", "初七", "初八" , "初九", "初十", "十一", "十二", "十三", "十四", "十五", "十六" , "十七", "十八", "十九", "二十", "廿一", "廿二", "廿三", "廿四" , "廿五", "廿六", "廿七", "廿八", "廿九", "三十"}; const char MonName[12][5] = {"正", "二", "三", "四", "五", "六" , "七", "八", "九", "十", "十一", "腊"}; const char WuXing[5][3] = {"木", "火", "土", "金", "水"}; //地支对应的五行表,规律怪,与其计算,还不如查表快 const char wuxing[12][3] = {"水", "土", "木", "木", "土", "火" , "火", "土", "金", "金", "土", "水"}; /* const int NongliData[100]的数据构成: 低16位表示(12个或13个月)每个月是大月还是小月,高16位表示闰哪个月 比如2006年表中10进制464219,16进制0x7155b,二进制 0000 0000 0000 0111 0001 0101 0101 1011 |--------闰7月------|-------98 *765 4321---| (*闰月,这里闰7月) 比如2007年表中10进制605,16进制0x25D,二进制 0000 0000 0000 0000 0000 0010 0101 1011 |--------无闰月-----|--------9 8765 4321---| */ const int NongliData[100] = {2635,333387,1701,1748,267701,694,2391,133423,1175,396438 ,3402,3749,331177,1453,694,201326,2350,465197,3221,3402 ,400202,2901,1386,267611,605,2349,137515,2709,464533,1738 ,2901,330421,1242,2651,199255,1323,529706,3733,1706,398762 ,2741,1206,267438,2647,1318,204070,3477,461653,1386,2413 ,330077,1197,2637,268877,3365,531109,2900,2922,398042,2395 ,1179,267415,2635,661067,1701,1748,398772,2742,2391,330031 ,1175,1611,200010,3749,527717,1452,2742,332397,2350,3222 ,268949,3402,3493,133973,1386,464219,605,2349,334123,2709 ,2890,267946,2773,592565,1210,2651,395863,1323,2707,265877}; //const int MonthAdd[12]是当前月之前的经过的整月天数,二月暂以28天计 const int MonthDay[12] = {0,31,59,90,120,151,181,212,243,273,304,334}; //平年和闰年的月表 const int _Month[2][12]={{31,28,31,30,31,30,31,31,30,31,30,31},{31,29,31,30,31,30,31,31,30,31,30,31}}; ////////////////////////////////////////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////////////////////////////////////// ///输入日期 int year, month, day, hour; cout << "请输入要查询者的相关内容/n" << endl; while (cout << "请输入 年份(1922 - 2021):" && cin >> year) if(year >= 1922 && year <= 2021) break; //闰年计算,其实这里可以不用这么精确的计算,直接year % 4 == 0即可,因为年份跨度不大 int leapyear = (year % 4 == 0) && ((year % 100 != 0)||(year % 400 == 0)) ? 1 : 0; while (cout << "请输入 月份(1 - 12):" && cin >> month) if(month >= 1 && month <= 12) break; while (cout << "请输入 日期(1 - 31):" && cin >> day) if(day >= 1 && day <= _Month[leapyear][month - 1]) break; while (cout << "请输入 时刻(0 - 23):" && cin >> hour) if(hour >= 0 && hour <= 23) break; cout << "/n" << year << " - " << month << " - " << day << " - " << hour << endl; ////////////////////////////////////////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////////////////////////////////////// ///预转换 hour = (++hour) >= 24 ? 0 : hour / 2; //时间转换成时辰 //计算日期差 X<-TheDate->1921-2-8 //1921-2-8(辛酉年庚寅月壬寅日)而1921-1-1(辛酉年戊子月甲子) int sDay = (year - 1921) * 365 + (year - 1921) / 4 + day + MonthDay[month - 1] - 38;//38是代表是从1921-2-8(正月初一)开始计算,而不是1921-1-1,去除38天 //如今年阳历是闰年(2月有29天),而且当前月份大于2月,经历的总天数加1 if((!(year % 4)) && (month > 2)) sDay = sDay + 1; ////////////////////////////////////////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////////////////////////////////////// ///农历数据转换 bool IsEnd = false; int mYear = 0, h = 0, TDMonth = 0, TheDate = sDay, mMonth, n; //逐年逐月减天数 while(!IsEnd) { if(NongliData[mYear] < 4095) //判断是否有闰月 mMonth = 11; else { mMonth = 12; //有闰月,故一年有13个月 ++h; } n = mMonth; while(n >= 0) { int Bit = NongliData[mYear]; Bit = (Bit >> n) & 1; //大小月补差 if (TheDate <= (29 + Bit)) //判断天数是否少于当月实际总天数 { IsEnd = true; break; } ++TDMonth; //农历月份累加 TheDate -= 29 + Bit; --n; } if(IsEnd) break; ++mYear; //农历年份累加 } month = mMonth - n; TDMonth = TDMonth - h; day = TheDate; if (mMonth == 12) //判断闰月及相关数据调整 { if (month < NongliData[mYear] / 65536) ++TDMonth; else if (month == NongliData[mYear] / 65536) //正好是闰月 month = 1 - month; else if (month > NongliData[mYear] / 65536) //如果为闰月后面的月份,月份值调整 --month; } int Tian[4], Di[4]; ///各天干计算:年、月、日、时 Tian[0] = (mYear + 7) % 10; Tian[1] = (TDMonth + 6) % 10; Tian[2] = (sDay + 7) % 10; Tian[3] = ((Tian[2] % 5) * 2 + hour) % 10; ///各地支计算:年、月、日、时 Di[0] = (mYear + 9) % 12; Di[1] = (TDMonth + 2) % 12; Di[2] = (sDay + 1) % 12; Di[3] = hour; const char *theWuXing[8]; ///天干地支对应的五行属性 //年 theWuXing[0] = WuXing[Tian[0] / 2]; theWuXing[1] = wuxing[Di[0]]; //月 theWuXing[2] = WuXing[Tian[1] / 2]; theWuXing[3] = wuxing[Di[1]]; //日 theWuXing[4] = WuXing[Tian[2] / 2]; theWuXing[5] = wuxing[Di[2]]; //时 theWuXing[6] = WuXing[Tian[3] / 2]; theWuXing[7] = wuxing[Di[3]]; //五行统计 bool nWuXing[5] = {true, true, true, true, true}; for(int i = 0; i != 8; ++i) for(int n = 0; n != 5; ++n) if(0 == strcmp(theWuXing[i], WuXing[n] )) nWuXing[n] = false; char NongliStr[7]; sprintf(NongliStr, "%s%s年", TianGan[Tian[0]], DiZhi[Di[0]]); //显示XX年 char NongliDayStr[13]; //显示(闰)X月 if (month < 0) //判断是否为闰月 sprintf(NongliDayStr, "闰%s月", MonName[-1 * month]); else sprintf(NongliDayStr, "%s月", MonName[month]); strcat(NongliDayStr, DayName[day - 1]); ////////////////////////////////////////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////////////////////////////////////// ///结果输出 cout << "/n农历:" << NongliStr << "(" << ShuXiang[(mYear + 9) % 12] << ") " << NongliDayStr << " " << DiZhi[Di[3]] << "时/n" << NongliStr << " " << TianGan[Tian[1]] << DiZhi[Di[1]] << "月 " << TianGan[Tian[2]] << DiZhi[Di[2]] << "日 " << TianGan[Tian[3]] << DiZhi[Di[3]] << "时" << "/n/n八字为:" << TianGan[Tian[0]] << DiZhi[Di[0]] << TianGan[Tian[1]] << DiZhi[Di[1]] << TianGan[Tian[2]] << DiZhi[Di[2]] << TianGan[Tian[3]] << DiZhi[Di[3]] << "/n五行为:" << theWuXing[0] << theWuXing[1] << theWuXing[2] << theWuXing[3] << theWuXing[4] << theWuXing[5] << theWuXing[6] << theWuXing[7] << endl; cout << "五行缺:/t"; for(int i = 0; i != 5; ++i) if(nWuXing[i]) cout << WuXing[i]; cout << endl; ////////////////////////////////////////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////////////////////////////////////// return 0; }