最新版万年历,用法参照unix下的cal程序!
相关信息
http://www.vcgood.com/bbs/forum_posts.asp?TID=2567&PN=1
旧版本
http://www.vcgood.com/bbs/forum_posts.asp?TID=2571&PN=1
下载
ftp://vcgood:www.vcgood.com@ftp.vcgood.com/网友上传/xcal.tar.gz
windows下
环境: MinGW
编译: make -f makefile.win
makefile.win
[code]
# MinGW
CC = gcc
RM = del
CFLAGS = --std=c99
LFLAGS =
OBJS = xcal.o calendar.o displaycalendar.o
xcal : $(OBJS)
$(CC) -o $@ $^
%.o%.c :
$(CC) $(CFLAGS)
clean :
$(RM) $(OBJS)
$(RM) xcal.exe
[/code]
solaris下
环境: gcc
编译: make -f makefile.sun
makefile.sun
[code]
# sun solaris gcc
CC = gcc
RM = rm
CFLAGS = --std=c99
LFLAGS =
OBJS = xcal.o calendar.o displaycalendar.o
xcal : $(OBJS)
$(CC) -o $@ $^
%.o%.c :
$(CC) $(CFLAGS)
clean :
$(RM) $(OBJS)
$(RM) xcal
[/code]
>> 本文固定链接: http://www.vcgood.com/archives/2577
xcal.c
[code]
/**********************************************************************/
/* project : 万年历 */
/* version : Ver 1.0 */
/* file : xcal.c */
/* author : xstar.wxb */
/* date : 2008/08/01 */
/* history : */
/* date : 2008/07/31 ver : 0.9 author : xstar.wxb */
/* date : 2008/08/01 ver : 1.0 author : xstar.wxb */
/**********************************************************************/
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include "calendar.h"
#include "displaycalendar.h"
/* 主函数 */
int main(int argc, char *argv[])
{
int rc = 0; /* 返回值 */
int year = 0; /* 输入的年份(1 - 9999) */
int month = 0; /* 输入的月份(1 - 12) */
time_t tt; /* 当前时间 */
struct tm *mtime; /* 当前时间 */
/* 初始化 */
rc = 0;
switch (argc)
{
case 1: /* xcal */
time( &tt );
mtime = gmtime( &tt );
year = mtime->tm_year + 1900;
month = mtime->tm_mon + 1;
/* 显示日历 */
displaymonth( year, month );
rc = 0;
break;
case 2: /* xcal year */
/* 转换为数字 */
year = atoi( argv[ 1 ] );
/* 判断输入的参数,简单判断 */
if ((year < 1) || (year > 9999))
{
printf( "Usage: xcal [[month] year]\n" );
printf( "year : 1 - 9999\n" );
return -1;
}
/* 显示日历 */
displayyear( year );
rc = 0;
break;
case 3: /* xcal month year */
/* 转换为数字 */
year = atoi( argv[ 2 ] );
month = atoi( argv[ 1 ] );
/* 判断输入的参数,简单判断 */
if ((year < 1) || (year > 9999))
{
printf( "Usage: xcal [[month] year]\n" );
printf( "year : 1 - 9999\n" );
return -1;
}
/* 判断输入的参数,简单判断 */
if ((month < 1) || (month > 12))
{
printf( "Usage: xcal [[month] year]\n" );
printf( "month : 1 - 12\n" );
return -1;
}
/* 显示日历 */
displaymonth( year, month );
rc = 0;
break;
default:
printf( "Usage: xcal [[month] year]\n" );
rc = -1;
}
return rc;
}
[/code]
calendar.h
[code]
/**********************************************************************/
/* project : 万年历 */
/* version : Ver 1.0 */
/* file : calendar.h */
/* author : xstar.wxb */
/* date : 2008/08/01 */
/* history : */
/* date : 2008/08/01 ver : 1.0 author : xstar.wxb */
/**********************************************************************/
#ifndef _CALENDAR_H_
#define _CALENDAR_H_
/* 日期与星期对应结构 */
typedef struct _DATE2WEEKDAY {
int date;
int weekday;
} DATE2WEEKDAY;
/* 儒略历(Julian Calendar) 1 - 1751 */
int JulianCalendar(int year, int month, DATE2WEEKDAY *date2weekday);
/* 格里历(GregorianCalendar) 1753 - ... */
int GregorianCalendar(int year, int month, DATE2WEEKDAY *date2weekday);
/* 特殊的1752年 */
int Special1752(int year, int month, DATE2WEEKDAY *date2weekday);
#endif /* #ifndef _CALENDAR_H_ */
[/code]
calendar.c
[code]
/**********************************************************************/
/* project : 万年历 */
/* version : Ver 1.0 */
/* file : calendar.c */
/* author : xstar.wxb */
/* date : 2008/08/01 */
/* history : */
/* date : 2008/08/01 ver : 1.0 author : xstar.wxb */
/**********************************************************************/
#include "calendar.h"
/* 月份数据 */
/* YEAR[ 0 ] 为平年数据 */
/* YEAR[ 1 ] 为闰年数据 */
/* YEAR[ 2 ] 为特殊年份数据 1752年 */
int YEAR[ 3 ][ 12 ] = {
{ 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 },
{ 31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 },
{ 31, 29, 31, 30, 31, 30, 31, 31, 19, 31, 30, 31 }
};
/* 儒略历(Julian Calendar) */
/* 公元1年1月1日为星期六 */
/* 1年1月1日 - 1752年9月2日 */
/* 1 3 5 7 8 10 12 为大月,31天 */
/* 4 6 9 11 为小月,30天 */
/* 2 能被4整除的年份为闰年,29天,其他年份为平年,28天 */
int JulianCalendar(int year, int month, DATE2WEEKDAY *date2weekday)
{
int leap = 0; /* 适用的月份数据 */
int firstday = 6; /* 每月1日的星期数 */
/* 是否为闰年,设置适用的月份数据 */
if ((year % 4) == 0)
{
leap = 1;
}
/* 计算每年的1月1日的星期数 */
/* 计算累加天数,1月1日: 前一年平年星期数累加一,前一年闰年星期数加二 */
/* year年1月1日 */
firstday = (5 + (5 * year - 1) / 4) % 7;
/* 计算month月1日的星期数 */
for (int i = 0; i < month - 1; i++)
{
firstday += YEAR[ leap ][ i ];
}
/* year年month月1日 */
firstday = firstday % 7;
/* month月 */
for (int i = 0; i < YEAR[ leap ][ month - 1 ]; i++)
{
date2weekday->date = i + 1;
date2weekday->weekday = (firstday + i) % 7;
date2weekday++;
}
/* 返回当月天数 */
return YEAR[ leap ][ month - 1 ];
}
/* 格里历(GregorianCalendar) */
/* 公元1753年1月1日为星期一 */
/* 1752年9月14日 - 现在,现行历法标准 */
/* 1 3 5 7 8 10 12 为大月,31天 */
/* 4 6 9 11 为小月,30天 */
/* 2 能被4整除且不能被100整除或能被400整除的年份为闰年,29天,其他年份为平年,28天 */
int GregorianCalendar(int year, int month, DATE2WEEKDAY *date2weekday)
{
int leap = 0; /* 适用的月份数据 */
int firstday = 1; /* 每月1日的星期数 */
int days = 0; /* 累加天数 */
/* 是否为闰年,设置适用的月份数据 */
if ((((year % 4) == 0) && ((year % 100) != 0)) || ((year % 400) == 0))
{
leap = 1;
}
/* 计算每年的1月1日的星期数 */
/* 初始化 */
days = 0;
/* 计算累加天数,1月1日: 前一年平年星期数累加一,前一年闰年星期数加二 */
for (int n = 1753; n < year; n++)
{
if ((((n % 4) == 0) && ((n % 100) != 0)) || ((n % 400) == 0))
{
days += 2; /* 闰年 */
} else {
days++; /* 平年 */
}
}
/* year年1月1日 */
firstday = (firstday + days) % 7;
/* 计算month月1日的星期数 */
for (int i = 0; i < month - 1; i++)
{
firstday += YEAR[ leap ][ i ];
}
/* year年month月1日 */
firstday = firstday % 7;
/* month月 */
for (int i = 0; i < YEAR[ leap ][ month - 1 ]; i++)
{
date2weekday->date = i + 1;
date2weekday->weekday = (firstday + i) % 7;
date2weekday++;
}
/* 返回当月天数 */
return YEAR[ leap ][ month - 1 ];
}
/* 推行新历法的时候为了消除历法和太阳周期的误差,1752年9月2日下一日期为1752年9月14日 */
/* 为计算方便这一年单独提取出来计算 */
/* 公元1752年1月1日为星期三 */
int Special1752(int year, int month, DATE2WEEKDAY *date2weekday)
{
int leap = 2; /* 适用的月份数据 特殊年份 */
int firstday = 3; /* 每月1日的星期数 */
/* 计算month月1日的星期数 */
for (int i = 0; i < month - 1; i++)
{
firstday += YEAR[ leap ][ i ];
}
/* 1752年month月1日 */
firstday = firstday % 7;
/* 9月份特殊处理 */
if (month == 9)
{
/* month月 */
for (int i = 0; i < YEAR[ leap ][ month - 1 ]; i++)
{
date2weekday->date = i + 1;
/* 1752年9月2日下一日期为1752年9月14日 */
if (date2weekday->date > 2)
{
date2weekday->date += 11;
}
date2weekday->weekday = (firstday + i) % 7;
date2weekday++;
}
/* 返回当月天数 */
return YEAR[ leap ][ month - 1 ];
}
/* 其他月份的处理 */
for (int i = 0; i < YEAR[ leap ][ month - 1 ]; i++)
{
date2weekday->date = i + 1;
date2weekday->weekday = (firstday + i) % 7;
date2weekday++;
}
/* 返回当月天数 */
return YEAR[ leap ][ month - 1 ];
}
[/code]
displaycalendar.h
[code]
/**********************************************************************/
/* project : 万年历 */
/* version : Ver 1.0 */
/* file : displaycalendar.h */
/* author : xstar.wxb */
/* date : 2008/08/01 */
/* history : */
/* date : 2008/08/01 ver : 1.0 author : xstar.wxb */
/**********************************************************************/
#ifndef _DISPLAYCALENDAR_H_
#define _DISPLAYCALENDAR_H_
#include "calendar.h"
typedef struct _MONTHDAY {
int days;
DATE2WEEKDAY date2weekday[ 31 ];
} MONTHDAY;
/* 显示日历函数 按月 */
int displaymonth(int year, int month);
/* 显示日历函数 按年 */
int displayyear(int year);
#endif /* #ifndef _DISPLAYCALENDAR_H_ */
[/code]
displaycalendar.c
[code]
/**********************************************************************/
/* project : 万年历 */
/* version : Ver 1.0 */
/* file : displaycalendar.c */
/* author : xstar.wxb */
/* date : 2008/08/01 */
/* history : */
/* date : 2008/08/01 ver : 1.0 author : xstar.wxb */
/**********************************************************************/
#include <stdio.h>
#include <stdlib.h>
#include "displaycalendar.h"
/* 星期 */
#define WEEKDAY "Su Mo Tu We Th Fr Sa"
/* 数字的ASCII码形式 */
char NUM[ 10 ] = { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9' };
/* 月份 */
char *MONTHSTR[ 12 ] = {
"January",
"February",
"March",
"April",
"May",
"June",
"July",
"August",
"September",
"October",
"November",
"December"
};
/* 显示日历函数 按月 */
int displaymonth(int year, int month)
{
int line = 0; /* 行 */
int days; /* 返回值,输入月份的天数 */
DATE2WEEKDAY date2weekday[ 31 ]; /* 返回值,输入月份的日期和星期对应关系 */
/* 显示用 */
char BUFF[ 6 ][ 21 ] = { /* 20 spaces */
" ", " ",
" ", " ",
" ", " "
};
/* 判断输入的参数,简单判断 */
if ((year < 1) || (year > 9999))
{
return -1;
}
/* 判断输入的参数,简单判断 */
if ((month < 1) || (month > 12))
{
return -1;
}
/* 判断输入的年份,调用适用的历法 */
if (year < 1752) {
/* 儒略历(Julian Calendar) 1 - 1751 */
days = JulianCalendar( year, month, &date2weekday[ 0 ] );
} else if (year == 1752) {
/* 特殊的1752年 */
days = Special1752( year, month, &date2weekday[ 0 ] );
} else if (year > 1752) {
/* 格里历(GregorianCalendar) 1753 - ... */
days = GregorianCalendar( year, month, &date2weekday[ 0 ] );
}
/* 初始化 */
line = 0;
/* 设置每行显示的内容 */
for (int i = 0; i < days; i++)
{
BUFF[ line ][ date2weekday[ i ].weekday * 3 ]
= NUM[ date2weekday[ i ].date / 10 ];
BUFF[ line ][ date2weekday[ i ].weekday * 3 + 1 ]
= NUM[ date2weekday[ i ].date % 10 ];
if (date2weekday[ i ].weekday == 6)
{
line++;
}
}
/* 显示 */
printf( " %s %4d\n", MONTHSTR[ month - 1], year );
printf( "%s\n", WEEKDAY );
for (int i = 0; i < 6; i++)
{
printf( "%s\n", BUFF[ i ] );
}
return 0;
}
/* 显示日历函数 按年 */
int displayyear(int year)
{
int line = 0; /* 行 */
MONTHDAY monthday[ 12 ]; /* 年 */
/* 显示用 */
char BUFF[ 12 ][ 6 ][ 21 ] = { /* 20 spaces */
{ " ", " ",
" ", " ",
" ", " " }, /* 1 */
{ " ", " ",
" ", " ",
" ", " " }, /* 2 */
{ " ", " ",
" ", " ",
" ", " " }, /* 3 */
{ " ", " ",
" ", " ",
" ", " " }, /* 4 */
{ " ", " ",
" ", " ",
" ", " " }, /* 5 */
{ " ", " ",
" ", " ",
" ", " " }, /* 6 */
{ " ", " ",
" ", " ",
" ", " " }, /* 7 */
{ " ", " ",
" ", " ",
" ", " " }, /* 8 */
{ " ", " ",
" ", " ",
" ", " " }, /* 9 */
{ " ", " ",
" ", " ",
" ", " " }, /* 10 */
{ " ", " ",
" ", " ",
" ", " " }, /* 11 */
{ " ", " ",
" ", " ",
" ", " " } /* 12 */
};
/* 判断输入的参数,简单判断 */
if ((year < 1) || (year > 9999))
{
return -1;
}
/* 判断输入的年份,调用适用的历法 */
if (year < 1752) {
/* 儒略历(Julian Calendar) 1 - 1751 */
for (int i = 0; i < 12; i++)
{
monthday[ i ].days = JulianCalendar( year, i + 1, &(monthday[ i ].date2weekday[ 0 ]) );
}
} else if (year == 1752) {
/* 特殊的1752年 */
for (int i = 0; i < 12; i++)
{
monthday[ i ].days = Special1752( year, i + 1, &(monthday[ i ].date2weekday[ 0 ]) );
}
} else if (year > 1752) {
/* 格里历(GregorianCalendar) 1753 - ... */
for (int i = 0; i < 12; i++)
{
monthday[ i ].days = GregorianCalendar( year, i + 1, &(monthday[ i ].date2weekday[ 0 ]) );
}
}
for (int month = 0; month < 12; month++)
{
/* 初始化 */
line = 0;
/* 设置每行显示的内容 */
for (int i = 0; i < monthday[ month ].days; i++)
{
BUFF[ month ][ line ][ monthday[ month ].date2weekday[ i ].weekday * 3 ]
= NUM[ monthday[ month ].date2weekday[ i ].date / 10 ];
BUFF[ month ][ line ][ monthday[ month ].date2weekday[ i ].weekday * 3 + 1 ]
= NUM[ monthday[ month ].date2weekday[ i ].date % 10 ];
if (monthday[ month ].date2weekday[ i ].weekday == 6)
{
line++;
}
}
}
printf( " %d\n\n", year );
for (int i = 0; i < 4; i++)
{
printf( " %10s %10s %10s\n",
MONTHSTR[ i * 3 ], MONTHSTR[ i * 3 + 1 ], MONTHSTR[ i * 3 + 2 ] );
printf( "%s %s %s\n",
WEEKDAY, WEEKDAY, WEEKDAY );
for (int j = 0; j < 6; j++)
{
printf( "%s %s %s\n",
BUFF[ i * 3 ][ j ],
BUFF[ i * 3 + 1 ][ j ],
BUFF[ i * 3 + 2 ][ j ] );
}
}
}
[/code]
顶一个!
不错。支持原创。。