📄 calendar.c
字号:
/*
*Filename :calendar.c
*Description: calculate date
*Author : Frank.Shen
*Date : 2008/10/18
*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
typedef struct lunar_date_st
{
int year;
int month;
int day;
}lunar_data_t;
typedef struct date_info_st
{
int year;
int month;
int day;
int week;
int lunar_year;
int lunar_month;
int lunar_day;
int lunar_year_num;
int lunar_month_num;
int lunar_day_num;
}date_info_t;
#define START_YEAR 1900
#define END_YEAR 2100
/*one element is one year,12 hight bit is 12 month (1 to 12), value of bit is 1,the days of month
is 30, value of bit is 0,the days of month is 29. the 4 low bit is leap month, if value of these
low bits is 0xf, in the before year,days of leap month is 30, else days is 29*/
static long lunarInfo[]={
0x4bd8,0x4ae0,0xa570,0x54d5,0xd260,0xd950,0x5554,0x56af,0x9ad0,0x55d2,
0x4ae0,0xa5b6,0xa4d0,0xd250,0xd255,0xb54f,0xd6a0,0xada2,0x95b0,0x4977,
0x497f,0xa4b0,0xb4b5,0x6a50,0x6d40,0xab54,0x2b6f,0x9570,0x52f2,0x4970,
0x6566,0xd4a0,0xea50,0x6a95,0x5adf,0x2b60,0x86e3,0x92ef,0xc8d7,0xc95f,
0xd4a0,0xd8a6,0xb55f,0x56a0,0xa5b4,0x25df,0x92d0,0xd2b2,0xa950,0xb557,
0x6ca0,0xb550,0x5355,0x4daf,0xa5b0,0x4573,0x52bf,0xa9a8,0xe950,0x6aa0,
0xaea6,0xab50,0x4b60,0xaae4,0xa570,0x5260,0xf263,0xd950,0x5b57,0x56a0,
0x96d0,0x4dd5,0x4ad0,0xa4d0,0xd4d4,0xd250,0xd558,0xb540,0xb6a0,0x95a6,
0x95bf,0x49b0,0xa974,0xa4b0,0xb27a,0x6a50,0x6d40,0xaf46,0xab60,0x9570,
0x4af5,0x4970,0x64b0,0x74a3,0xea50,0x6b58,0x5ac0,0xab60,0x96d5,0x92e0,
0xc960,0xd954,0xd4a0,0xda50,0x7552,0x56a0,0xabb7,0x25d0,0x92d0,0xcab5,
0xa950,0xb4a0,0xbaa4,0xad50,0x55d9,0x4ba0,0xa5b0,0x5176,0x52bf,0xa930,
0x7954,0x6aa0,0xad50,0x5b52,0x4b60,0xa6e6,0xa4e0,0xd260,0xea65,0xd530,
0x5aa0,0x76a3,0x96d0,0x4afb,0x4ad0,0xa4d0,0xd0b6,0xd25f,0xd520,0xdd45,
0xb5a0,0x56d0,0x55b2,0x49b0,0xa577,0xa4b0,0xaa50,0xb255,0x6d2f,0xada0,
0x4b63,0x937f,0x49f8,0x4970,0x64b0,0x68a6,0xea5f,0x6b20,0xa6c4,0xaaef,
0x92e0,0xd2e3,0xc960,0xd557,0xd4a0,0xda50,0x5d55,0x56a0,0xa6d0,0x55d4,
0x52d0,0xa9b8,0xa950,0xb4a0,0xb6a6,0xad50,0x55a0,0xaba4,0xa5b0,0x52b0,
0xb273,0x6930,0x7337,0x6aa0,0xad50,0x4b55,0x4b6f,0xa570,0x54e4,0xd260,
0xe968,0xd520,0xdaa0,0x6aa6,0x56df,0x4ae0,0xa9d4,0xa4d0,0xd150,0xf252,
0xd520};
static int g_week_day = 1; /*1980-01-01 is Tuesday*/
/*
*func name : IsLeapYear
*paratmeter:
* int year ;
*return : 1: year is leapyear; 0: year is not leapyear
*/
static int IsLeapYear( int year )
{
if ((year %4 == 0) && (year % 100 != 0) ||
(year % 400 == 0) )
{
return 1;
}
else
{
return 0;
}
}
/*
*func name : calculate_total_days
*paratmeter:
* int year ;
* int month;
* int day ;
*return : total days
*/
static long calculate_total_days(int year,int month, int day)
{
long total_days =0;
int leapday = 0;
int i =0;
for(i= START_YEAR; i < year; i++ )
{
if(1 == IsLeapYear(i))
{
total_days += 366;
}
else
{
total_days += 365;
}
}
if(1==IsLeapYear(year))
{
leapday = 1;
}
switch(month)
{
case 1:
total_days += day;
break;
case 2:
total_days += day + 31;
break;
case 3:
total_days += day + 31 + 28+leapday;
break;
case 4:
total_days += day + 31 + 28+leapday + 31;
break;
case 5:
total_days += day + 31 + 28+leapday + 31 + 30;
break;
case 6:
total_days += day + 31 + 28+leapday + 31 + 30 + 31;
break;
case 7:
total_days += day + 31 + 28+leapday + 31 + 30 + 31 + 30;
break;
case 8:
total_days += day + 31 + 28+leapday + 31 + 30 + 31 + 30 + 31;
break;
case 9:
total_days += day + 31 + 28+leapday + 31 + 30 + 31 + 30 + 31 + 31;
break;
case 10:
total_days += day + 31 + 28+leapday + 31 + 30 + 31 + 30 + 31 + 31 + 30;
break;
case 11:
total_days += day + 31 + 28+leapday + 31 + 30 + 31 + 30 + 31 + 31 + 30 + 31;
break;
case 12:
total_days += day + 31 + 28+leapday + 31 + 30 + 31 + 30 + 31 + 31 + 30 + 31 + 30;
break;
default:
break;
}
return total_days;
}
/*
*func name : calculate_week_day
*paratmeter:
* int year ;
* int month;
* int day ;
*return : weekday
*/
static int calculate_week_day(int year, int month, int day)
{
long total_days =0;
total_days = calculate_total_days(year, month, day);
return ((g_week_day-1+total_days%7)%7);
}
/*
*func name : lYearDays
*paratmeter:
* int y;
*return : days of leap year
*/
static int lYearDays(int y)
{
int i,sum = 348; // 12*29;
for(i=0x8000; i>0x8; i>>=1)
sum += (lunarInfo[y-START_YEAR] & i)? 1: 0;
return(sum+leapDays(y));
}
/*
*func name : leapDays
*paratmeter:
* int y;
*return : days of leap month
*/
static int leapDays(int y)
{
if(leapMonth(y)) return((lunarInfo[y-START_YEAR+1]&0xf)==0xf? 30: 29);
else return(0);
}
/*
*func name : leapMonth
*paratmeter:
* int y;
*return : leap month of the year
*/
static int leapMonth(int y)
{
int lm = lunarInfo[y-START_YEAR] & 0xf;
return(lm==0xf?0:lm);
}
/*
*func name : monthDays
*paratmeter:
* int y;
* int m;
*return : days of m month of y years
*/
static int monthDays(int y,int m)
{
return( (lunarInfo[y-START_YEAR] & (0x10000>>m))? 30: 29 );
}
/*
*func name : monthDays
*paratmeter:
* int year;
* int month;
* int day;
*return : get date of lunar
*/
lunar_data_t Lunar(int year, int month, int day)
{
int i = 0, leap = 0, temp = 0;
lunar_data_t m_date;
int this_year = 0;
int this_month;
int this_day;
int this_isLeap = 0;
int offset = calculate_total_days(year, month, day) -31;
for(i=START_YEAR; i<END_YEAR && offset>0; i++)
{
temp= lYearDays(i);
offset-=temp;
}
if(offset<0)
{
offset+=temp;
i--;
}
this_year = i;
leap = leapMonth(i);
this_isLeap = 0;
for(i=1; i<13 && offset>0; i++)
{
if(leap>0 && i==(leap+1) && this_isLeap==0)
{
--i;
this_isLeap = 1;
temp = leapDays(this_year);
}
else
{
temp = monthDays(this_year, i);
}
/*release leap month*/
if(this_isLeap==1 && i==(leap+1))
this_isLeap = 0;
offset -= temp;
}
if((offset==0 )&& (leap>0) && (i==(leap+1)))
if(this_isLeap)
{
this_isLeap = 0;
}
else
{
this_isLeap = 1;
--i;
}
if(offset<0)
{
offset += temp;
--i;
}
this_month = i;
this_day = offset + 1;
m_date.year = this_year;
m_date.month = this_month;
m_date.day = this_day;
return m_date;
}
void main()
{
int year = 0;
int month = 0;
int day = 0;
int week_day = 0;
date_info_t m_date_info;
lunar_data_t m_lunar_date;
/*input date, formate of date is "0000-00-00"*/
printf("Input date, formate of date is 0000-00-00: \n");
scanf("%d-%d-%d",&year,&month,&day);
if(END_YEAR+1>year || year > END_YEAR ||month > 12 ||month <1 ||day <1 ||day >31)
return;
week_day = calculate_week_day(year,month, day);
m_lunar_date = Lunar(year,month, day);
m_date_info.year = year;
m_date_info.month = month;
m_date_info.day = day;
m_date_info.week = week_day;
m_date_info.lunar_year = m_lunar_date.year;
m_date_info.lunar_month= m_lunar_date.month;
m_date_info.lunar_day= m_lunar_date.day;
exit(0);
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -