计算农历-查表法

单片机存储有限,需要对整个农历数据进行精简

我设计了一种方法,后来发现一个更结简的方法

见《esp-01s+1.3oled显示汉字星期、农历

以下代码是c#生成LUNAR_YEARS[]常量表代码的代码

public int GetYearCode(int year)
{
	//获取year至year+1年的农历
	//QueryNongli函数可以通过数据库或天文计算等等获得,根据你所用数据源改变,这里不再写出
	//1个农历年跨越2个公历年
	List<BaseInfo> list = QueryNongli(year, year + 1);

	int chunjieMonth = 0, chunjieDay = 0;
	int runyue = 0;
	int n = 0;
	int[] days = new int[13];
	days[12] = 0;
	NongliInfo preItem = null;//根据你所用数据源变化

	//逐天遍历,寻找在year开始的整个农历
	foreach (NongliInfo item in list)
	{
		if (preItem==null)
		{
			if (item.yue == 1 && item.ri == 1)
			{
				chunjieMonth = (item.gtime % 10000) / 100;
				chunjieDay = item.gtime % 100;
				preItem = item;
			}
			continue;
		}

		if (item.ri == 1)
		{
			if (preItem.IsLeapYue)
				runyue = preItem.Yue;

			days[n++] = preItem.Ri;
			if (item.yue == 1)
				break;
		}

		preItem = item;
	}

	//    0101          1        011101010010       01      11011
	//  闰月月份   闰月大小月       大小月情况      春节月份  春节日份
	//                            大月为1,小月为0 
	int code = 0;
	code |= (chunjieMonth & 0x3) << 5;
	code |= (chunjieDay & 0x1f);
	for (int i = 0; i <= 12; i++)
	{
		code |= (days[i] == 30 ? 1 : 0) << (7 + i);
	}
	if (runyue > 0)
	{
		code |= (runyue << (12 + 7 + 1));
	}

	return code;
}

public string CreateTable()
{
	StringBuilder sb = new StringBuilder();
	int startYear = 1971;
	int endYear = 2099;
	int code;

	sb.AppendLine("static uint[] LUNAR_YEARS = {");

	for (int year = startYear; year <= endYear; year++)
	{
		code = GetYearCode(year);
		sb.Append($"0x{code:X06},");

		if (year % 5 == 0)
			sb.AppendLine((year % 10 == 0) ? $"// {year - 9}-{year}" : "");
	}

	sb.AppendLine("\r\n};");

	return sb.ToString();
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值