/* calen.c */
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#define YES 1
#define NO 0
#define OK 1
#define NG 0
#define number_of_horidays 20
struct tm
{
int tm_sec; /* 秒 - [0,59] */
int tm_min; /* 分 - [0,59] */
int tm_hour; /* 時 - [0,23] */
int tm_mday; /* 日 - [1,31] */
int tm_mon; /* 月 - [0,11] */
int tm_year; /* 年(年-1900) */
int tm_wday; /* 曜日 - [0,6] */
int tm_yday; /* 通算日 - [0,365] */
int tm_isdst; /* 夏時間調整フラグ */
};
int leapyear(int yy);
long _mjd(struct tm *date);
void _jdate(long mjd, struct tm *date);
int _holiday(struct tm *date);
long daycount(struct tm *from, struct tm *to);
struct tm date;
/*--------------------------------------*/
/* 曜日エリア */
/*--------------------------------------*/
char *_wday[7] = {"日","月","火","水","木","金","土"};
/*--------------------------------------*/
/* 月の末日エリア */
/*--------------------------------------*/
int _mday[12] = { 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};
/*--------------------------------------*/
/* 祝日エリア(振替休日を考慮) */
/*--------------------------------------*/
static int _holytbl1[number_of_horidays] =
{ 101, 115, 211, 429, 503, 504, 505, 720,
915, 923,1010,1103,1123,1223, 0};
/*--------------------------------------*/
/* 休日エリア(その他の休日) */
/*--------------------------------------*/
static int _horiday_table_read = NO;
static int _holytbl2[number_of_horidays] = {0};
/*--------------------------------------*/
/* 閏年判定 (YES:閏年, NO:閏年でない) */
/*--------------------------------------*/
int leapyear(int yy)
{
if((yy % 400) == 0) return YES;
if((yy % 100) == 0) return NO;
if((yy % 4) == 0) return YES;
return NO;
}
/*--------------------------------------*/
/* 準ユリウス日(MJD)の計算 */
/*--------------------------------------*/
long _mjd(struct tm *date)
{
long mjd;
int y, m, d;
/* 月 = 3 4 5 6 7 8 9 10 11 12 1 2 */
/* m = 0 1 2 3 4 5 6 7 8 9 10 11 */
static yday[] = { 0, 31, 61, 92,122,153,184,214,245,275,306,337};
if((*date).tm_mon >= 2)
{
d = date->tm_mday;
m = date->tm_mon - 2;
y = date->tm_year;
date->tm_yday = 59 + leapyear(1900 + y) + yday[m] + d;
}
else
{
d = date->tm_mday;
m = date->tm_mon + 10;
y = date->tm_year - 1;
date->tm_yday = date->tm_mon * 31 + d;
}
y += 1900;
mjd = 365L * y + y / 4 - y / 100 + y / 400 + yday[m] + d - 678882L;
date->tm_wday = (int)((mjd - 4) % 7);
return mjd;
}
/*--------------------------------------*/
/* MJDから年月日を計算 */
/*--------------------------------------*/
void _jdate(long mjd, struct tm *date)
{
int y, i, j;
long mjd1, mjd2;
mjd1 = mjd + 678882L;
y = (int)(mjd1 / 365 - 2);
for(;;)
{
mjd2 = y * 365L + y / 4 - y / 100 + y / 400 + 306;
if(mjd2 < mjd1) break;
y--;
}
y++;
date->tm_year = y - 1900;
date->tm_mon = 0; /* 1月 */
date->tm_mday = 0; /* 0日 */
j = (int)(mjd - _mjd(date));
_mday[1] = 28 + leapyear(y);
for(i = 0; i < 12; i++)
{
j -= _mday[i];
if(j <= 0)
{
j += _mday[i];
break;
}
}
date->tm_mon = i;
date->tm_mday = j;
}
/*--------------------------------------*/
/* 休日判定 */
/* ( 0:休日でない 1:指定休日 */
/* 2:祝祭日&振替休日 ) */
/*--------------------------------------*/
int _holiday(struct tm *date)
{
int day, i, j;
FILE *fp;
if(_horiday_table_read == NO)
{
fp = fopen("horiday.tbl", "r");
if(fp != NULL)
{
for(i = 0, j = 1; i < 20 && j == 1; i++)
j = fscanf(fp, "%d", &(_holytbl2[i]));
fclose(fp);
}
_horiday_table_read = YES;
}
i = date->tm_mon + 1;
day = i * 100 + date->tm_mday;
for(i = 0; i < number_of_horidays && day >= _holytbl1[i]; i++)
if(day == _holytbl1[i]) return 2;
for(i = 0; i < number_of_horidays && day >= _holytbl2[i]; i++)
if(day == _holytbl2[i]) return 1;
_mjd(date);
if(date->tm_wday == 1) /* 振替休日 */
{
if(date->tm_mday != 1) day -= 1; /* 前日を計算 */
else
{
i = date->tm_mon;
day = i * 100 + _mday[i-1];
}
for(i = 0; i < number_of_horidays && day >= _holytbl1[i]; i++)
if(day == _holytbl1[i]) return 2;
}
return NO;
}
/*--------------------------------------*/
/* 日数計算 */
/*--------------------------------------*/
long daycount(struct tm *from, struct tm *to)
{
long days;
days = _mjd(to) - _mjd(from);
if(days >= 0) return days + 1L;
return days - 1L;
}
/*--------------------------------------*/
/* カレンダ作成:メイン関数 */
/*--------------------------------------*/
int main(int ac, char *av[])
{
int i, j, k, dd;
if(ac != 3)
{
printf("usage: %s 91 5 ・・・ 1991年5月のカレンダ出力\n", av[0]);
return 0;
}
date.tm_year = atoi(av[1]); /* 19xx年 */
date.tm_mon = atoi(av[2]) - 1; /* x月 */
date.tm_mday = 1; /* 1日 */
_mjd(&date);
dd = _mday[date.tm_mon];
j = date.tm_wday;
for(i = 0; i < j; i++) printf(" ");
for(i = 1; i <= dd; i++)
{
date.tm_mday = i;
k = _holiday(&date);
if(k != 0) printf("\x1b[31m");
else if(j == 0) printf("\x1b[31m");
else if(j == 6) printf("\x1b[34m");
printf("%3d\x1b[0m", i);
j = (j + 1) % 7;
if(j == 0) putchar('\n');
}
putchar('\n');
return 1;
}
|