C言語でカレンダー表示
昔似たモノを作ったはずなのに見つかりません。
なので作りなおしました。
引数なしで今月のカレンダー、年月を指定すればその月のカレンダーを表示します。
まずは、Zellerの公式が必要。年月日から曜日を求めるやつ。
それと、閏年かどうかを判定する関数。
当時は2000年より前だったから、2000年に正しく動くかどうか何度もテストしました。
今は各種ライブラリが用意されているけれど、昔はみんな手作りしていました。
VisualStudioで開発したのだけれど、localtimeで警告されるので、#pragmaで無効にしてます。
#include <stdio.h> #include <stdlib.h> #include <time.h> #pragma warning(disable: 4996) // 'localtime': This function or variable may be unsafe. Consider using localtime_s instead. To disable deprecation, use _CRT_SECURE_NO_WARNINGS. See online help for details. // ツェラーの公式 // 1:月 2:火 3:水 4:木 5:金 6:土 7:日 int getZeller(int yyyy, int mm, int dd) { int c, y, gamma, d; if (mm <= 2) { yyyy -= 1; mm += 12; } c = yyyy / 100; y = yyyy % 100; gamma = 5 * c + (c / 4); d = (dd + (26 * (mm + 1) / 10) + y + y / 4 + gamma + 5) % 7 + 1; return d; } // 閏年か? // 1:閏年 0:閏年ではない int isLeapYear(int yyyy) { return yyyy % 4 == 0 && yyyy % 100 != 0 || yyyy % 400 == 0; } // 指定した年月の日数を返す // ex. (2000, 2) => 29 int getDays(int yyyy, int mm) { switch (mm) { case 2: return isLeapYear(yyyy) ? 29 : 28; case 4: case 6: case 9: case 11: return 30; default: return 31; } } void dispCalendar(int yyyy, int mm) { int dd, days, youbi, i; printf(" *** %4d年%2d月 ***\n", yyyy, mm); printf("日 月 火 水 木 金 土\n"); days = getDays(yyyy, mm); youbi = getZeller(yyyy, mm, 1); if (youbi != 7) { for (i = 0; i < youbi; i++) { printf(" "); } } for (dd = 1; dd <= days; dd++) { printf("%2d ", dd); if ((dd + youbi) % 7 == 0) printf("\n"); } } int main(int argc, char* argv[]) { int yyyy, mm; fprintf(stderr, "calen version 0.0\n"); fprintf(stderr, "Copyright (C) Yoshinori Watanabe 2021. All Rights Reserved.\n"); fprintf(stderr, "\n"); if (argc == 3) { // 引数より年月を取得 yyyy = atoi(argv[1]); mm = atoi(argv[2]); } else if (argc == 1) { // 現在日時より年月を取得 time_t timer; struct tm* local; timer = time(NULL); local = localtime(&timer); yyyy = local->tm_year + 1900; mm = local->tm_mon + 1; } else { // 使い方を説明 printf("usage: calen <yyyy> <mm>\n"); return 1; } dispCalendar(yyyy, mm); return 0; }