📄 calendar.c
字号:
#include <CsAgb.h>
#include <rb_string.h>
#include <rb_stdio.h>
#include <Qgraph.h>
#include <graph.h>
#include <mytype.h>
#define font_color RGB(15,15,15)
extern u8 rb_xp;
extern u8 rb_yp;
extern u8 arlt(char *tit,char *mes);
extern void n_box(u8 xp,u8 yp,u8 xsp,u8 ysp,u16 co,u16 bg);
extern void win_plate(char *tit,char *mes,u16 bg);
extern void valendar_set(date *M,u8 act); //日历设置;
u16 day_mask[14]={
0x8000,0x4000,0x2000,0x1000,
0x0800,0x0400,0x0200,0x0100,
0x0080,0x0040,0x0020,0x0010,
0x0008,0x0004};
const u8 Mdays[12]={31,28,31,30,31,30,31,31,30,31,30,31};
// 数组LMdays存入农历2001年到2050年每年中的月天数信息
// 农历每月只能是29或30天,一年用12(或13)个二进制位表示,从高到低,对应位为1表示30天,否则29天
const u16 LMdays[]={
0xd4a8,0xd4a0,0xda50,0x5aa8,0x56a0,0xaad8,0x25d0,0x92d0,0xc958,0xa950, // 2001-2010
0xb4a0,0xb550,0xb550,0x55a8,0x4ba0,0xa5b0,0x52b8,0x52b0,0xa930,0x74a8, // 2011-2020
0x6aa0,0xad50,0x4da8,0x4b60,0x9570,0xa4e0,0xd260,0xe930,0xd530,0x5aa0, // 2021-2030
0x6b50,0x96d0,0x4ae8,0x4ad0,0xa4d0,0xd258,0xd250,0xd520,0xdaa0,0xb5a0, // 2031-2040
0x56d0,0x4ad8,0x49b0,0xa4b8,0xa4b0,0xaa50,0xb528,0x6d20,0xada0,0x55b0 // 2041-2050
};
// 数组LeapYear存放农历2001年到2050年闰月的月份,如没有则为0,从高到低,每字节存两年
const u8 LeapYear[]={
0x40,0x02,0x07,0x00,0x50, // 2001-2010
0x04,0x09,0x00,0x60,0x04, // 2011-2020
0x00,0x20,0x60,0x05,0x00, // 2021-2030
0x30,0xb0,0x06,0x00,0x50, // 2031-2040
0x02,0x07,0x00,0x50,0x03 // 2041-2050
};
u8 L_IsLeapYear(u16 year)// 农历year年是否有润月并返回润月月份(没有返回0)
{
year-=2001;
if (year%2==0) return (LeapYear[year/2]&0xf0)>>4;//取高位
else return LeapYear[year/2]&0x0f;//取低位
}
u32 Ydays(u16 year) //返回农历year年总天数
{
u8 i,step;
u32 days=0;
u16 day=LMdays[year-2001];
step=L_IsLeapYear(year)?13:12;
for (i=0;i<step;i++)
{
if (day & day_mask[i]) days+=30;
else days+=29;
}
return days;
}
u8 IsLeapYear(u16 year)//阳历year是否为润年
{
return year%400==0||(year&100 && year%4==0);
}
u8 days_in_mon(u16 year,u8 mon)//返回某月的总天数
{
const static u8 days[]={0,31,28,31,30,31,30,31,31,30,31,30,31};
if (mon!=2) return days[mon];
else return 28+IsLeapYear(year);
}
u32 Ddays(u16 year,u8 mon,u8 day)//计算阳历y-m-d距2001-1-24日的天数
{
u16 i;
u32 days=0;
for (i=2001;i<year;i++) days+=(IsLeapYear(i)?366:365);
for (i=1;i<mon;i++) days+=Mdays[i-1];
days+=day;
days=days+(IsLeapYear(year) && mon>2);
return days-24;
}
u8 get_week(u32 days) //计算2001-1-24后days天是星期几
{
return (3+days)%7;
}
void NLmes(u32 days,u8 *mes)//计算2001-1-24后days天的农历信息
{
u32 day=0;
u16 i=2001;
u8 LeepMon;
u8 step;
if (days==0)
{
mes[0]=0;//年(-2001)
mes[1]=1;//月
mes[2]=1;//日
return;
}
while (day<=days)
{
day+=Ydays(i);
i++;
}
i--;
LeepMon=L_IsLeapYear(i);
step=LeepMon?13:12;
mes[0]=i-2001;//年份已经确定
day-=Ydays(i);
i=0;
while (day<=days)
{
if (LMdays[mes[0]] & day_mask[i]) day+=30;
else day+=29;
i++;
}
mes[1]=i;//当前月份
i--;
day=day-((LMdays[mes[0]] & day_mask[i])?30:29);
mes[2]=days+1-day;
}
void calen_tab()
{
int i;
int xp,yp;
char weeks[7][4]={"Sun","Mon","Tue","Wed","Thu","Fri","Sat"};
r_box(40,30-14,217,110+15,RGB(24,15,13),1);
Q_box(41,31-14,216,109+15,RGB(30,30,30));
Q_box(42,110,215,109+14,RGB(13,15,24));
cwrite(43,112,0,"[A]农历[B]退出[START]帮助");
cwrite(42,111,RGB(30,30,0),"[A]农历[B]退出[START]帮助");
for (i=0;i<7;i++)
{
Q_box(42+i*25,32,42+23+i*25,45,RGB(13,15,24));
cwrite(44+i*25,34,0,weeks[i]);
if (i) cwrite(43+i*25,33,RGB(30,30,30),weeks[i]);
else cwrite(43+i*25,33,RGB(30,30,13),weeks[i]);
}
}
void list_day(u8 week,u8 days)
{
int i;
int xp,yp;
const static char num[11]="0123456789";
char day[3]="00";
for (i=0;i<7;i++) Q_box(42+i*25,47,42+23+i*25,108,RGB(24,15,13));
for (i=0;i<days;i++)
{
yp=(i+week)/7;
xp=(i+week)%7;
yp=yp%5;
day[0]=num[(i+1)/10];
day[1]=num[(i+1)%10];
cwrite(47+xp*25,49+yp*12,0,day);
cwrite(46+xp*25,48+yp*12,RGB(30,30,30),day);
}
}
void list_day_s(u8 week,u8 days,u8 id,u8 mod)
{
int xp,yp;
const static char num[11]="0123456789";
char day[3]="00";
yp=(id+week-1)/7;
xp=(id+week-1)%7;
yp=yp%5;
day[0]=num[id/10];
day[1]=num[id%10];
Q_box(43+xp*25,49+yp*12,42+22+xp*25,48+11+yp*12,mod?RGB(24,15,13):RGB(13,14,24));
cwrite(47+xp*25,49+yp*12,0,day);
cwrite(46+xp*25,48+yp*12,mod?RGB(30,30,30):RGB(30,30,13),day);
}
void date_to_str(u16 year,u8 mon,u8 day,u8 week,char *str)
{
char num[]="0123456789";
char weeks[]="日一二三四五六";
str[0]=num[year/1000];
year%=1000;
str[1]=num[year/100];
year%=100;
str[2]=num[year/10];
str[3]=num[year%10];
str[4]='\0';
str_cat(str,"年");
str[6]=num[mon/10];
str[7]=num[mon%10];
str[8]='\0';
str_cat(str,"月");
str[10]=num[day/10];
str[11]=num[day%10];
str[12]='\0';
str_cat(str,"日");
str[14]=' ';
str[15]='\0';
str_cat(str,"星期");
str[19]='\0';
str_cat(str,weeks+(week*2));
str[21]='\0';
}
void nl_to_str(u16 year,u8 mon,u8 day,char *str)
{
char temp[30]="\0";
u16 nums;
char tiangan[]="甲乙丙丁戊己庚辛壬癸";
char dizhi[]="子丑寅卯辰巳午未申酉戌亥";
char shengxiao[]="鼠牛虎免龙蛇马羊猴鸡狗猪";
char month[13][8]={"**","正月 ","二月 ","三月 ","四月 ","五月 ","六月 ","七月 ","八月 ","九月 ","十月 ","十一月","腊月 "};
char days[4][6]={"初","十","廿","三十"};
char num[]="零一二三四五六七八九";
str[0]='\0';
str_cat(str,"农历");
str[4]='\0';
nums=year-2001;
str_cat(str,tiangan+((nums+7)%10)*2);
str[6]='\0';
str_cat(str,dizhi+((nums+5)%12)*2);
str[8]='\0';
str_cat(str,"年 ");
str[12]='\0';
str_cat(str,month[mon]);
if (day==10) str_cat(temp,"初十");
else if (day==20) str_cat(temp,"廿十");
else if (day==30) str_cat(temp,"三十");
else
{
str_cat(temp,days[day/10]);
temp[2]='\0';
str_cat(temp,num+(day%10)*2);
temp[4]='\0';
}
str_cat(str,temp);
temp[0]=' ';
temp[1]='(';
temp[2]=shengxiao[((nums+5)%12)*2];
temp[3]=shengxiao[((nums+5)%12)*2+1];
temp[4]=')';
temp[5]='\0';
str_cat(str,temp);
}
void calendar()
{
char str[40];
u8 week,week_1st;
u8 leep_mon=0;
u8 done=1;
u8 old=1;
u8 nl_mes[4];
u32 days,days_1st,the_days;
date get;
calendar_set(&get,2);
if (get.year<2002 || get.year>2049 || get.mon<1 || get.mon>12 || get.day<1 ||get.day>days_in_mon(get.year,get.mon))
{
get.year=2005;
get.mon=1;
get.day=20;
calendar_set(&get,1);
}
the_days=days_in_mon(get.year,get.mon);
days=Ddays(get.year,get.mon,get.day);
days_1st=Ddays(get.year,get.mon,1);
week=get_week(days);
week_1st=get_week(days_1st);
calen_tab();
list_day(week_1st,the_days);
list_day_s(week_1st,the_days,get.day,0);
date_to_str(get.year,get.mon,get.day,week,str);
Q_box(42,31-13,215,30,RGB(24,15,13));
cwrite(42,31-12,RGB(30,30,30),str);
while(1)
{
readkey();
if (CS_IsKeyDown(KEY_LEFT))
{
if (get.day==1) get.day=the_days;
else get.day--;
done=1;
}
else if(CS_IsKeyDown(KEY_RIGHT))
{
if (get.day==the_days) get.day=1;
else get.day++;
done=1;
}
else if(CS_IsKeyDown(KEY_UP))
{
if (get.mon==1) get.mon=12;
else get.mon--;
done=2;
}
else if(CS_IsKeyDown(KEY_DOWN))
{
if (get.mon==12) get.mon=1;
else get.mon++;
done=2;
}
else if(CS_IsKeyDown(KEY_L))
{
if (get.year==2002) get.year=2049;
else get.year--;
done=2;
}
else if(CS_IsKeyDown(KEY_R))
{
if (get.year==2049) get.year=2002;
else get.year++;
done=2;
}
else if (CS_IsKeyDown(KEY_A))
{
arlt("操作说明:","R /L :年调整\nUP /DOWN :月调整\nLEFT/RIGHT:日调整");
}
else if (CS_IsKeyDown(KEY_B))
{
calendar_set(&get,1);
return;
}
if (done==2)
{
the_days=days_in_mon(get.year,get.mon);
if (get.day>the_days) get.day=the_days;
days=Ddays(get.year,get.mon,get.day);
days_1st=Ddays(get.year,get.mon,1);
week=get_week(days);
week_1st=get_week(days_1st);
list_day(week_1st,the_days);
}
if (done)
{
if (done==1) list_day_s(week_1st,the_days,old,1);
list_day_s(week_1st,the_days,get.day,0);
old=get.day;
days=Ddays(get.year,get.mon,get.day);
week=get_week(days);
date_to_str(get.year,get.mon,get.day,week,str);
Q_box(42,31-13,215,30,RGB(24,15,13));
cwrite(42,31-12,RGB(30,30,30),str);
Q_box(42,110,215,109+14,RGB(24,15,13));
NLmes(days,nl_mes);
leep_mon=L_IsLeapYear(2001+nl_mes[0]);
if (leep_mon && nl_mes[1]>leep_mon) nl_mes[1]--;
nl_to_str((u16)(2001+nl_mes[0]),nl_mes[1],nl_mes[2],str);
cwrite(43,112,0,str);
cwrite(42,111,RGB(30,30,0),str);
done=0;
}
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -