📄 calendar.c
字号:
/*******************************************
万年历的完整算法:1900~2100
它首先计算出对应阳历月第一天对应是星期几,然后根据数据压缩算法确定,
确定对应的阴历日期;
而阴历节气,则有条件规律算法实现
这个万年历包括
阳历 阴历 星期对照
阴历 天干地支 生肖
********************************************/
#include "globals.h"
#include "display.h"
#include "fastlcd.h"
#include "sysdata.h"
#include "fs.h"
#include "cursor.h"
#include "string.h"
#include "debug.h"
#include "ctype.h"
#include "ime.h"
#include "userapi.h"
#include "phonebook.h"
#include "databank.h"
#include "flashmap.h"
#include "Editdef.h"
#include "Editor.h"
#include "calendar.h"
#include "display.h"
#define X_START_SCREEN 3
#define Y_START_SCREEN 35
#define X_INTERVAL 22
#define Y_INTERVAL 18
#define SOLAR_END_Y 142
#define LUNAR_X 28
#define InvertArea ReverseRect
#define ClearArea ClearRect
/**************************/
/*Calendar variables 2003.6.12 sun*/
/**************************/
code BYTE lunar_calendar_month_table[]={
0x00,0x04,0xad,0x08,0x5a,0x01,0xd5,0x54,0xb4,0x09,0x64,0x05,0x59,0x45,
0x95,0x0a,0xa6,0x04,0x55,0x24,0xad,0x08,0x5a,0x62,0xda,0x04,0xb4,0x05,
0xb4,0x55,0x52,0x0d,0x94,0x0a,0x4a,0x2a,0x56,0x02,0x6d,0x71,0x6d,0x01,
0xda,0x02,0xd2,0x52,0xa9,0x05,0x49,0x0d,0x2a,0x45,0x2b,0x09,0x56,0x01,
0xb5,0x20,0x6d,0x01,0x59,0x69,0xd4,0x0a,0xa8,0x05,0xa9,0x56,0xa5,0x04,
0x2b,0x09,0x9e,0x38,0xb6,0x08,0xec,0x74,0x6c,0x05,0xd4,0x0a,0xe4,0x6a,
0x52,0x05,0x95,0x0a,0x5a,0x42,0x5b,0x04,0xb6,0x04,0xb4,0x22,0x6a,0x05,
0x52,0x75,0xc9,0x0a,0x52,0x05,0x35,0x55,0x4d,0x0a,0x5a,0x02,0x5d,0x31,
0xb5,0x02,0x6a,0x8a,0x68,0x05,0xa9,0x0a,0x8a,0x6a,0x2a,0x05,0x2d,0x09,
0xaa,0x48,0x5a,0x01,0xb5,0x09,0xb0,0x39,0x64,0x05,0x25,0x75,0x95,0x0a,
0x96,0x04,0x4d,0x54,0xad,0x04,0xda,0x04,0xd4,0x44,0xb4,0x05,0x54,0x85,
0x52,0x0d,0x92,0x0a,0x56,0x6a,0x56,0x02,0x6d,0x02,0x6a,0x41,0xda,0x02,
0xb2,0xa1,0xa9,0x05,0x49,0x0d,0x0a,0x6d,0x2a,0x09,0x56,0x01,0xad,0x50,
0x6d,0x01,0xd9,0x02,0xd1,0x3a,0xa8,0x05,0x29,0x85,0xa5,0x0c,0x2a,0x09,
0x96,0x54,0xb6,0x08,0x6c,0x09,0x64,0x45,0xd4,0x0a,0xa4,0x05,0x51,0x25,
0x95,0x0a,0x2a,0x72,0x5b,0x04,0xb6,0x04,0xac,0x52,0x6a,0x05,0xd2,0x0a,
0xa2,0x4a,0x4a,0x05,0x55,0x94,0x2d,0x0a,0x5a,0x02,0x75,0x61,0xb5,0x02,
0x6a,0x03,0x61,0x45,0xa9,0x0a,0x4a,0x05,0x25,0x25,0x2d,0x09,0x9a,0x68,
0xda,0x08,0xb4,0x09,0xa8,0x59,0x54,0x03,0xa5,0x0a,0x91,0x3a,0x96,0x04,
0xad,0xb0,0xad,0x04,0xda,0x04,0xf4,0x62,0xb4,0x05,0x54,0x0b,0x44,0x5d,
0x52,0x0a,0x95,0x04,0x55,0x22,0x6d,0x02,0x5a,0x71,0xda,0x02,0xaa,0x05,
0xb2,0x55,0x49,0x0b,0x4a,0x0a,0x2d,0x39,0x36,0x01,0x6d,0x80,0x6d,0x01,
0xd9,0x02,0xe9,0x6a,0xa8,0x05,0x29,0x0b,0x9a,0x4c,0xaa,0x08,0xb6,0x08,
0xb4,0x38,0x6c,0x09,0x54,0x75,0xd4,0x0a,0xa4,0x05,0x45,0x55,0x95,0x0a,
0x9a,0x04,0x55,0x44,0xb5,0x04,0x6a,0x82,0x6a,0x05,0xd2,0x0a,0x92,0x6a,
0x4a,0x05,0x55,0x0a,0x2a,0x4a,0x5a,0x02,0xb5,0x02,0xb2,0x31,0x69,0x03,
0x31,0x73,0xa9,0x0a,0x4a,0x05,0x2d,0x55,0x2d,0x09,0x5a,0x01,0xd5,0x48,
0xb4,0x09,0x68,0x89,0x54,0x0b,0xa4,0x0a,0xa5,0x6a,0x95,0x04,0xad,0x08,
0x6a,0x44,0xda,0x04,0x74,0x05,0xb0,0x25,0x54,0x03
};
#define Year_Up 0xf9
#define Year_Down 0xfa
#define Month_Up 0xfb
#define Month_Down 0xfc
#define Day_Up 0xfd
#define Day_Down 0xfe
#define SOLAR_LINE 2
#define WEEK_LINE 18
#define LUNAR_LINE 140
// 7+8+36+8+7 = 66
// +8+24+8+7 = 47+66 = 113
// +8+24+8+7 = 47+113 =160
code RECT Calendar_Button[]=
{
{7,SOLAR_LINE+3, 7+6,SOLAR_LINE+10},{53,SOLAR_LINE+3, 53+6,SOLAR_LINE+10},
{66,SOLAR_LINE+3, 66+6,SOLAR_LINE+10},{99,SOLAR_LINE+3, 99+6,SOLAR_LINE+10},
{113,SOLAR_LINE+3,113+6,SOLAR_LINE+10},{147,SOLAR_LINE+3,147+6,SOLAR_LINE+10}
};
code BYTE CalendarKey[] = {Year_Up,Year_Down,Month_Up,Month_Down,Day_Up,Day_Down};
code BYTE calendarText1[]="鼠牛虎兔龙蛇马羊猴鸡狗猪";
code BYTE calendarText2[]="零正二三四五六七八九十冬腊";
code BYTE calendarText3[]="零零初一初二初三初四初五初六初七初八初九初十十一十二十三十四十五十六十七十八十九廿十廿一廿二廿三廿四廿五廿六廿七廿八廿九三十";
code BYTE calendarText4[]="年阴历闰 月";
code BYTE calendarText5[]="年阴历 月";
code BYTE calendarText6[]="农闰 月";
code BYTE calendarText7[]="农 月";
code BYTE calendarText8[]="日一二三四五六";
BYTE IsNumberKey(BYTE KeyTabVu);
bool PenSelectButton(uint8 key, RECT *pRect, uint8 nCount, uint8 *pnSelect);
/***********************************
说明:函数get_solar_day_date(void)
输入变量:gc_solar_calendar_year和gc_solar_calendar_month
输出变量:start_day_of_week和temp_total_day
算出阳历星期排法
***********************************/
WORD get_solar_day_date(DATE solar_calendar,BYTE *start_week)
{
BYTE temp01;
BYTE calculate_temp;
BYTE start_day_of_week;
WORD temp_total_day;
/*------calculate what day is the day of the current month and year. Mon~Sun?---*/
/*条件初始化二次,减少运算数据量. g_temp_total_day 是int型变量*/
calculate_temp = 1;
temp_total_day = 0;
start_day_of_week = 2; /*1901 年1月1日 星期二*/
if(solar_calendar.year >=150)
{
start_day_of_week = 6; /*2050年1月1日 星期六*/
calculate_temp = 150; /*2050 年*/
}
else if(solar_calendar.year >=100)
{
start_day_of_week = 6; /*2000年1月1日 星期六*/
calculate_temp = 100; /*2000 年*/
}
else if(solar_calendar.year >=50)
{
start_day_of_week = 1; /*1950年1月1日 星期1*/
calculate_temp = 50; /*1950 年*/
}
for(temp01 = calculate_temp; temp01<solar_calendar.year; temp01++)
{ /*计算起始年1月1日起过去年头内所有天数*/
if(temp01%4 == 0)
{
start_day_of_week +=2;
temp_total_day += 366; /*阳历闰年*/
}
else
{
start_day_of_week +=1;
temp_total_day += 365;
}
}
for(temp01 = 1;temp01<solar_calendar.month;temp01++)
{ /*计算从当年1月1日起到当月1日内所有天数*/
switch(temp01)
{
case 1:case 3:case 5:case 7:case 8:case 10:case 12:
start_day_of_week +=3;
temp_total_day +=31;
break;
case 2:
if(((solar_calendar.year%4) == 0)&&(solar_calendar.year != 200))
{
start_day_of_week +=1;
temp_total_day +=29;
}
else
{
start_day_of_week +=0;
temp_total_day +=28;
}
break;
case 4:case 6:case 9:case 11:
start_day_of_week +=2;
temp_total_day +=30;
break;
}
}
start_day_of_week %=7; /* will g_solar_calendar_year=99 g_start_day_of_week=140*/
/*-end of calculate what day is the day(Mon~Sun?) and total day --*/
*start_week=start_day_of_week;
return temp_total_day;
}
/**************************************************************************
说明:函数solar_month_total_day(void)
根据输入变量gc_solar_calendar_year和gc_solar_calendar_month,
计算出对应阳历月的总的天数。
****************************************************************************/
BYTE solar_month_total_day(BYTE solar_calendar_year,BYTE solar_calendar_month)
{
BYTE total_day;
switch(solar_calendar_month)
{
case 1:case 3:case 5:case 7:case 8:case 10:case 12:
total_day=31;
break;
case 2:
if(((solar_calendar_year%4) == 0)&&(solar_calendar_year != 200))
total_day=29;
else
total_day=28;
break;
case 4:case 6:case 9:case 11:
total_day=30;
break;
}
return total_day;
}
/**************************************************************************
说明:函数lunar_month_total_day(void)
根据输入变量gc_lunar_calendar_year和gc_lunar_calendar_month,
结合压缩数据表lunar_calendar_month_table计算出对应阴历月的总的天数。
****************************************************************************/
BYTE lunar_month_total_day(BYTE lunar_calendar_year,BYTE lunar_calendar_month)
{
BYTE mc_tpumenus_temp_01;
BYTE mc_tpumenus_temp_02;
if(lunar_calendar_month < 9)
{
mc_tpumenus_temp_01 = lunar_calendar_month_table[2*lunar_calendar_year];
mc_tpumenus_temp_02 = lunar_calendar_month - 1;
}
else
{
mc_tpumenus_temp_01 = lunar_calendar_month_table[2*lunar_calendar_year + 1];
mc_tpumenus_temp_02 = lunar_calendar_month - 9;
}
if((mc_tpumenus_temp_01>> mc_tpumenus_temp_02)&0x01)
return(29);
else
return(30);
}
/****
说明: 函数get_lunar_month(void)
输入变量:solar_calendar.year和solar_calendar.month
输出变量:gc_lunar_calendar_year、gc_lunar_calendar_month和gc_lunar_calendar_date
功能:计算出输入阳历年、阳历月,对应该阳历月第一天对应阴历时间,即阴历年、月、日
所得闰月lunar_leap_month 的数目即为所闰月份
***/
void get_lunar_month(DATE solar_calendar,DATE *lunar_calendar,BYTE *lunar_leap_month,WORD total_day)
{
BYTE temp_leap_month; /* 阴历闰月 */
BYTE temp_flag;
BYTE calculate_temp;
BYTE mc_tpumenus_temp_loop;
BYTE mc_tpumenus_temp_01;
BYTE lunar_calendar_year;
BYTE lunar_calendar_month;
BYTE lunar_calendar_date;
WORD temp_total_day;
temp_total_day=total_day;
temp_leap_month = 0;
temp_flag = 1;
/*条件初始化二次,减少运算数据量.*/
if(solar_calendar.year >=150)
{
lunar_calendar_year = 149;
lunar_calendar_month = 12;
lunar_calendar_date = 8; /*阳历2050年1月1日 是 阴历2049年12月8*/
temp_total_day += 8;
calculate_temp = 150;
}
else if(solar_calendar.year >=100)
{
lunar_calendar_year = 99;
lunar_calendar_month = 11;
lunar_calendar_date = 25; /*阳历2000年1月1日 是 阴历1999年11月25*/
temp_total_day += 25;
calculate_temp = 100;
}
else if(solar_calendar.year >=50)
{
lunar_calendar_year = 49;
lunar_calendar_month = 11;
lunar_calendar_date = 13; /*阳历1950年1月1日 是 阴历1949年11月13*/
temp_total_day += 13;
calculate_temp = 50;
}
else
{
lunar_calendar_year = 0;
lunar_calendar_month = 11;
lunar_calendar_date = 11;
temp_total_day += 11;
calculate_temp = 1;
}
if(solar_calendar.year >calculate_temp||solar_calendar.month>1)
{
for(mc_tpumenus_temp_loop = 1;mc_tpumenus_temp_loop>0;)
{
temp_total_day -=lunar_month_total_day(lunar_calendar_year,lunar_calendar_month);
temp_leap_month = lunar_calendar_month_table[2*lunar_calendar_year + 1];
temp_leap_month = (temp_leap_month>>4)&0x0F;
if(lunar_calendar_month == temp_leap_month)
{
switch(lunar_calendar_year)
{
case 6: case 14: case 19: case 25: case 33: case 36:
case 38: case 41: case 44: case 52: case 55: case 79: case 117:
case 136: case 147: case 150: case 155: case 158: case 185:
case 193:
if(temp_total_day<31)
{
lunar_calendar_date = temp_total_day;
mc_tpumenus_temp_loop = 0;
temp_flag = 0;
}
else
temp_total_day -= 30;
break;
/*current month:temp_leap_month*/
default:
if(temp_total_day < 30)
{
lunar_calendar_date = temp_total_day;
mc_tpumenus_temp_loop = 0;
temp_flag = 0; /*current month:temp_leap_month*/
}
else
temp_total_day -= 29;
}
}
if(temp_flag)
{
lunar_calendar_month++;
if(lunar_calendar_month == 13)
{
lunar_calendar_month = 1;
lunar_calendar_year++;
}
if(temp_total_day < 61) /*if g_temp_total_day>60,ignore compare */
{
mc_tpumenus_temp_01 = lunar_month_total_day(lunar_calendar_year,lunar_calendar_month);
if(temp_total_day < (mc_tpumenus_temp_01 + 1))
{
mc_tpumenus_temp_loop = 0;
lunar_calendar_date = temp_total_day;
}
}
}
}
}
*lunar_leap_month = (temp_flag<<4)|temp_leap_month; /*set leap_month flag*/
lunar_calendar->year=lunar_calendar_year;
lunar_calendar->month=lunar_calendar_month;
lunar_calendar->day=lunar_calendar_date; /*阳历开月的1号的阴历日 */
}
/***********************************************
说明: 函数get_lunar_day(void)
输入变量:gc_solar_calendar_year和gc_solar_calendar_month
输出变量:gc_lunar_calendar_year、gc_lunar_calendar_month和gc_lunar_calendar_date
功能:计算出输入阳历年、阳历月,对应该阳历月第一天对应阴历时间,即阴历年、月、日
所得闰月lunar_leap_month 的数目即为所闰月份
*****************************************************/
void get_lunar_day(DATE solar_calendar,DATE *lunar_calendar,BYTE *lunar_leap_month,WORD total_day)
{
BYTE mc_tpumenus_temp_01;
WORD lunar_calendar_year;
WORD lunar_calendar_month;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -