CalendarConvert.cpp 5.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212
  1. // CalendarConvert.cpp: implementation of the CCalendarConvert class.
  2. // Download by http://www.codefans.net
  3. //////////////////////////////////////////////////////////////////////
  4. #include "stdafx.h"
  5. #include "CalendarConvert.h"
  6. #ifdef _DEBUG
  7. #undef THIS_FILE
  8. static char THIS_FILE[]=__FILE__;
  9. #define new DEBUG_NEW
  10. #endif
  11. //////////////////////////////////////////////////////////////////////
  12. // Construction/Destruction
  13. //////////////////////////////////////////////////////////////////////
  14. CCalendarConvert::CCalendarConvert()
  15. {
  16. }
  17. CCalendarConvert::~CCalendarConvert()
  18. {
  19. }
  20. //
  21. // 得到表示农历通用表示的字串
  22. //
  23. CString CCalendarConvert::GetLunarString ( IN PSYSTEMTIME pSt, BOOL bEmbolism )
  24. {
  25. TCHAR szNongli[30], szNongliDay[10],szShuXiang[10];
  26. /*天干名称*/
  27. const char *cTianGan[] = {"甲","乙","丙","丁","戊","己","庚","辛","壬","癸"};
  28. /*地支名称*/
  29. const char *cDiZhi[] = {"子","丑","寅","卯","辰","巳","午", "未","申","酉","戌","亥"};
  30. /*属相名称*/
  31. const char *cShuXiang[] = {"鼠","牛","虎","兔","龙","蛇","马","羊","猴","鸡","狗","猪"};
  32. /*农历日期名*/
  33. const char *cDayName[] = { "*","初一","初二","初三","初四","初五",
  34. "初六","初七","初八","初九","初十",
  35. "十一","十二","十三","十四","十五",
  36. "十六","十七","十八","十九","二十",
  37. "廿一","廿二","廿三","廿四","廿五",
  38. "廿六","廿七","廿八","廿九","三十"};
  39. /*农历月份名*/
  40. const char *cMonName[] = {"*","正","二","三","四","五","六", "七","八","九","十","十一","腊"};
  41. /*--生成农历天干、地支、属相 ==> wNongli--*/
  42. int nShuXiang = ((pSt->wYear - 4) % 60) % 12;
  43. if ( nShuXiang < 0 || nShuXiang >= sizeof(cShuXiang)/sizeof(cShuXiang[0]) )
  44. return "Error Year";
  45. wsprintf(szShuXiang,"%s",cShuXiang[nShuXiang]);
  46. int nTianGan = ((pSt->wYear - 4) % 60) % 10;
  47. if ( nTianGan < 0 || nTianGan >= sizeof(cTianGan)/sizeof(cTianGan[0]) )
  48. return "Error Year";
  49. int nDiZhi = ((pSt->wYear - 4) % 60) % 12;
  50. if ( nDiZhi < 0 || nDiZhi >= sizeof(cDiZhi)/sizeof(cDiZhi[0]) )
  51. return "Error Year";
  52. wsprintf(szNongli,"%s(%s%s)年",szShuXiang,cTianGan[nTianGan],cDiZhi[nDiZhi]);
  53. /*--生成农历月、日 ==> wNongliDay--*/
  54. if ( pSt->wMonth < 0 || pSt->wMonth >= sizeof(cMonName)/sizeof(cMonName[0]) )
  55. return "Error Month";
  56. if ( bEmbolism )
  57. {
  58. wsprintf(szNongliDay,"闰%s",cMonName[pSt->wMonth]);
  59. }
  60. else
  61. {
  62. strcpy(szNongliDay,cMonName[pSt->wMonth]);
  63. }
  64. strcat(szNongliDay,"月");
  65. if ( pSt->wDay < 0 || pSt->wDay >= sizeof(cDayName)/sizeof(cDayName[0]) )
  66. return "Error Day";
  67. strcat(szNongliDay,cDayName[pSt->wDay]);
  68. return strcat(szNongli,szNongliDay);
  69. }
  70. //
  71. // 公历转农历
  72. //
  73. BOOL CCalendarConvert::Gregorian2Lunar ( IN PSYSTEMTIME pSt, OUT PSYSTEMTIME pDst, OUT BOOL *pEmbolism )
  74. {
  75. if ( !pSt || !pDst || !pEmbolism ) return FALSE;
  76. SYSTEMTIME Dst = {0};
  77. /*公历每月前面的天数*/
  78. const int wMonthAdd[12] = {0,31,59,90,120,151,181,212,243,273,304,334};
  79. /*农历数据*/
  80. const int wNongliData[100] = {2635,333387,1701,1748,267701,694,2391,133423,1175,396438
  81. ,3402,3749,331177,1453,694,201326,2350,465197,3221,3402
  82. ,400202,2901,1386,267611,605,2349,137515,2709,464533,1738
  83. ,2901,330421,1242,2651,199255,1323,529706,3733,1706,398762
  84. ,2741,1206,267438,2647,1318,204070,3477,461653,1386,2413
  85. ,330077,1197,2637,268877,3365,531109,2900,2922,398042,2395
  86. ,1179,267415,2635,661067,1701,1748,398772,2742,2391,330031
  87. ,1175,1611,200010,3749,527717,1452,2742,332397,2350,3222
  88. ,268949,3402,3493,133973,1386,464219,605,2349,334123,2709
  89. ,2890,267946,2773,592565,1210,2651,395863,1323,2707,265877};
  90. static int wCurYear,wCurMonth,wCurDay;
  91. static int nTheDate,nIsEnd,m,k,n,i,nBit;
  92. /*---取当前公历年、月、日---*/
  93. wCurYear = pSt->wYear;
  94. wCurMonth = pSt->wMonth;
  95. wCurDay = pSt->wDay;
  96. /*---计算到初始时间1921年2月8日的天数:1921-2-8(正月初一)---*/
  97. nTheDate = (wCurYear - 1921) * 365 + (wCurYear - 1921) / 4 + wCurDay + wMonthAdd[wCurMonth - 1] - 38;
  98. if ( nTheDate < 0 ) return FALSE;
  99. if((!(wCurYear % 4)) && (wCurMonth > 2))
  100. nTheDate = nTheDate + 1;
  101. /*--计算农历天干、地支、月、日---*/
  102. nIsEnd = 0;
  103. m = 0;
  104. while(nIsEnd != 1)
  105. {
  106. if(wNongliData[m] < 4095)
  107. k = 11;
  108. else
  109. k = 12;
  110. n = k;
  111. while(n>=0)
  112. {
  113. //获取wNongliData(m)的第n个二进制位的值
  114. nBit = wNongliData[m];
  115. for(i=1;i<n+1;i++)
  116. nBit = nBit/2;
  117. nBit = nBit % 2;
  118. if (nTheDate <= (29 + nBit))
  119. {
  120. nIsEnd = 1;
  121. break;
  122. }
  123. nTheDate = nTheDate - 29 - nBit;
  124. n = n - 1;
  125. }
  126. if(nIsEnd)
  127. break;
  128. m = m + 1;
  129. }
  130. wCurYear = 1921 + m;
  131. wCurMonth = k - n + 1;
  132. wCurDay = nTheDate;
  133. if ( wCurDay < 0 ) return FALSE;
  134. if (k == 12)
  135. {
  136. if (wCurMonth == wNongliData[m] / 65536 + 1)
  137. wCurMonth = 1 - wCurMonth;
  138. else if (wCurMonth > wNongliData[m] / 65536 + 1)
  139. wCurMonth = wCurMonth - 1;
  140. }
  141. Dst.wYear = (USHORT)wCurYear;
  142. if (wCurMonth < 1)
  143. {
  144. Dst.wMonth = -wCurMonth;
  145. *pEmbolism = TRUE;
  146. }
  147. else
  148. {
  149. Dst.wMonth = wCurMonth;
  150. *pEmbolism = FALSE;
  151. }
  152. Dst.wDay = wCurDay;
  153. memcpy ( pDst, &Dst, sizeof(SYSTEMTIME) );
  154. return TRUE;
  155. }
  156. //
  157. // 农历转公历
  158. //
  159. BOOL CCalendarConvert::Lunar2Gregorian ( IN PSYSTEMTIME pSt, IN BOOL bEmbolism, OUT PSYSTEMTIME pDst )
  160. {
  161. if ( !pSt || !pDst ) return FALSE;
  162. COleDateTimeSpan Span(1,0,0,0);
  163. COleDateTime tStart ( *pSt );
  164. for ( int i=0; i<100; i++ )
  165. {
  166. SYSTEMTIME Src = {0};
  167. SYSTEMTIME Dst = {0};
  168. BOOL bDstEmbolism = FALSE;
  169. if ( !tStart.GetAsSystemTime ( Src ) )
  170. return FALSE;
  171. if ( !Gregorian2Lunar ( &Src, &Dst, &bDstEmbolism ) )
  172. return FALSE;
  173. if ( Dst.wYear==pSt->wYear && Dst.wMonth==pSt->wMonth && Dst.wDay==pSt->wDay && bEmbolism==bDstEmbolism )
  174. {
  175. memcpy ( pDst, &Src, sizeof(SYSTEMTIME) );
  176. return TRUE;
  177. }
  178. tStart+=Span;
  179. }
  180. return FALSE;
  181. }
  182. COleDateTime CCalendarConvert::ConvertSysTime2OleDateTime(PSYSTEMTIME pSt)
  183. {
  184. ASSERT ( pSt );
  185. COleDateTime t ( *pSt );
  186. return t;
  187. }