作者 jjchen.bbs@bbs.ntnu.edu.tw (陳金進), 看板 mud
標題 Re: About MudOS 陰陽曆轉換程式
時間 師大計中(精靈之城) (Mon Mar 10 09:13:31 1997)
路徑 maple!news.cs.nthu!news.cis.nctu!news.cc.nctu!cc.ntnu!elfBBS!bbs
───────────────────────────────────────
※ 引述《Kenny.bbs@bbs.cis.nctu.edu.tw (小祥)》之銘言:
: 我也來貢獻一點… (改自 Wade 作品)
: #define BASE (723916800) // Dec 10 00:00:00 1992
: #define DAY (86400)
: #define MONTHS ({"Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug",\
: "Sep", "Oct", "Nov", "Dec"})
既然有人支持我, 在此再提供一個陽曆萬年曆月曆的程式,
配合國情, 我們只從民國元年起供應月曆.
// cal.c 類似 unix 上的 cal 命令
// 語法: cal 年 月
// 1997 3 10 wade@Fantasy.Space jjchen@ice.ntnu.edu.tw
// 歡迎流傳本程式, 請保留本說明
#include <localtime.h>
inherit F_CLEAN_UP;
// 這個雖然是 #define 來的, 可是只要更動其值, 會影響星期的算法
// 請見底下打十個星號的那一行的說明
#define FIRSTYEAR 1911
// 西曆年平年每月之日數
int *SolarCal = ({ 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 });
// 求此西曆年是否為閏年, 返回 0 為平年, 1 為閏年
int GetLeap (int year)
{
if ( year % 400 == 0 ) // 西曆年可被四百整除的話一定是潤年
return 1; // 如 1600, 2000 為潤年
else if ( year % 100 == 0 ) // 如果被一百整除卻不能被四百整除, 則為平年
return 0; // 如 1800, 1900 為平年
else if ( year % 4 == 0 ) // 不是一百的倍數卻是四的倍數, 則為潤年
return 1; // 如 1992, 1996, 2000, 2004 為潤年
else // 其餘皆為平年
return 0;
}
int main(object me, string arg)
{
mixed *local;
int leap; // 是否潤年
int yy, mm, dd; // 要查詢的日期
int ty, tm, td; // 今天的日期
int acc; // 累積天數, 用來算星期幾用的
int Weekday; // 本月的第一天為星期幾
int d; // 該月的天數
int i;
// 取得今天的日期
local = localtime(time());
ty = local[LT_YEAR]-1911;
tm = local[LT_MON]+1;
td = local[LT_MDAY];
if (!arg || arg == "") { // 本月份
yy = ty;
mm = tm;
dd = td;
}
else { // 指定的月份
if (!sscanf (arg, "%d%d", yy, mm) == 2) {
printf ("語法: cal 年 月\n");
return 1;
}
yy += 1911;
dd = td;
}
if (yy < FIRSTYEAR) {
printf ("對不起, 目前只提供 %d 年以上的月曆.\n", FIRSTYEAR);
return 1;
}
// 是否為潤年
leap = GetLeap ( yy );
// 由是否潤年計算該月的天數
if ( mm == 1 ) // 二月
d = leap + 28;
else
d = SolarCal[mm-1];
acc = 0;
// 計算累積到去年的日數 from 公元 FIRSTYEAR年
for (i=FIRSTYEAR; i<yy; i++)
acc = acc + 365 + GetLeap (i);
// 計算累積到上個月的日數
for (i=1; i<mm; i++)
acc = acc + SolarCal[i-1];
if (mm > 2 && GetLeap (yy)) acc++; // 今年潤年加一天
// 本月第一日的星期數
// ********** 這邊的算法是因為 1911 年的 1 月 1 日是星期日 **********
Weekday = acc % 7;
printf ("中華民國 %d 年 %d 月\n日 一 二 三 四 五 六\n", yy-1911, mm);
for (i=0; i<Weekday; i++)
printf (" ");
for (i=1; i<=d; i++) {
printf ("%2d ", i);
if ((Weekday + i) % 7 == 0)
printf ("\n");
}
printf ("\n");
return 1;
}