代码,改自 农历01(http://www.cnblogs.com/cppskill/p/5930558.html)

1、main.cpp

#include "Lunar_ZC.h"
#include <stdio.h> void main()
{
//WORD iYear = 2016, iMonth = 10, iDay = 16;
//WORD iYear = 1903, iMonth = 5, iDay = 27; // 阴历为 1903年5月初一
WORD iYear = , iMonth = , iDay = ; // 阴历为 1903年闰5月初一
WORD iLunarYear = , iLunarMonth = , iLunarDay = ;
BOOL lbIsLeapMonth = ; TLunar* pLunar = new TLunar();
pLunar->l_CalcLunarDate(iLunarYear, iLunarMonth, iLunarDay, lbIsLeapMonth, pLunar->CalcDateDiff(iYear, iMonth, iDay));
printf("%d,%d,%d, 闰月?:%d\n", iLunarYear, iLunarMonth, iLunarDay, lbIsLeapMonth); iYear = ;
iMonth = ;
iDay = ;
LONG lRtn = pLunar->CalcDateDiff_01(, );
printf("%d\n", lRtn); printf("\n"); for (int i=; i<=; i++)
{
int iDays = pLunar->GetLunarYearDays(i);
printf("[%03d] : %d\n", i-, iDays);
} int iDaysTotal = ;
for (int j=; j<=; j++)
{
int iDays = pLunar->GetLunarYearDays(j);
iDaysTotal += iDays;
//printf("(%03d) : %d\n", j-1900, iDaysTotal);
printf("%d,", iDaysTotal);
if (j % == )
printf("\n");
}
}
/*
354, 709, 1092, 1446, 1801, 2185, 2539, 2894, 3278, 3632,
4016, 4370, 4724, 5108, 5463, 5817, 6201, 6556, 6940, 7294,
7648, 8032, 8386, 8740, 9125, 9479, 9834,10218,10572,10955,
11309,11664,12048,12403,12757,13141,13495,13879,14233,14587,
14971,15326,15680,16065,16419,16773,17157,17511,17895,18249,
18604,18988,19342,19697,20081,20435,20818,21173,21527,21911,
22266,22620,23004,23359,23712,24096,24451,24835,25189,25544,
25928,26282,26636,27020,27374,27758,28112,28467,28851,29206,
29560,29944,30298,30682,31036,31390,31774,32129,32484,32868,
33222,33576,33959,34314,34698,35052,35407,35791,36145,36499,
36883,37237,37592,37976,38330,38715,39069,39423,39807,40161,
40515,40899,41254,41638,41992,42347,42731,43085,43439,43823,
44177,44532,44916,45270,45654,46008,46362,46746,47101,47455,
47839,48194,48578,48932,49286,49670,50024,50378,50762,51117,
51472,51856,52210,52594,52948,53302,53686,54040,54395,54779,
*/

2、类 TLunar

  2.1、Lunar_ZC.h

#ifndef __LUNAR_ZC_20161015__
#define __LUNAR_ZC_20161015__ #include <windows.h> extern const WORD START_YEAR;
extern const WORD END_YEAR ; class TLunar
{
public:
WORD m_wYear, m_wMonth, m_wDay; TLunar(WORD _wYear, WORD _wMonth, WORD _wDay);
TLunar(); BOOL SetDate(WORD _wYear , WORD _wMonth , WORD _wDay);
void l_InitData(); //=====================================================================================// //返回 公历_wYear年_wMonth月的天数 1年1月 --- 65535年12月
static WORD MonthDays(WORD _wYear, WORD _wMonth); //判断 公历_wYear是不是闰年
static BOOL IsLeapYear(WORD _wYear)
{
return ( !(_wYear%)&&(_wYear%) ) || ( !(_wYear%) );
} //=====================================================================================// static LONG CalcDateDiff_01(WORD _wEndYear, WORD _wStartYear); //计算 公历两个日期间相差的天数 1年1月1日 --- 65535年12月31日
static LONG CalcDateDiff(WORD _wEndYear, WORD _wEndMonth, WORD _wEndDay,
WORD _wStartYear = START_YEAR, WORD _wStartMonth =, WORD _wStartDay =); public:
//计算从 公历1901年1月1日过iSpanDays天后的 阴历日期
static void l_CalcLunarDate(WORD &_wYear, WORD &_wMonth, WORD &_wDay, BOOL &_lbIsLeepMonth, LONG _lSpanDays); //返回阴历iLunarYear年的闰月月份,如没有返回0
// 1901年1月---2050年12月
static WORD GetLunarLeapMonth(WORD _wLunarYear); //返回阴历_wLunarYear年阴历_wLunarMonth月的天数,
//如果_wLunarMonth为闰月,高字为第二个_wLunarMonth月的天数,否则高字为0 。
// 1901年1月---2050年12月
static LONG GetLunarMonthDays(WORD _wLunarYear, WORD _wLunarMonth); //返回阴历iLunarYear年的总天数
// 1901年1月---2050年12月
static WORD GetLunarYearDays(WORD _wLunarYear);
}; #endif// __LUNAR_ZC_20161015__

  2.2、Lunar_ZC.cpp

#include "Lunar_ZC.h"
#include <windows.h> /*
ZC: 中/英文
农历 : Lunar calendar
闰月 : Leap month
*/ extern WORD g_wordsLunarMonthDay[];
extern BYTE g_bytesLunarMonth[]; const WORD START_YEAR =;
const WORD END_YEAR =; //===========================================================================//
TLunar::TLunar(WORD _wYear, WORD _wMonth, WORD _wDay)
{
if(! SetDate(_wYear, _wMonth, _wDay))
l_InitData();
}
//===========================================================================//
TLunar::TLunar()
{
l_InitData();
}
//===========================================================================//
BOOL TLunar::SetDate(WORD _wYear, WORD _wMonth, WORD _wDay)
{
if (_wYear < START_YEAR || _wYear > END_YEAR || _wMonth < || _wMonth >)
return FALSE; if (_wDay < || _wDay > MonthDays(_wYear, _wMonth))
return FALSE; m_wYear = _wYear;
m_wMonth = _wMonth;
m_wDay = _wDay; return TRUE;
}
//===========================================================================//
void TLunar::l_InitData()
{
SYSTEMTIME systime;
::GetSystemTime(&systime); m_wYear = systime.wYear;
m_wMonth = systime.wMonth;
m_wDay = systime.wDay;
} //===========================================================================//
WORD TLunar::MonthDays(WORD _wYear, WORD _wMonth)
{
switch(_wMonth)
{
case : //一 (月)
case : //三 (月)
case : //五 (月)
case : //七 (月)
case : //八 (月)
case ://十 (月)
case ://十二(月)
return ; case : //四 (月)
case : //六 (月)
case : //九 (月)
case ://十一(月)
return ; case : //二 (月)
//如果是闰年
if(IsLeapYear(_wYear))
return ;
else
return ; }
return ;
} LONG TLunar::CalcDateDiff_01(WORD _wEndYear, WORD _wStartYear)
{
//计算两个年份1月1日之间相差的天数
// ZC: 这里应该是处理 闰年多出来的天数
LONG lDiffDays01 = (_wEndYear-)/ - (_wStartYear-)/;
LONG lDiffDays02 = ( (_wEndYear-)/ - (_wStartYear-)/ );
LONG lDiffDays03 = (_wEndYear-)/ - (_wStartYear-)/; LONG lDiffDays = (_wEndYear - _wStartYear) * ;
lDiffDays += lDiffDays01;
lDiffDays -= lDiffDays02;
lDiffDays += lDiffDays03; return lDiffDays;
} //===========================================================================//
LONG TLunar::CalcDateDiff(WORD _wEndYear, WORD _wEndMonth, WORD _wEndDay,
WORD _wStartYear, WORD _wStartMonth, WORD _wStartDay)
{
WORD monthday[] = {, , ,, , , , , , , , }; //计算两个年份1月1日之间相差的天数
LONG lDiffDays = CalcDateDiff_01(_wEndYear, _wStartYear); //加上iEndYear年1月1日到iEndMonth月iEndDay日之间的天数
lDiffDays += monthday[_wEndMonth-] + ( IsLeapYear(_wEndYear) && (_wEndMonth > ? : ) );
lDiffDays += _wEndDay; //减去iStartYear年1月1日到iStartMonth月iStartDay日之间的天数
lDiffDays -= monthday[_wStartMonth-] + ( IsLeapYear(_wStartYear) && (_wStartMonth > ? : ) );
lDiffDays -= _wStartDay; return lDiffDays;
}
//===========================================================================//
void TLunar::l_CalcLunarDate(WORD &_wYear, WORD &_wMonth, WORD &_wDay, BOOL &_lbIsLeepMonth, LONG _lSpanDays)
{
//阳历1901年2月19日 为 阴历1901年正月初一
//阳历1901年1月1日 到 2月19日 共有49天
if(_lSpanDays <)
{
_wYear = START_YEAR - ;
if(_lSpanDays < )
{
_wMonth = ;
_wDay = + WORD(_lSpanDays);
}
else
{
_wMonth = ;
_wDay = WORD(_lSpanDays) - ;
}
return;
} //下面从阴历1901年正月初一算起
_lSpanDays -= ;
_wYear = START_YEAR;
_wMonth = ;
_wDay = ;
//计算年
LONG tmp = GetLunarYearDays(_wYear);
while(_lSpanDays >= tmp)
{
_lSpanDays -= tmp;
tmp = GetLunarYearDays(++_wYear);
}
//计算月
tmp = LOWORD(GetLunarMonthDays(_wYear, _wMonth));
while(_lSpanDays >= tmp)
{
_lSpanDays -= tmp;
if(_wMonth == GetLunarLeapMonth(_wYear))
{
tmp = HIWORD(GetLunarMonthDays(_wYear, _wMonth));
if(_lSpanDays < tmp)
{
_lbIsLeepMonth = true;
break;
}
_lSpanDays -= tmp;
}
tmp = LOWORD(GetLunarMonthDays(_wYear, ++_wMonth));
}
//计算日
_wDay += WORD(_lSpanDays);
}
//===========================================================================//
WORD TLunar::GetLunarLeapMonth(WORD _wLunarYear)
{
BYTE &flag = g_bytesLunarMonth[(_wLunarYear - START_YEAR)/]; // ZC: 这里&的作用 和 函数参数中使用&的作用 一样。
return (_wLunarYear - START_YEAR)% ? flag&0x0f : flag>>;
}
//===========================================================================//
/*
ZC: 算法注释: (一年最多只有一个闰月)
以1903年为例,5月为闰月,每月的天数信息为0101 0010 0110 1000 .
if (iLunarMonth==6) :则一开始iBit==16-6=10,∵5月是闰月,∴ 1<<10指向的是闰5月的天数信息,1<<9指向的才是6月的天数信息,∴会有“iBit--”的操作。
if (iLunarMonth==5) :则一开始iBit==16-5=11,∵5月是闰月,∴ 1<<11指向的是第1个5月的天数信息,1<<(11-1)指向的才是闰5月的天数信息。
*/
LONG TLunar::GetLunarMonthDays(WORD _wLunarYear, WORD _wLunarMonth)
{
if (_wLunarYear < START_YEAR)
return 30L; WORD high =, low =;
int iBit = - _wLunarMonth;
WORD wLeapMonth = GetLunarLeapMonth(_wLunarYear); if ( (_wLunarMonth > wLeapMonth) && (wLeapMonth != ) )
{ iBit --; } if(g_wordsLunarMonthDay[_wLunarYear - START_YEAR] & (<<iBit))
{ low = ; }// ZC: 每个月的天数只可能是2个值中的1个:29/30 if(_wLunarMonth == wLeapMonth)
{
if(g_wordsLunarMonthDay[_wLunarYear - START_YEAR] & (<< (iBit -)))
{ high =; }
else
{ high =; }
} return MAKELONG(low, high);
} //===========================================================================//
WORD TLunar::GetLunarYearDays(WORD _wLunarYear)
{
WORD days =;
for(WORD i=; i<=; i++)
{
LONG tmp = GetLunarMonthDays(_wLunarYear ,i);
days += HIWORD(tmp);
days += LOWORD(tmp);
}
return days;
} /*
ZC:
他是这样存储的:(1个WORD存放1年的信息, 实际只是用了高位的12/13个bit位)(高位存放前一个月的信息, 低位存放后一个月的信息)
1901年信息:0x4ae0 ==> 高位->地位的比特位为: 0100 1010 1110 0000, 由g_bytesLunarMonth中的信息可知,该年不是闰年,于是12个月的天数信息依次为0100 1010 1110
1902年信息:0xa570 ==> 高位->地位的比特位为: 1010 0101 0111 0000, 由g_bytesLunarMonth中的信息可知,该年不是闰年,于是12个月的天数信息依次为1010 0101 0111
1903年信息:0x5268 ==> 高位->地位的比特位为: 0101 0010 0110 1000, 由g_bytesLunarMonth中的信息可知,该年 是闰年,于是13个月的天数信息依次为0101 0010 0110 1
我的想法是: 低位存放前一个月的信息,高位存放后一个月的信息,这样在内存中每个WORD从低位到高位 都是1->12月的信息排列(后面也留有空位)。
他的做法 和 我的想法 不一致...
*/
/******************************************************************************
下面为阴历计算所需的数据,为节省存储空间,所以采用下面比较变态的存储方法.
*******************************************************************************/
//数组gLunarDay存入阴历1901年到2100年每年中的月天数信息,
//阴历每月只能是29或30天,一年用12(或13)个二进制位表示,对应位为1表30天,否则为29天
WORD g_wordsLunarMonthDay[]=
{
//测试数据只有1901.1.1 --2050.12.31
0X4ae0, 0Xa570, 0X5268, 0Xd260, 0Xd950, 0X6aa8, 0X56a0, 0X9ad0, 0X4ae8, 0X4ae0, //1910
0Xa4d8, 0Xa4d0, 0Xd250, 0Xd548, 0Xb550, 0X56a0, 0X96d0, 0X95b0, 0X49b8, 0X49b0, //1920
0Xa4b0, 0Xb258, 0X6a50, 0X6d40, 0Xada8, 0X2b60, 0X9570, 0X4978, 0X4970, 0X64b0, //1930
0Xd4a0, 0Xea50, 0X6d48, 0X5ad0, 0X2b60, 0X9370, 0X92e0, 0Xc968, 0Xc950, 0Xd4a0, //1940
0Xda50, 0Xb550, 0X56a0, 0Xaad8, 0X25d0, 0X92d0, 0Xc958, 0Xa950, 0Xb4a8, 0X6ca0, //1950
0Xb550, 0X55a8, 0X4da0, 0Xa5b0, 0X52b8, 0X52b0, 0Xa950, 0Xe950, 0X6aa0, 0Xad50, //1960
0Xab50, 0X4b60, 0Xa570, 0Xa570, 0X5260, 0Xe930, 0Xd950, 0X5aa8, 0X56a0, 0X96d0, //1970
0X4ae8, 0X4ad0, 0Xa4d0, 0Xd268, 0Xd250, 0Xd528, 0Xb540, 0Xb6a0, 0X96d0, 0X95b0, //1980
0X49b0, 0Xa4b8, 0Xa4b0, 0Xb258, 0X6a50, 0X6d40, 0Xada0, 0Xab60, 0X9370, 0X4978, //1990
0X4970, 0X64b0, 0X6a50, 0Xea50, 0X6b28, 0X5ac0, 0Xab60, 0X9368, 0X92e0, 0Xc960, //2000
0Xd4a8, 0Xd4a0, 0Xda50, 0X5aa8, 0X56a0, 0Xaad8, 0X25d0, 0X92d0, 0Xc958, 0Xa950, //2010
0Xb4a0, 0Xb550, 0Xb550, 0X55a8, 0X4ba0, 0Xa5b0, 0X52b8, 0X52b0, 0Xa930, 0X74a8, //2020
0X6aa0, 0Xad50, 0X4da8, 0X4b60, 0X9570, 0Xa4e0, 0Xd260, 0Xe930, 0Xd530, 0X5aa0, //2030
0X6b50, 0X96d0, 0X4ae8, 0X4ad0, 0Xa4d0, 0Xd258, 0Xd250, 0Xd520, 0Xdaa0, 0Xb5a0, //2040
0X56d0, 0X4ad8, 0X49b0, 0Xa4b8, 0Xa4b0, 0Xaa50, 0Xb528, 0X6d20, 0Xada0, 0X55b0, //2050 }; /*
ZC:
他是这样存储的:(高位 放的是 前一年的信息; 低位 放的是 后一年的信息)
1901,1902年的信息为 0x00 ==> 说明 这两年都不是闰年
1903,1904年的信息为 0x50 ==> 1903:5月是闰月; 1904不是闰年
我的想法是: 低位存放前一年信息,高位存放后一年信息,这样在内存中从低位到高位 就是1901->2050年的信息排列。
他的做法 和 我的想法 不一致...
*/
//数组gLanarMonth存放阴历1901年到2050年闰月的月份,如没有则为0,每字节存两年
BYTE g_bytesLunarMonth[]=
{
0X00, 0X50, 0X04, 0X00, 0X20, //1910
0X60, 0X05, 0X00, 0X20, 0X70, //1920
0X05, 0X00, 0X40, 0X02, 0X06, //1930
0X00, 0X50, 0X03, 0X07, 0X00, //1940
0X60, 0X04, 0X00, 0X20, 0X70, //1950
0X05, 0X00, 0X30, 0X80, 0X06, //1960
0X00, 0X40, 0X03, 0X07, 0X00, //1970
0X50, 0X04, 0X08, 0X00, 0X60, //1980
0X04, 0X0a, 0X00, 0X60, 0X05, //1990
0X00, 0X30, 0X80, 0X05, 0X00, //2000
0X40, 0X02, 0X07, 0X00, 0X50, //2010
0X04, 0X09, 0X00, 0X60, 0X04, //2020
0X00, 0X20, 0X60, 0X05, 0X00, //2030
0X30, 0Xb0, 0X06, 0X00, 0X50, //2040
0X02, 0X07, 0X00, 0X50, 0X03 //2050
};

3、

4、

5、

农历03__ZC的更多相关文章

  1. FullCalendar应用——整合农历节气和节日

    FullCalendar用来做日程管理功能非常强大,但是唯一不足的地方是没有将中国农历历法加进去,今天我将结合实例和大家分享如何将中国农历中的节气和节日整合到FullCalendar中,从而增强其实用 ...

  2. php阳历转农历的类 谷歌到的

    <?phpclass Lunar {    var $MIN_YEAR = 1891;    var $MAX_YEAR = 2100;    var $lunarInfo = array(   ...

  3. 带节日和农历的js日历

    带农历的脚本: http://keleyi.com/keleyi/phtml/jstexiao/11.htm http://keleyi.com/tools/rili/ <html> &l ...

  4. atitit.农历的公式与原理以及农历日期运算

    atitit.农历的公式与原理以及农历日期运算 1. 农历的概述1 2. 如何在电脑程序里面计算农历??1 3. 农历的公式2 4. 获取当日农历日历3 5. 历史日期公式加查表才能得到精确日期3 6 ...

  5. 红米3 SudaMod(android_6.01_r72)高配指纹/农历/归属地/SM天气/流畅运行/红外线正常/更新于20161025

    一.写在前面 我只是个人爱好,本ROM未集成任何第三方推广软件,我只是喜欢把好的资源分享出来,若可以,我们一起学习,一起进步. 请不要问我怎么刷机! 请不要问我玩游戏卡不卡(有钱你就换好点的手机)! ...

  6. c#实现万年历示例分享 万年历农历查询

    cs.cs(类页面) using System;using System.Collections.Generic;using System.Linq;using System.Web; namespa ...

  7. 时间星期农历js

    <script> var CalendarData=new Array(20); var madd=new Array(12); var TheDate=new Date(); var n ...

  8. jquery 农历日历 可自适应

    在网上找了许多大牛做的农历日历,但是不是不符合项目中的要求,就是本身就有问题有Bug ,把大牛门的做日历看了n遍 自己又改造了一遍得到了这个:随后日历又要做个自适应的长宽,又在js中改造代码..... ...

  9. 【转】js写显示农历的日期

    网上查找了个,记录下. <body> <!-- 中国农历开始 --> <SCRIPT language=JavaScript> <!-- var lunarI ...

随机推荐

  1. Oracle下select语句

    先看scott下自带的emp表 empno:编号  ename:名字  Job:职位  mgr:上级编号 hiredate:入职时间 sal:薪水 comm:奖金 deptno:部门编号 部门表dep ...

  2. HTTP cookies 详解(国外一位大牛的文章)

    原文:http://blog.csdn.net/lijing198997/article/details/9378047 HTTP cookies,通常又称作"cookies",已 ...

  3. PyCharm安装与配置,python的Hello World

    1. 访问https://www.jetbrains.com/zh/pycharm/download/download-thanks.html, 下载pycharm 安 装包,点击安装. 2. 用记事 ...

  4. 【Python】【爬虫】如何学习Python爬虫?

    如何学习Python爬虫[入门篇]? 路人甲 1 年前 想写这么一篇文章,但是知乎社区爬虫大神很多,光是整理他们的答案就够我这篇文章的内容了.对于我个人来说我更喜欢那种非常实用的教程,这种教程对于想直 ...

  5. .NET、NET Framewor以及.NET Core的关系(一)

    什么是.NET?什么是.NET Framework?本文将从上往下,循序渐进的介绍一系列相关.NET的概念,先从类型系统开始讲起,我将通过跨语言操作这个例子来逐渐引入一系列.NET的相关概念,这主要包 ...

  6. JavaScript类库汇总

    日期处理Moment.js    http://momentjs.cn/  http://momentjs.com/ nodejslinq,jslinq    http://jslinq.codepl ...

  7. Atom飞行手册翻译

    https://www.w3cschool.cn/atomflightmanualzhcn/

  8. 【译】Using Objects to Organize Your Code

    耗了一个晚上吐血翻译不过也学到了不少...<使用对象来组织你的代码>,翻译中发现原作者在原文中有部分代码有误或不全,本文已修改和添加~ 丽贝卡·墨菲原文链接:http://rmurphey ...

  9. ubuntu update-alternatives

    update-alternatives是ubuntu系统中专门维护系统命令链接符的工具,通过它可以很方便的设置系统默认使用哪个命令.哪个软件版本,比如,我们在系统中同时安装了open jdk和sun ...

  10. 4.1 Routing -- Introduction

    一.Routing 1. 当用户与应用程序交互时,它会经过很多状态.Ember.js为你提供了有用的工具去管理它的状态和扩展你的app. 2. 要理解为什么这是重要的,假设我们正在编写一个Web应用程 ...