此万年历有问题 有待于研究

来源:互联网 发布:天猫商城首页淘宝网 编辑:程序博客网 时间:2024/04/29 16:13

在万年历中加入农历(C#)
中国的农历似乎没有什么明显的规律,网上有很多关于农历的算法,感觉都比较复杂。其实最简单的算法莫过于查表了,现在我定义一个数组记录阳历每个月一号是阴历的几月几号以及这个月有几天。这样通过非常简单的算法就能将阳历转换为阴历了。
先定义一个结构体:
struct DateInfo
{
public ushort Year;
public ushort Month;
public ushort Day;
public override String ToString()
{
if(Day==1)
{
return NumberToString(Month)+"月";;
}
else if(Day<=10)
{
return "初"+NumberToString(Day);
}
else if(Day<20)
{
return "十"+NumberToString((ushort)(Day%10));
}
else if(Day==20)
{
return "二十";
}
else if(Day<30)
{
return "廿"+NumberToString((ushort)(Day%10));
}
else
{
return "三十";
}
}
}

private String NumberToString(ushort num)
{
switch(num)
{
case 1:return "一";
case 2:return "二";
case 3:return "三";
case 4:return "四";
case 5:return "五";
case 6:return "六";
case 7:return "七";
case 8:return "八";
case 9:return "九";
case 10:return "十";
case 11:return "十一";
case 12:return "十二";
default :return "MonthError";
}
}

两个重要的函数:
private int GetWeek(int y,int m,int d)//返回某日星期
{
DateTime date=new DateTime(y,m,d);
return (int)date.DayOfWeek;
}

private int GetMonthDays(int y,int m)//得到某月天数
{
return DateTime.DaysInMonth(y,m);;
}

将阳历转换为阴历:
YearInfo记录主要信息:万位表示该月天数1-30,0-29;下千百位表示月,十个位表示日期。

private DateInfo SolarToLunar(DateInfo Solar)
{
static ushort [] YearInfo={1121,11223,121,10223,323,10425,525,10627,10728,828,10930,11101,1202};

if(Solar.Year<2005||Solar.Year>2005)
return Solar;

DateInfo Lunar;
if(Solar.Month<1||Solar.Month>12)
{
Lunar.Year=Lunar.Month=Lunar.Day=1;
return Lunar;
}

ushort Index=(ushort)((Solar.Year-2005)*12+Solar.Month-1);
if(YearInfo[Index]%10000/100<Solar.Month)
{
Lunar.Year=Solar.Year;
}
else
{
Lunar.Year=(ushort)(Solar.Year-1);
}

Lunar.Month=(ushort)(YearInfo[Index]%10000/100);
ushort Days=(ushort)(YearInfo[Index]/10000 == 1 ? 30 : 29);
ushort day=(ushort)(YearInfo[Index]%10000%100+(Solar.Day-1));
if(day<=Days)
{
Lunar.Day=day;
}
else
{
Lunar.Day=(ushort)(day-Days);
Lunar.Month++;
if(Lunar.Month>12)
Lunar.Month=1;
}

return Lunar;
}

主函数绘图:
private void Form1_Paint(object sender, System.Windows.Forms.PaintEventArgs e)
{
Graphics g=e.Graphics;

Font AFont=new Font("Arial",16);
Font VFont=new Font("Verdana",10);
int x_start=340,x_step=50,y_start=60,y_step=60;

ushort Total=(ushort)GetMonthDays(Year,Month);
short w=(short)GetWeek(Year,Month,1);

DateInfo Solar;
DateInfo Lunar;
Solar.Year=Year;
Solar.Month=Month;
Brush brush=Brushes.Black;
ushort d;
for(d=1;d<=Total;d++)
{
Solar.Day=d;
Lunar=SolarToLunar(Solar);
g.DrawString(d.ToString(),AFont,brush,x_start+x_step*((d+w)%7)+5,y_start+y_step+y_step*((d+w)/7)+5);
g.DrawString(Lunar.ToString(),VFont,brush,x_start+x_step*((d+w)%7)+5,y_start+y_step+y_step*((d+w)/7)+35);
}