#include "stdafx.h" #ifdef _DEBUG #define new DEBUG_NEW #undef THIS_FILE static char THIS_FILE[] = __FILE__; #endif struct ConvDate { int Source; // ==0 则输入日期为西历, !=0 则输入为农历 int SolarYear; //输出或输入之西历年份 YYYY int SolarMonth; //西历月 MM int SolarDate; //西历日 DD int LunarYear; //输出或输入之农历年份 YYYY int LunarMonth; //农历月 负数表示闰月 int LunarDate; //农历日 int Weekday; //该日为星期几 (0星期日 1星期一 2星期二 3星期三 4星期四 5星期五 6星期六) int Kan; //该日天干(0甲 1乙 2丙 3丁 4戊 5己 6庚 7辛 8壬 9癸) int Chih; //该日地支(0子 1丑 2寅 3卯 4辰 5巳 6午 7未 8申 9酉 10戌 11亥) }; struct tagLunarCal { char BaseDays; //西历 1 月 1 日到农历正月初一的累积日数 char Intercalation; //闰月月份. 0==此年没有闰月 char BaseWeekday; //此年西历 1 月 1 日为星期几再减 1 char BaseKanChih; //此年西历 1 月 1 日到干支序号减 1 char MonthDays[13]; //此农历年每月之大小, 0==小月(29日), 1==大月(30日) }; struct tagLunarCal LunarCal[] = { { 23, 3, 2, 17, 1, 0, 0, 1, 0, 0, 1, 1, 0, 1, 1, 1, 0 }, /* 1936 */ { 41, 0, 4, 23, 1, 0, 0, 1, 0, 0, 1, 0, 1, 1, 1, 0, 1 }, { 30, 7, 5, 28, 1, 1, 0, 0, 1, 0, 0, 1, 0, 1, 1, 0, 1 }, { 49, 0, 6, 33, 1, 1, 0, 0, 1, 0, 0, 1, 0, 1, 0, 1, 1 }, { 38, 0, 0, 38, 1, 1, 0, 1, 0, 1, 0, 0, 1, 0, 1, 0, 1 }, /* 1940 */ { 26, 6, 2, 44, 1, 1, 0, 1, 1, 0, 1, 0, 0, 1, 0, 1, 0 }, { 45, 0, 3, 49, 1, 0, 1, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0 }, { 35, 0, 4, 54, 0, 1, 0, 1, 0, 1, 1, 0, 1, 0, 1, 0, 1 }, { 24, 4, 5, 59, 1, 0, 1, 0, 1, 0, 1, 0, 1, 1, 0, 1, 1 }, /* 1944 */ { 43, 0, 0, 5, 0, 0, 1, 0, 0, 1, 0, 1, 1, 1, 0, 1, 1 }, { 32, 0, 1, 10, 1, 0, 0, 1, 0, 0, 1, 0, 1, 1, 0, 1, 1 }, { 21, 2, 2, 15, 1, 1, 0, 0, 1, 0, 0, 1, 0, 1, 0, 1, 1 }, { 40, 0, 3, 20, 1, 0, 1, 0, 1, 0, 0, 1, 0, 1, 0, 1, 1 }, /* 1948 */ { 28, 7, 5, 26, 1, 0, 1, 1, 0, 1, 0, 0, 1, 0, 1, 0, 1 }, { 47, 0, 6, 31, 0, 1, 1, 0, 1, 1, 0, 0, 1, 0, 1, 0, 1 }, { 36, 0, 0, 36, 1, 0, 1, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0 }, { 26, 5, 1, 41, 0, 1, 0, 1, 0, 1, 0, 1, 1, 0, 1, 0, 1 }, /* 1952 */ { 44, 0, 3, 47, 0, 1, 0, 0, 1, 1, 0, 1, 1, 0, 1, 0, 1 }, { 33, 0, 4, 52, 1, 0, 1, 0, 0, 1, 0, 1, 1, 0, 1, 1, 0 }, { 23, 3, 5, 57, 0, 1, 0, 1, 0, 0, 1, 0, 1, 0, 1, 1, 1 }, { 42, 0, 6, 2, 0, 1, 0, 1, 0, 0, 1, 0, 1, 0, 1, 1, 1 }, /* 1956 */ { 30, 8, 1, 8, 1, 0, 1, 0, 1, 0, 0, 1, 0, 1, 0, 1, 0 }, { 48, 0, 2, 13, 1, 1, 1, 0, 1, 0, 0, 1, 0, 1, 0, 1, 0 }, { 38, 0, 3, 18, 0, 1, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1 }, { 27, 6, 4, 23, 1, 0, 1, 0, 1, 1, 0, 1, 0, 1, 0, 1, 0 }, /* 1960 */ { 45, 0, 6, 29, 1, 0, 1, 0, 1, 0, 1, 1, 0, 1, 0, 1, 0 }, { 35, 0, 0, 34, 0, 1, 0, 0, 1, 0, 1, 1, 0, 1, 1, 0, 1 }, { 24, 4, 1, 39, 1, 0, 1, 0, 0, 1, 0, 1, 0, 1, 1, 1, 0 }, { 43, 0, 2, 44, 1, 0, 1, 0, 0, 1, 0, 1, 0, 1, 1, 1, 0 }, /* 1964 */ { 32, 0, 4, 50, 0, 1, 0, 1, 0, 0, 1, 0, 0, 1, 1, 0, 1 }, { 20, 3, 5, 55, 1, 1, 1, 0, 1, 0, 0, 1, 0, 0, 1, 1, 0 }, { 39, 0, 6, 0, 1, 1, 0, 1, 1, 0, 0, 1, 0, 1, 0, 1, 0 }, { 29, 7, 0, 5, 0, 1, 0, 1, 1, 0, 1, 0, 1, 0, 1, 0, 1 }, /* 1968 */ { 47, 0, 2, 11, 0, 1, 0, 1, 0, 1, 1, 0, 1, 0, 1, 0, 1 }, { 36, 0, 3, 16, 1, 0, 0, 1, 0, 1, 1, 0, 1, 1, 0, 1, 0 }, { 26, 5, 4, 21, 0, 1, 0, 0, 1, 0, 1, 0, 1, 1, 1, 0, 1 }, { 45, 0, 5, 26, 0, 1, 0, 0, 1, 0, 1, 0, 1, 1, 0, 1, 1 }, /* 1972 */ { 33, 0, 0, 32, 1, 0, 1, 0, 0, 1, 0, 0, 1, 1, 0, 1, 1 }, { 22, 4, 1, 37, 1, 1, 0, 1, 0, 0, 1, 0, 0, 1, 1, 0, 1 }, { 41, 0, 2, 42, 1, 1, 0, 1, 0, 0, 1, 0, 0, 1, 0, 1, 1 }, { 30, 8, 3, 47, 1, 1, 0, 1, 0, 1, 0, 1, 0, 0, 1, 0, 1 }, /* 1976 */ { 48, 0, 5, 53, 1, 0, 1, 1, 0, 1, 0, 1, 0, 1, 0, 0, 1 }, { 37, 0, 6, 58, 1, 0, 1, 1, 0, 1, 1, 0, 1, 0, 1, 0, 1 }, { 27, 6, 0, 3, 1, 0, 0, 1, 0, 1, 1, 0, 1, 1, 0, 1, 0 }, { 46, 0, 1, 8, 1, 0, 0, 1, 0, 1, 0, 1, 1, 0, 1, 1, 0 }, /* 1980 */ { 35, 0, 3, 14, 0, 1, 0, 0, 1, 0, 0, 1, 1, 0, 1, 1, 1 }, { 24, 4, 4, 19, 1, 0, 1, 0, 0, 1, 0, 0, 1, 0, 1, 1, 1 }, { 43, 0, 5, 24, 1, 0, 1, 0, 0, 1, 0, 0, 1, 0, 1, 1, 1 }, { 32, 10, 6, 29, 1, 0, 1, 1, 0, 0, 1, 0, 0, 1, 0, 1, 1 }, /* 1984 */ { 50, 0, 1, 35, 0, 1, 1, 0, 1, 0, 1, 0, 0, 1, 0, 1, 0 }, { 39, 0, 2, 40, 0, 1, 1, 0, 1, 1, 0, 1, 0, 1, 0, 0, 1 }, { 28, 6, 3, 45, 1, 0, 1, 0, 1, 1, 0, 1, 1, 0, 1, 0, 0 }, { 47, 0, 4, 50, 1, 0, 1, 0, 1, 0, 1, 1, 0, 1, 1, 0, 1 }, /* 1988 */ { 36, 0, 6, 56, 1, 0, 0, 1, 0, 0, 1, 1, 0, 1, 1, 1, 0 }, { 26, 5, 0, 1, 0, 1, 0, 0, 1, 0, 0, 1, 0, 1, 1, 1, 1 }, { 45, 0, 1, 6, 0, 1, 0, 0, 1, 0, 0, 1, 0, 1, 1, 1, 0 }, { 34, 0, 2, 11, 0, 1, 1, 0, 0, 1, 0, 0, 1, 0, 1, 1, 0 }, /* 1992 */ { 22, 3, 4, 17, 0, 1, 1, 0, 1, 0, 1, 0, 0, 1, 0, 1, 0 }, { 40, 0, 5, 22, 1, 1, 1, 0, 1, 0, 1, 0, 0, 1, 0, 1, 0 }, { 30, 8, 6, 27, 0, 1, 1, 0, 1, 0, 1, 1, 0, 0, 1, 0, 1 }, { 49, 0, 0, 32, 0, 1, 0, 1, 1, 0, 1, 0, 1, 1, 0, 0, 1 }, /* 1996 */ { 37, 0, 2, 38, 1, 0, 1, 0, 1, 0, 1, 1, 0, 1, 1, 0, 1 }, { 27, 5, 3, 43, 1, 0, 0, 1, 0, 0, 1, 1, 0, 1, 1, 0, 1 }, { 46, 0, 4, 48, 1, 0, 0, 1, 0, 0, 1, 0, 1, 1, 1, 0, 1 }, { 35, 0, 5, 53, 1, 1, 0, 0, 1, 0, 0, 1, 0, 1, 1, 0, 1 }, /* 2000 */ { 23, 4, 0, 59, 1, 1, 0, 1, 0, 1, 0, 0, 1, 0, 1, 0, 1 }, { 42, 0, 1, 4, 1, 1, 0, 1, 0, 1, 0, 0, 1, 0, 1, 0, 1 }, { 31, 0, 2, 9, 1, 1, 0, 1, 1, 0, 1, 0, 0, 1, 0, 1, 0 }, { 21, 2, 3, 14, 0, 1, 0, 1, 1, 0, 1, 0, 1, 0, 1, 0, 1 }, /* 2004 */ { 39, 0, 5, 20, 0, 1, 0, 1, 0, 1, 1, 0, 1, 0, 1, 0, 1 }, { 28, 7, 6, 25, 1, 0, 1, 0, 1, 0, 1, 0, 1, 1, 0, 1, 1 }, { 48, 0, 0, 30, 0, 0, 1, 0, 0, 1, 0, 1, 1, 1, 0, 1, 1 }, { 37, 0, 1, 35, 1, 0, 0, 1, 0, 0, 1, 0, 1, 1, 0, 1, 1 }, /* 2008 */ { 25, 5, 3, 41, 1, 1, 0, 0, 1, 0, 0, 1, 0, 1, 0, 1, 1 }, { 44, 0, 4, 46, 1, 0, 1, 0, 1, 0, 0, 1, 0, 1, 0, 1, 1 }, { 33, 0, 5, 51, 1, 0, 1, 1, 0, 1, 0, 0, 1, 0, 1, 0, 1 }, { 22, 4, 6, 56, 1, 0, 1, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0 }, /* 2012 */ { 40, 0, 1, 2, 1, 0, 1, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0 }, { 30, 9, 2, 7, 0, 1, 0, 1, 0, 1, 0, 1, 1, 0, 1, 0, 1 }, { 49, 0, 3, 12, 0, 1, 0, 0, 1, 0, 1, 1, 1, 0, 1, 0, 1 }, { 38, 0, 4, 17, 1, 0, 1, 0, 0, 1, 0, 1, 1, 0, 1, 1, 0 }, /* 2016 */ { 27, 6, 6, 23, 0, 1, 0, 1, 0, 0, 1, 0, 1, 0, 1, 1, 1 }, { 46, 0, 0, 28, 0, 1, 0, 1, 0, 0, 1, 0, 1, 0, 1, 1, 0 }, { 35, 0, 1, 33, 0, 1, 1, 0, 1, 0, 0, 1, 0, 0, 1, 1, 0 }, { 24, 4, 2, 38, 0, 1, 1, 1, 0, 1, 0, 0, 1, 0, 1, 0, 1 }, /* 2020 */ { 42, 0, 4, 44, 0, 1, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1 }, { 31, 0, 5, 49, 1, 0, 1, 0, 1, 1, 0, 1, 0, 1, 0, 1, 0 }, { 21, 2, 6, 54, 0, 1, 0, 1, 0, 1, 0, 1, 1, 0, 1, 0, 1 }, { 40, 0, 0, 59, 0, 1, 0, 0, 1, 0, 1, 1, 0, 1, 1, 0, 1 }, /* 2024 */ { 28, 6, 2, 5, 1, 0, 1, 0, 0, 1, 0, 1, 0, 1, 1, 1, 0 }, { 47, 0, 3, 10, 1, 0, 1, 0, 0, 1, 0, 0, 1, 1, 1, 0, 1 }, { 36, 0, 4, 15, 1, 1, 0, 1, 0, 0, 1, 0, 0, 1, 1, 0, 1 }, { 25, 5, 5, 20, 1, 1, 1, 0, 1, 0, 0, 1, 0, 0, 1, 1, 0 }, /* 2028 */ { 43, 0, 0, 26, 1, 1, 0, 1, 0, 1, 0, 1, 0, 0, 1, 0, 1 }, { 32, 0, 1, 31, 1, 1, 0, 1, 1, 0, 1, 0, 1, 0, 1, 0, 0 }, { 22, 3, 2, 36, 0, 1, 1, 0, 1, 0, 1, 1, 0, 1, 0, 1, 0 }}; const int FIRST_YEAR = 1936; // The first year in LunarCal[] const int LAST_YEAR = FIRST_YEAR + sizeof(LunarCal)/sizeof(struct tagLunarCal) - 1; // 西历年平年每月之日数 int arr_nDays[12] = {31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31}; // 西历年每月之累积日数, 平年与闰年 第一行平年,第二行闰年 int SolarDays[2][14] = {{0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334, 365, 396 },{0, 31, 60, 91, 121, 152, 182, 213, 244, 274, 305, 335, 366, 397 }}; #define NO_ERROR 0 const char INPUT_YEAR_ERROR = 1; const char INPUT_MONTH_ERROR = 2; const char INPUT_DAY_ERROR = 3; /* int main(int argc, char*argv[]) { struct ConvDate stConvDate; printf("0. 阳历转化为阴历\n1. 阴历转化为阳历\n"); scanf("%d",&stConvDate.Source); if (stConvDate.Source == 0) { printf("输入年份:"); scanf("%d",&stConvDate.SolarYear); printf("\n输入月份:"); scanf("%d",&stConvDate.SolarMonth); printf("\n输入日期:"); scanf("%d",&stConvDate.SolarDate); } else { printf("输入年份:"); scanf("%d",&stConvDate.LunarYear); printf("\n输入月份:"); scanf("%d",&stConvDate.LunarMonth); printf("\n输入日期:"); scanf("%d",&stConvDate.LunarDate); } switch(CalConv(&stConvDate)) { case INPUT_YEAR_ERROR: printf("INPUT_YEAR_ERROR\n"); break; case INPUT_MONTH_ERROR: printf("INPUT_MONTH_ERROR\n"); break; case INPUT_DAY_ERROR: printf("INPUT_DAY_ERROR\n"); break; default: printf("YYMMDD: %d %d %d Week:%d Kan:%d Chih:%d\n", stConvDate.LunarYear,stConvDate.LunarMonth,stConvDate.LunarDate, stConvDate.Weekday,stConvDate.Kan,stConvDate.Chih); } return 0; }*/ // 求此西历年是否为闰年, 返回 0 为平年, 1 为闰年 int IsLeap(int _nYear ) { if ( _nYear % 400 == 0 ) return 1; else if ( _nYear % 100 == 0 ) return 0; else if ( _nYear % 4 == 0 ) return 1; else return 0; } // 西历农历转换 char CalConv( struct ConvDate *_stDate ) { int nIsLeap; int nMonthDay; int nSolarMonth; int nYearOffset; int im; int l1; int l2; int nDayOfYear; int i; int lm; int nKanChih; if ( _stDate->Source == 0 ) // ==0 输入阳历,否则输出阴历 { if ( _stDate->SolarYear <= FIRST_YEAR || _stDate->SolarYear > LAST_YEAR ) //检查输入年份错误 { return INPUT_YEAR_ERROR; } nSolarMonth = _stDate->SolarMonth - 1; //对齐数组下标 if ( nSolarMonth < 0 || nSolarMonth > 11 ) //检查输入月份错误 { return INPUT_MONTH_ERROR; } nIsLeap = IsLeap( _stDate->SolarYear ); //判断是否闰年 闰年为1 平年为0 if ( nSolarMonth == 1 ) // 根据平年闰年计算 2月天数 { nMonthDay = nIsLeap + 28; // 是闰年 2 月加一天 } else //其他月份天数 { nMonthDay = arr_nDays[nSolarMonth]; } if ( _stDate->SolarDate < 1 || _stDate->SolarDate > nMonthDay ) // 检查输入日期是否有误 { return INPUT_DAY_ERROR; } nYearOffset = _stDate->SolarYear - FIRST_YEAR; //年份在表里面的偏移,对齐数组 nDayOfYear = SolarDays[nIsLeap][nSolarMonth] + _stDate->SolarDate; //每个阳历年的第几天 _stDate->Weekday = ( nDayOfYear + LunarCal[nYearOffset].BaseWeekday ) % 7; //算出星期几 nKanChih = nDayOfYear + LunarCal[nYearOffset].BaseKanChih; //由天干地支的基数得出 _stDate->Kan = nKanChih % 10; //算天干 _stDate->Chih = nKanChih % 12; //算地支 if ( nDayOfYear < LunarCal[nYearOffset].BaseDays + 1 ) //过了元旦,但还没过春节 { nYearOffset--; _stDate->LunarYear = _stDate->SolarYear - 1; nIsLeap = IsLeap( _stDate->LunarYear ); nSolarMonth += 12; nDayOfYear = SolarDays[nIsLeap][nSolarMonth] + _stDate->SolarDate; } else //年份一致的时间 { _stDate->LunarYear = _stDate->SolarYear; } l1 = LunarCal[nYearOffset].BaseDays; for ( i=0; i<13; i++ ) { l2 = l1 + LunarCal[nYearOffset].MonthDays[i] + 29; if ( nDayOfYear <= l2 ) break; l1 = l2; } _stDate->LunarMonth = i + 1; _stDate->LunarDate = nDayOfYear - l1; im = LunarCal[nYearOffset].Intercalation; if ( im != 0 && _stDate->LunarMonth > im ) { _stDate->LunarMonth--; if ( _stDate->LunarMonth == im ) _stDate->LunarMonth = -im; } if ( _stDate->LunarMonth > 12 ) _stDate->LunarMonth -= 12; } else //输入阴历,输出阳历 { if ( _stDate->LunarYear < FIRST_YEAR || _stDate->LunarYear >= LAST_YEAR ) //输入之年份错误 { return INPUT_YEAR_ERROR; } nYearOffset = _stDate->LunarYear - FIRST_YEAR; im = LunarCal[nYearOffset].Intercalation; lm = _stDate->LunarMonth; if ( lm < 0 ) { if ( lm != -im ) return INPUT_MONTH_ERROR; } else if ( lm < 1 || lm > 12 ) return INPUT_MONTH_ERROR; if ( im != 0 ) { if ( lm > im ) lm++; else if ( lm == -im ) lm = im + 1; } lm--; if ( _stDate->LunarDate > LunarCal[nYearOffset].MonthDays[lm] + 29 ) return INPUT_DAY_ERROR; nDayOfYear = LunarCal[nYearOffset].BaseDays; for ( i=0; iLunarDate; nIsLeap = IsLeap( _stDate->LunarYear ); for ( i=13; i>=0; i-- ) { if ( nDayOfYear > SolarDays[nIsLeap][i] ) break; } _stDate->SolarDate = nDayOfYear - SolarDays[nIsLeap][i]; if ( i <= 11 ) { _stDate->SolarYear = _stDate->LunarYear; _stDate->SolarMonth = i + 1; } else { _stDate->SolarYear = _stDate->LunarYear + 1; _stDate->SolarMonth = i - 11; } nIsLeap = IsLeap( _stDate->SolarYear ); nYearOffset = _stDate->SolarYear - FIRST_YEAR; nDayOfYear = SolarDays[nIsLeap][_stDate->SolarMonth-1] + _stDate->SolarDate; _stDate->Weekday = ( nDayOfYear + LunarCal[nYearOffset].BaseWeekday ) % 7; nKanChih = nDayOfYear + LunarCal[nYearOffset].BaseKanChih; _stDate->Kan = nKanChih % 10; _stDate->Chih = nKanChih % 12; } return NO_ERROR; } void GongToLongOld(CString &date) { if(date.GetLength()!=10)return; struct ConvDate stConvDate; stConvDate.Source=0;//公转农 stConvDate.SolarYear=atoi(date.Mid (0,4)); stConvDate.SolarMonth=atoi(date.Mid (5,2)); stConvDate.SolarDate=atoi(date.Mid (8,2)); date="2020-13-33"; if(0!=CalConv(&stConvDate))return; date.Format ("%04d-%02d-%02d", stConvDate.LunarYear,stConvDate.LunarMonth,stConvDate.LunarDate ); } void LongToGong(CString &date) { if(date.GetLength()!=10)return; struct ConvDate stConvDate; stConvDate.Source=1;//农转公 stConvDate.LunarYear=atoi(date.Mid (0,4)); stConvDate.LunarMonth=atoi(date.Mid (5,2)); stConvDate.LunarDate=atoi(date.Mid (8,2)); date="2020-13-33"; if(0!=CalConv(&stConvDate))return; date.Format ("%04d-%02d-%02d", stConvDate.SolarYear,stConvDate.SolarMonth,stConvDate.SolarDate ); }