代码,改自 农历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. 微信小程序 --- 事件绑定

    事件类别: tap:点击事件: longtap:长按事件: touchstart:触摸开始: touchend:触摸结束: touchcansce:取消触摸: 事件绑定: bind绑定: catch绑 ...

  2. ThinkPHP做自动登陆及异位或加密COOKIE!

    异位或加密方法: /* *登陆如果自动登陆加密 *默认是0解密状态,1是加密 *采用的方法是异位或加密 */ function encrytion($value,$type=0){ $key = md ...

  3. javascript飞机大战-----004创建子弹对象

    /* 创建子弹:因为子弹不是只创建一个所以要用构造函数 注意一点:子弹发射的位置应该是英雄机的正中央的位置,所以需要传点东西进来 */ function Bullet(l,t){ this.l = l ...

  4. supervisor安装篇

    服务器环境: [root@kafka60 supervisor-]# uname -a Linux kafka60 -.el6.x86_64 # SMP Tue May :: UTC x86_64 x ...

  5. CodeForces 19D Points (线段树+set)

    D. Points time limit per test 2 seconds memory limit per test 256 megabytes input standard input out ...

  6. 南京网络赛I-Skr【回文树模板】

    19.32% 1000ms 256000K A number is skr, if and only if it's unchanged after being reversed. For examp ...

  7. ar的主流算法

    基于无标志AR:代表作是PTAM/M,Mixare,将是AR未来的发展方向 跟踪技术可以大致分成两大类,一类是基于特征的跟踪(Feature Based Tracking),比如通过跟踪从输入图像中抽 ...

  8. Database Sharding, The “Shared-Nothing” Approach DATABASE SHARDING

    w将单个服务器上的单个数据库打碎为多个服务器上的单个数据库 http://www.agildata.com/database-sharding/ Database Sharding provides ...

  9. scrapy爬虫系列之七--scrapy_redis的使用

    功能点:如何发送携带cookie访问登录后的页面,如何发送post请求登录 简单介绍: 安装:pip3 install scrapy_redis 在scrapy的基础上实现了更多的功能:如reques ...

  10. linux IO多路复用POLL机制深入分析

    POLL机制的作用这里就不进行介绍,根据linux man手册,解释为在一个文件描述符上等待某个事件.按照抽象一点的理解,当某个事件被触发(条件被满足),文件描述符变为有状态,那么用户空间可以根据此进 ...