【datecalc.cのソースコード】
/*
 * 日付の間の計算を行うプログラム
 * datecalc.c(date calculation)
 *
 * 1582年10月15日以降(グレゴリオ暦上)、9999年12月31日以前で動作する。
 * 西暦0年1月1日((*)拡張したグレゴリオ暦による)からの日数で計算する。
 */
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include <string.h> /* strcspn, strcmp, strcat */
#include <ctype.h>  /* isdigit */
#define BUF_SIZE 256
/*
 * 自作のbool型の定義
 */
typedef enum {
    false,
    true
} bool;
/*
 * 構造体dateの定義
 */
struct date {
    int year;
    int month;
    int day;
};
/*
 * ユーザー定義関数の関数原型宣言
 */
void initialize(void);
void menu(void);
void proc1_print_title(void);
bool proc1_input(void);
bool input_date(struct date *some_datep);
bool input_year(int *yearp);
bool is_valid_integer(char buf[]);
bool input_month(int *monthp);
bool input_day(int year, int month, int *dayp);
int get_days_of_the_month(int year, int month);
bool is_leap_year(int year);
void proc1_calc(void);
int get_days_to_the_date(struct date some_date);
int get_days_to_the_year(int year);
int get_days_in_the_year(struct date some_date);
void comma_sep(char *sp, int n);
void proc1_output(void);
void output_result_dif(void);
void foutput_result_dif(void);
void gen_filename(char filename[]);
bool retry(void);
void proc2_print_title(void);
bool proc2_input(void);
void addsub_date(struct date *date2p);
bool is_out_of_range(struct date some_date);
void proc2_output(void);
void output_result_addsub(void);
void foutput_result_addsub(void);
/*
 * グローバル変数
 */
bool is_first_output = true;
char sel_proc, addsub, strdays[BUF_SIZE], filename[BUF_SIZE];
int days;
struct date date1, date2, *date2p;
/*
 * メイン関数
 */
int main(void)
{
    /* 初期化 */
    initialize();
    
    while (1) {
        do_menu:
            /* メニュー */
            menu();
        
        /* メニューからの処理の分岐 */
        switch (sel_proc) {
        
         /* 処理1(差の計算) */
         case '1':
            /* 処理1中の標題の表示 */
            proc1_print_title();
            
            /* 処理1中の入力 */
            if (!proc1_input())
                goto do_menu;
            
            /* 処理1中の計算 */
            proc1_calc();
            
            /* 処理1中の出力 */
            proc1_output();
            
            /* 操作を繰り返すかどうかの選択 */
            if (!retry())
                goto do_end;
            break;
        
         /* 処理2(日数の足し算引き算) */
         case '2':
            /* 処理2中の標題の表示 */
            proc2_print_title();
            
            while (1) {
                /* 処理2中の入力 */
                if (!proc2_input())
                    goto do_menu;
                
                /* 処理2中の計算 */
                addsub_date(&date2);
                
                /* 計算結果の日付が計算対象の範囲内かどうかで分岐 */
                if (!is_out_of_range(date2))
                    break;
            }
            
            /* 処理2中の出力 */
            proc2_output();
            
            /* 操作を繰り返すかどうかの選択 */
            if (!retry())
                goto do_end;
            break;
        
         /* 処理0(プログラムの終了) */
         case '0':
            goto do_end;
        
         default:
            break;
        }
    }
    do_end:
        printf("プログラムを終了します。\n");
        return EXIT_SUCCESS;
}
/*
 * 初期化を行う関数
 */
void initialize(void)
{
    /* 乱数系列の設定 */
    srand((unsigned int)time(NULL));
}
/*
 * メニューの関数
 */
void menu(void)
{
    char buf[BUF_SIZE], zz;
    
    /* 標題の表示 */
    printf("【日付に関する2通りの計算を行います】\n\n"
     "次のいずれかを選択してください。\n\n");
    
    /* 処理の選択 */
    while (1) {
        printf("1.日付の間の差を計算する。\n"
         "2.日付に日数を足したり引いたりする。\n"
         "0.終了する。\n\n0、1、2のどれですか? ");
        fgets(buf, sizeof buf, stdin);
        sscanf(buf, "%c%c", &sel_proc, &zz);
        if ((sel_proc != '0' && sel_proc != '1' && sel_proc != '2') ||
         zz != '\n') {
            printf("無効な入力です。\n"
             "0、1、2のいずれかを入力してください。\n\n");
            continue;
        } else
            break;
    }
}
/*
 * 処理1中の標題を表示する関数
 */
void proc1_print_title(void)
{
    printf("\n【日付の間の差を計算します】\n\n"
     "「日付1」をより古い日付、「日付2」をより新しい日付とします。\n"
     "各日付を入力してください。\n\n");
}
/*
 * 処理1中の入力処理をする関数
 * true: 次に進む、false: 中断してメニューに戻る。
 * input_date関数を使用する。
 */
bool proc1_input(void)
{
    while (1) {
        printf("日付1を入力してください。\n"
         "途中で中断したい場合は、qを入力してください。\n");
        if (!input_date(&date1)) {
            printf("\n+++++\n\n");
            return false;
        }
        
        printf("日付2を入力してください。\n"
         "途中で中断したい場合は、qを入力してください。\n");
        if (!input_date(&date2)) {
            printf("\n+++++\n\n");
            return false;
        }
        
        if (10000*date1.year+100*date1.month+date1.day >
         10000*date2.year+100*date2.month+date2.day) {
            printf("日付1と日付2の順序が逆です。\n"
             "日付1がより古い日付、日付2がより新しい日付となるように"
             "入力してください。\n\n");
            continue;
        } else
            break;
    }
    return true;
}
/*
 * 日付を入力する関数
 * true: 次に進む、false: 中断してメニューに戻る。
 * input_year関数、input_month関数およびinput_day関数を使用する。
 */
bool input_date(struct date *some_datep)
{
    while (1) {
        /* 年の入力 */
        if (!input_year(&some_datep->year))
            return false;
        
        /* 月の入力 */
        if (!input_month(&some_datep->month))
            return false;
        
        /* 日の入力 */
        if (!input_day(some_datep->year, some_datep->month, &some_datep->day))
            return false;
        
        /* 入力結果がグレゴリオ暦の範囲内かどうかで分岐 */
        if (10000*some_datep->year+100*some_datep->month+some_datep->day
         < 15821015) {
            printf("%d年%d月%d日はグレゴリオ暦の範囲外です。\n"
             "1582年10月15日以降の日付を入力してください。\n"
             "途中で中断したい場合は、qを入力してください。\n\n",
             some_datep->year, some_datep->month, some_datep->day);
            continue;
        } else
            break;
    }
    return true;
}
/*
 * 年を入力する関数
 * true: 次に進む、false: 中断してメニューに戻る。
 * is_valid_integer関数を使用する。
 */
bool input_year(int *yearp)
{
    char buf[BUF_SIZE], zz;
    
    while (1) {
        printf("年 = ?(西暦で) ");
        fgets(buf, sizeof buf, stdin);
        sscanf(buf, "%d%c", yearp, &zz);
        buf[strcspn(buf, "\n")] = '\0';
        
        /* 中断判定 */
        if (strcmp(buf, "q") == 0 || strcmp(buf, "Q") == 0)
            return false;
        
        if (!is_valid_integer(buf)) {
            printf("無効な入力です。\n半角整数値を入力してください。\n"
             "途中で中断したい場合は、qを入力してください。\n\n");
            continue;
        } else if (*yearp < 1582) {
            printf("%d年はグレゴリオ暦の範囲外です。\n"
             "1582年以降の年を入力してください。\n"
             "途中で中断したい場合は、qを入力してください。\n\n",*yearp);
            continue;
        } else if (*yearp > 9999) {
            printf("無効な入力です。\n9999年以前の年を入力してください。\n"
             "途中で中断したい場合は、qを入力してください。\n\n");
            continue;
        } else
            break;
    }
    return true;
}
/*
 * 文字列が正しい形式の整数値かどうかを判定する関数
 * true: 正しい形式である、false: 無効な形式である。
 */
bool is_valid_integer(char buf[])
{
    int i = 0;
    
    /* 空文字列ならば偽を返す */
    if (buf[0] == '\0')
        return false;
    
    /* 最初は符号(省略可) */
    if (buf[i] == '+' || buf[i] == '-')
        i++;
    /* 次に数字(省略不可) */
    if (!isdigit((unsigned char)buf[i]))
        return false;
    i++;
    /* 次に数字列(省略可) */
    while (isdigit((unsigned char)buf[i]))
        i++;
    
    /* 他に余計な文字がなければ真、あれば偽を返す */
    return buf[i] == '\0';
}
/*
 * 月を入力する関数
 * true: 次に進む、false: 中断してメニューに戻る。
 * is_valid_integer関数を使用する。
 */
bool input_month(int *monthp)
{
    char buf[BUF_SIZE], zz;
    
    while (1) {
        printf("月 = ? ");
        fgets(buf, sizeof buf, stdin);
        sscanf(buf, "%d%c", monthp, &zz);
        buf[strcspn(buf, "\n")] = '\0';
        
        /* 中断判定 */
        if (strcmp(buf, "q") == 0 || strcmp(buf, "Q") == 0)
            return false;
        
        if (!is_valid_integer(buf)) {
            printf("無効な入力です。\n半角整数値を入力してください。\n"
             "途中で中断したい場合は、qを入力してください。\n\n");
            continue;
        } else if (*monthp < 1 || 12 < *monthp) {
            printf("無効な入力です。\n"
             "1から12の整数値を入力してください。\n"
             "途中で中断したい場合は、qを入力してください。\n\n");
            continue;
        } else
            break;
    }
    return true;
}
/*
 * 日を入力する関数
 * true: 次に進む、false: 中断してメニューに戻る。
 * is_valid_integer関数とget_days_of_the_month関数を使用する。
 */
bool input_day(int year, int month, int *dayp)
{
    char buf[BUF_SIZE], zz;
    
    while (1) {
        printf("日 = ? ");
        fgets(buf, sizeof buf, stdin);
        sscanf(buf, "%d%c", dayp, &zz);
        buf[strcspn(buf, "\n")] = '\0';
        
        /* 中断判定 */
        if (strcmp(buf, "q") == 0 || strcmp(buf, "Q") == 0)
            return false;
        
        if (!is_valid_integer(buf)) {
            printf("無効な入力です。\n半角整数値を入力してください。\n"
             "途中で中断したい場合は、qを入力してください。\n\n");
            continue;
        } else if (*dayp < 1 ||
         get_days_of_the_month(year, month) < *dayp) {
            printf("無効な入力です。\n"
             "%d年%d月は、1日から%d日までです。\n", year, month,
             get_days_of_the_month(year, month));
            printf("1から%dの整数値を入力してください。\n"
             "途中で中断したい場合は、qを入力してください。\n\n",
             get_days_of_the_month(year, month));
            continue;
        } else
            break;
    }
    return true;
}
/*
 * ある月に含まれる日数を返す関数
 * is_leap_year関数を使用する。
 */
int get_days_of_the_month(int year,int month)
{
    int days;
    
    switch (month) {
     /* 2月 */
     case 2:
        if (is_leap_year(year))
            days = 29;
        else
            days = 28;
        break;
    
     /* 4、6、9、11月 */
     case 4:
     case 6:
     case 9:
     case 11:
        days = 30;
        break;
    
     /* 1、3、5、7、8、10、12月 */
     case 1:
     case 3:
     case 5:
     case 7:
     case 8:
     case 10:
     case 12:
        days = 31;
        break;
    
     default:
        break;
    }
    return days;
}
/*
 * うるう年の判定をする関数
 * true: うるう年である、false: うるう年でない。
 *
 * 400で割り切れればうるう年である。
 * 400で割り切れず、100で割り切れればうるう年でない。
 * 100で割り切れず、4で割り切れればうるう年である。
 * 4で割り切れなければうるう年でない。
 */
bool is_leap_year(int year)
{
    return (year % 400 == 0 || (year % 100 && year % 4 == 0));
}
/*
 * 処理1中の計算をする関数
 * get_days_to_the_date関数とcomma_sep関数を使用する。
 */
void proc1_calc(void)
{
    /* 日数の計算 */
    days = get_days_to_the_date(date2) - get_days_to_the_date(date1);
    
    /* 日数を3桁ずつコンマで区切った文字列に変換 */
    comma_sep(strdays, days);
}
/*
 * 西暦0年1月1日(*)からその日までの日数を返す関数
 * ((*)拡張したグレゴリオ暦による)
 * get_days_to_the_year関数とget_days_in_the_year関数を使用する。
 */
int get_days_to_the_date(struct date some_date)
{
    return get_days_to_the_year(some_date.year) +
     get_days_in_the_year(some_date);
}
/*
 * 西暦0年1月1日(*)からその年の1月1日までの日数を返す関数
 * ((*)拡張したグレゴリオ暦による)
 * is_leap_year関数を使用する。
 */
int get_days_to_the_year(int year)
{
    int numleap = 0, i;
    
    for (i = 0; i < year; i++)
        if (is_leap_year(i))
            numleap++;
    return (365 * year + numleap);
}
/*
 * その年(*)の1月1日からその日までの日数を返す関数
 * ((*)拡張したグレゴリオ暦による)
 * get_days_of_the_month関数を使用する。
 */
int get_days_in_the_year(struct date some_date)
{
    int i, temp_days = some_date.day;
    
    temp_days--;
    for (i = some_date.month - 1; i > 0; i--)
        temp_days += get_days_of_the_month(some_date.year, i);
    return temp_days;
}
/*
 * 数値を3桁ずつコンマで区切った文字列に変換する関数
 */
void comma_sep(char *sp, int n)
{
    char *p = sp, c;
    int digit = 0, m = n, len = 0;
    
    /* nの桁数をlenに取得 */
    if (m == 0)
        len = 1;
    else
        while (m > 0) {
            m /= 10;
            len++;
        }
    
    /* nが0の場合は"0"を格納 */
    if (n == 0) {
        *p++ = '0';
        *p-- = '\0';
    }
    /* n > 0の場合は1の位からコンマで区切って格納 */
    else {
        while (n > 0) {
            *p++ = '0' + (n % 10);
            n /= 10;
            digit++;
            if (digit % 3 == 0 && digit != len)
                *p++ = ',';
        }
        *p-- = '\0';
    }
    
    /* 文字列を逆順に並べ替え */
    while (sp < p) {
        c = *sp;
        *sp++ = *p;
        *p-- = c;
    }
}
/*
 * 処理1中の出力処理をする関数
 * output_result_dif関数とfoutput_result_dif関数を使用する。
 */
void proc1_output(void)
{
    char buf[BUF_SIZE], ch, zz;
    
    /* 画面への出力 */
    output_result_dif();
    
    /* ファイルに出力するかどうかの分岐 */
    while (1) {
        printf("ファイルに出力しますか?(y/n) ");
        fgets(buf, sizeof buf, stdin);
        sscanf(buf, "%c%c", &ch, &zz);
        if ((ch == 'y' || ch == 'Y') && zz == '\n') {
            foutput_result_dif();
            break;
        } else if ((ch == 'n' || ch == 'N') && zz == '\n')
            break;
        else {
            printf("無効な入力です。\nyまたはnを入力してください。\n\n");
            continue;
        }
    }
}
/*
 * 差の計算の結果を画面に出力する関数
 */
void output_result_dif(void)
{
    printf("%d年%d月%d日と%d年%d月%d日の差は、%s日です。\n",
     date1.year, date1.month, date1.day,
     date2.year, date2.month, date2.day,
     strdays);
}
/*
 * 差の計算の結果をファイルに出力する関数
 * gen_filename関数を使用する。
 */
void foutput_result_dif(void)
{
    FILE *fp;
    
    /* 新規ファイル出力か追記かの分岐 */
    if (is_first_output) {
        /* 初めてのファイル出力のときだけファイル名を生成して新規作成 */
        gen_filename(filename);
        fp = fopen(filename, "w");
        if (fp == NULL) {
            printf("ファイルを開けません。ファイル出力を中断します。\n");
            return;
        }
        is_first_output = false; /* 以降は追記状態になる */
    } else {
        /* 2回目以降のファイル出力は追記 */
        fp = fopen(filename, "a");
        if (fp == NULL) {
            printf("ファイルを開けません。ファイル出力を中断します。\n");
            return;
        }
    }
    
    fprintf(fp, "%d年%d月%d日と%d年%d月%d日の差は、%s日です。\n",
     date1.year, date1.month, date1.day,
     date2.year, date2.month, date2.day,
     strdays);
    fclose(fp);
}
/*
 * 現在日付時刻からファイル名を生成する関数
 */
void gen_filename(char filename[])
{
    char strnumrand[10];
    time_t tt = time(NULL);
    struct tm *t = localtime(&tt);
    
    sprintf(filename, "datecalc%04d%02d%02d_%02d%02d%02d_",
     1900+(t->tm_year), 1+(t->tm_mon), t->tm_mday,
     t->tm_hour, t->tm_min, t->tm_sec);
    sprintf(strnumrand, "%04d", rand() % 10000);
    strcat(filename, strnumrand);
    strcat(filename, ".txt");
}
/*
 * 操作を繰り返すかどうかを選択する関数
 * true: 繰り返す、false: 終了する。
 */
bool retry(void)
{
    bool flag;
    char buf[BUF_SIZE], ch, zz;
    
    while (1) {
        printf("\n繰り返しますか?(y/n) ");
        fgets(buf, sizeof buf, stdin);
        sscanf(buf, "%c%c", &ch, &zz);
        if ((ch == 'y' || ch == 'Y') && zz == '\n') {
            printf("\n+++++\n\n");
            flag = true;
            break;
        } else if ((ch == 'n' || ch == 'N') && zz == '\n') {
            flag = false;
            break;
        }
        printf("無効な入力です。\nyまたはnを入力してください。\n");
    }
    return flag;
}
/*
 * 処理2中の標題を表示する関数
 */
void proc2_print_title(void)
{
    printf("\n【日付に日数を足したり引いたりします】\n\n");
}
/*
 * 処理2中の入力処理をする関数
 * true: 次に進む、false: 中断してメニューに戻る。
 * input_date関数、is_valid_integer関数およびcomma_sep関数を使用する。
 */
bool proc2_input(void)
{
    char buf[BUF_SIZE], zz;
    
    /* 日付の入力 */
    printf("日付を入力してください。\n"
     "途中で中断したい場合は、qを入力してください。\n");
    if (!input_date(&date1)) {
        printf("\n+++++\n\n");
        return false;
    }
    
    /* +か-かの入力 */
    while (1) {
        printf("足し算(+)か引き算(-)かを入力してください。\n"
         "途中で中断したい場合は、qを入力してください。\n"
         "「+」ですか、「-」ですか? ");
        fgets(buf, sizeof buf, stdin);
        sscanf(buf, "%c%c", &addsub, &zz);
        buf[strcspn(buf, "\n")] = '\0';
        
        /* 中断判定 */
        if (strcmp(buf, "q") == 0 || strcmp(buf, "Q") == 0) {
            printf("\n+++++\n\n");
            return false;
        }
        
        if ((addsub != '+' && addsub != '-') || zz != '\n') {
            printf("無効な入力です。\n"
             "半角の「+」または「-」を入力してください。\n\n");
            continue;
        } else
            break;
    }
    
    /* 日数の入力 */
    while (1) {
        printf("日数を入力してください。\n"
         "途中で中断したい場合は、qを入力してください。\n"
         "日数 = ? ");
        fgets(buf, sizeof buf, stdin);
        sscanf(buf, "%d%c", &days, &zz);
        buf[strcspn(buf, "\n")] = '\0';
        
        /* 中断判定 */
        if (strcmp(buf, "q") == 0 || strcmp(buf, "Q") == 0) {
            printf("\n+++++\n\n");
            return false;
        }
        
        if (!is_valid_integer(buf)) {
            printf("無効な入力です。\n半角整数値を入力してください。\n\n");
            continue;
        } else if (days < 0) {
            printf("負の日数の入力は受け付けません。\n"
             "0以上の整数を入力してください。\n\n");
            continue;
        } else
            break;
    }
    
    /* 日数を3桁ずつコンマで区切った文字列に変換 */
    comma_sep(strdays, days);
    
    return true;
}
/*
 * 日付に日数を足したり引いたりする関数
 * get_days_of_the_month関数を使用する。
 */
void addsub_date(struct date *date2p)
{
    /* 初期化 */
    date2p->year = date1.year;
    date2p->month = date1.month;
    
    /* 足し算か引き算か */
    switch (addsub) {
    
     /* 足し算の場合 */
     case '+':
        date2p->day = date1.day + days;
        while (date2p->day >
         get_days_of_the_month(date2p->year, date2p->month)) {
            date2p->day -= get_days_of_the_month(date2p->year, date2p->month);
            date2p->month++;
            if (date2p->month > 12) { /* 年をまたぐ場合 */
                date2p->year++;
                date2p->month = 1;
            }
        }
        break;
    
     /* 引き算の場合 */
     case '-':
        date2p->day = date1.day - days;
        while (date2p->day < 1 ||
         get_days_of_the_month(date2p->year, date2p->month) < date2p->day) {
            date2p->month--;
            if (date2p->month < 1) { /* 年をまたぐ場合 */
                date2p->year--;
                date2p->month = 12;
            }
            date2p->day += get_days_of_the_month(date2p->year, date2p->month);
        }
        break;
    
     default:
        break;
    }
}
/*
 * 計算結果の日付が計算対象の範囲内かどうかを判定する関数
 * true: 範囲外である、false: 範囲内である。
 */
bool is_out_of_range(struct date some_date)
{
    bool flag = true;
    int num_date =
     10000*some_date.year+100*some_date.month+some_date.day;
    
    /* グレゴリオ暦の範囲外の場合 */
    if (num_date < 15821015)
        printf("1582年10月15日より古い日付は計算できません。\n"
         "(グレゴリオ暦の範囲外です。)\n入力をやり直してください。\n\n");
    
    /* 9999年12月31日より新しい日付の場合 */
    else if (num_date > 99991231)
        printf("9999年12月31日より新しい日付は計算できません。\n"
         "入力をやり直してください。\n\n");
    
    /* 計算対象の範囲内の場合 */
    else
        flag = false;
    
    return flag;
}
/*
 * 処理2中の出力処理をする関数
 * output_result_addsub関数とfoutput_result_addsub関数を使用する。
 */
void proc2_output(void)
{
    char buf[BUF_SIZE], ch, zz;
    
    /* 画面への出力 */
    output_result_addsub();
    
    /* ファイルに出力するかどうかの分岐 */
    while (1) {
        printf("ファイルに出力しますか?(y/n) ");
        fgets(buf, sizeof buf, stdin);
        sscanf(buf, "%c%c", &ch, &zz);
        if ((ch == 'y' || ch == 'Y') && zz == '\n') {
            foutput_result_addsub();
            break;
        } else if ((ch == 'n' || ch == 'N') && zz == '\n')
            break;
        else {
            printf("無効な入力です。\nyまたはnを入力してください。\n\n");
            continue;
        }
    }
}
/*
 * 足し算引き算の結果を画面に出力する関数
 */
void output_result_addsub(void)
{
    switch (addsub) {
     case '+':
        printf("%d年%d月%d日足す%s日は、",
         date1.year, date1.month, date1.day, strdays);
        break;
     case '-':
        printf("%d年%d月%d日引く%s日は、",
         date1.year, date1.month, date1.day, strdays);
        break;
     default:
        break;
    }
    printf("%d年%d月%d日です。\n", date2.year, date2.month, date2.day);
}
/*
 * 足し算引き算の結果をファイルに出力する関数
 * gen_filename関数を使用する。
 */
void foutput_result_addsub(void)
{
    FILE *fp;
    
    /* 新規ファイル出力か追記かの分岐 */
    if (is_first_output) {
        /* 初めてのファイル出力のときだけファイル名を生成して新規作成 */
        gen_filename(filename);
        fp = fopen(filename, "w");
        if (fp == NULL) {
            printf("ファイルを開けません。ファイル出力を中断します。\n");
            return;
        }
        is_first_output = false; /* 以降は追記状態になる */
    } else {
        /* 2回目以降のファイル出力は追記 */
        fp = fopen(filename, "a");
        if (fp == NULL) {
            printf("ファイルを開けません。ファイル出力を中断します。\n");
            return;
        }
    }
    
    switch (addsub) {
     case '+':
        fprintf(fp, "%d年%d月%d日足す%s日は、",
         date1.year, date1.month, date1.day, strdays);
        break;
     case '-':
        fprintf(fp, "%d年%d月%d日引く%s日は、",
         date1.year, date1.month, date1.day, strdays);
        break;
     default:
        break;
    }
    fprintf(fp, "%d年%d月%d日です。\n", date2.year, date2.month, date2.day);
    fclose(fp);
}
C:\Users\skonishi\Documents>datecalc
【日付に関する2通りの計算を行います】
次のいずれかを選択してください。
1.日付の間の差を計算する。
2.日付に日数を足したり引いたりする。
0.終了する。
0、1、2のどれですか? 3
無効な入力です。                                                                ←0、1、2のいずれでもなければ入力繰り返し。 
0、1、2のいずれかを入力してください。
1.日付の間の差を計算する。
2.日付に日数を足したり引いたりする。
0.終了する。
0、1、2のどれですか? 2
【日付に日数を足したり引いたりします】
日付を入力してください。
途中で中断したい場合は、qを入力してください。
年 = ?(西暦で) 1
1年はグレゴリオ暦の範囲外です。                                                 ←1581年以前の年は無効。 
1582年以降の年を入力してください。
途中で中断したい場合は、qを入力してください。
年 = ?(西暦で) 1582y
無効な入力です。                                                                ←数値以外は無効。 
半角整数値を入力してください。
途中で中断したい場合は、qを入力してください。
年 = ?(西暦で) 15820
無効な入力です。                                                                ←10000年以降の年は無効。 
9999年以前の年を入力してください。
途中で中断したい場合は、qを入力してください。
年 = ?(西暦で) 1582
月 = ? 1
日 = ? 1
1582年1月1日はグレゴリオ暦の範囲外です。                                        ←日付はグレゴリオ暦の範囲内に限る。 
1582年10月15日以降の日付を入力してください。
途中で中断したい場合は、qを入力してください。
年 = ?(西暦で) 1582
月 = ? 10
日 = ? 15
足し算(+)か引き算(-)かを入力してください。
途中で中断したい場合は、qを入力してください。
「+」ですか、「-」ですか? -
日数を入力してください。
途中で中断したい場合は、qを入力してください。
日数 = ? 1
1582年10月15日より古い日付は計算できません。                                    ←計算結果がグレゴリオ暦から外れる場合のエラー処理。 
(グレゴリオ暦の範囲外です。)
入力をやり直してください。
日付を入力してください。
途中で中断したい場合は、qを入力してください。
年 = ?(西暦で) 1582
月 = ? 10
日 = ? 15
足し算(+)か引き算(-)かを入力してください。
途中で中断したい場合は、qを入力してください。
「+」ですか、「-」ですか? -
日数を入力してください。
途中で中断したい場合は、qを入力してください。
日数 = ? -1
負の日数の入力は受け付けません。                                                ←負の日数が入力された場合のエラー処理。 
0以上の整数を入力してください。
日数を入力してください。
途中で中断したい場合は、qを入力してください。
日数 = ? 0
1582年10月15日引く0日は、1582年10月15日です。
ファイルに出力しますか?(y/n) yy
無効な入力です。                                                                ←yでもnでもなければ入力繰り返し。 
yまたはnを入力してください。
ファイルに出力しますか?(y/n) y
繰り返しますか?(y/n) x
無効な入力です。                                                                ←yでもnでもなければ入力繰り返し。 
yまたはnを入力してください。
繰り返しますか?(y/n) y
+++++
【日付に関する2通りの計算を行います】
次のいずれかを選択してください。
1.日付の間の差を計算する。
2.日付に日数を足したり引いたりする。
0.終了する。
0、1、2のどれですか? 2
【日付に日数を足したり引いたりします】
日付を入力してください。
途中で中断したい場合は、qを入力してください。
年 = ?(西暦で) 9999
月 = ? 12
日 = ? 31
足し算(+)か引き算(-)かを入力してください。
途中で中断したい場合は、qを入力してください。
「+」ですか、「-」ですか? +
日数を入力してください。
途中で中断したい場合は、qを入力してください。
日数 = ? 1
9999年12月31日より新しい日付は計算できません。                                  ←計算結果が9999年12月31より新しい日付になる場合のエラー処理。 
入力をやり直してください。
日付を入力してください。
途中で中断したい場合は、qを入力してください。
年 = ?(西暦で) 9999
月 = ? 12
日 = ? 31
足し算(+)か引き算(-)かを入力してください。
途中で中断したい場合は、qを入力してください。
「+」ですか、「-」ですか? +
日数を入力してください。
途中で中断したい場合は、qを入力してください。
日数 = ? 0
9999年12月31日足す0日は、9999年12月31日です。
ファイルに出力しますか?(y/n) y
繰り返しますか?(y/n) y
+++++
【日付に関する2通りの計算を行います】
次のいずれかを選択してください。
1.日付の間の差を計算する。
2.日付に日数を足したり引いたりする。
0.終了する。
0、1、2のどれですか? 2000
無効な入力です。                                                                ←間違えて日付を入力しようとしてもエラー処理される。 
0、1、2のいずれかを入力してください。
1.日付の間の差を計算する。
2.日付に日数を足したり引いたりする。
0.終了する。
0、1、2のどれですか? 2
【日付に日数を足したり引いたりします】
日付を入力してください。
途中で中断したい場合は、qを入力してください。
年 = ?(西暦で) 2000
月 = ? 13
無効な入力です。                                                                ←「13月」はありえない。 
1から12の整数値を入力してください。
途中で中断したい場合は、qを入力してください。
月 = ? 2
日 = ? 30
無効な入力です。                                                                ←「2000年2月30日」はありえない。 
2000年2月は、1日から29日までです。
1から29の整数値を入力してください。
途中で中断したい場合は、qを入力してください。
日 = ? q                                                                        ←qを入力すると入力操作を中断できる。 
+++++
【日付に関する2通りの計算を行います】
次のいずれかを選択してください。
1.日付の間の差を計算する。
2.日付に日数を足したり引いたりする。
0.終了する。
0、1、2のどれですか? 2
【日付に日数を足したり引いたりします】
日付を入力してください。
途中で中断したい場合は、qを入力してください。
年 = ?(西暦で) 2021
月 = ? 7
日 = ? 23
足し算(+)か引き算(-)かを入力してください。
途中で中断したい場合は、qを入力してください。
「+」ですか、「-」ですか? -
日数を入力してください。
途中で中断したい場合は、qを入力してください。
日数 = ? 100
2021年7月23日引く100日は、2021年4月14日です。                                   ←「東京オリンピック開幕の100日前。」 
ファイルに出力しますか?(y/n) y
繰り返しますか?(y/n) y
+++++
【日付に関する2通りの計算を行います】
次のいずれかを選択してください。
1.日付の間の差を計算する。
2.日付に日数を足したり引いたりする。
0.終了する。
0、1、2のどれですか? 1
【日付の間の差を計算します】
「日付1」をより古い日付、「日付2」をより新しい日付とします。
各日付を入力してください。
日付1を入力してください。
途中で中断したい場合は、qを入力してください。
年 = ?(西暦で) 2021
月 = ? 7
日 = ? 23
日付2を入力してください。
途中で中断したい場合は、qを入力してください。
年 = ?(西暦で) 2021
月 = ? 4
日 = ? 14
日付1と日付2の順序が逆です。                                                    ←古い日付から順番に入力するように促される。 
日付1がより古い日付、日付2がより新しい日付となるように入力してください。
日付1を入力してください。
途中で中断したい場合は、qを入力してください。
年 = ?(西暦で) 2021
月 = ? 4
日 = ? 14
日付2を入力してください。
途中で中断したい場合は、qを入力してください。
年 = ?(西暦で) 2021
月 = ? 7
日 = ? 23
2021年4月14日と2021年7月23日の差は、100日です。                                 ←日数の足し算引き算と日付の差の計算が同じ結果となっている。 
ファイルに出力しますか?(y/n) y
繰り返しますか?(y/n) y
+++++
【日付に関する2通りの計算を行います】
次のいずれかを選択してください。
1.日付の間の差を計算する。
2.日付に日数を足したり引いたりする。
0.終了する。
0、1、2のどれですか? 1
【日付の間の差を計算します】
「日付1」をより古い日付、「日付2」をより新しい日付とします。
各日付を入力してください。
日付1を入力してください。
途中で中断したい場合は、qを入力してください。
年 = ?(西暦で) 1582
月 = ? 10
日 = ? 15
日付2を入力してください。
途中で中断したい場合は、qを入力してください。
年 = ?(西暦で) 9999
月 = ? 12
日 = ? 31
1582年10月15日と9999年12月31日の差は、3,074,323日です。                         ←数値が3桁ずつコンマで区切って出力されている。 
ファイルに出力しますか?(y/n) y
繰り返しますか?(y/n) y
+++++
【日付に関する2通りの計算を行います】
次のいずれかを選択してください。
1.日付の間の差を計算する。
2.日付に日数を足したり引いたりする。
0.終了する。
0、1、2のどれですか? 0
プログラムを終了します。
1582年10月15日引く0日は、1582年10月15日です。
9999年12月31日足す0日は、9999年12月31日です。               ←2行目以降が同じファイルに追記されている。 
2021年7月23日引く100日は、2021年4月14日です。
2021年4月14日と2021年7月23日の差は、100日です。
1582年10月15日と9999年12月31日の差は、3,074,323日です。
【datecalcの計算例】
●阪神タイガース・藤浪晋太郎投手、1,450日ぶりに甲子園白星
2017年4月27日~2021年4月16日
●大谷翔平、1,072日ぶり勝利
2018年5月20日~2021年4月26日
●ソフトバンクホークス、巨人に708日ぶり黒星
2019年6月22日~2021年5月30日
●阪神タイガース、2,860日ぶりに敵地で中日・大野雄大に黒星つけた
2013年8月23日~2021年6月22日
●上野由岐子、4,717日ぶりの五輪でのピッチング
2008年8月21日~2021年7月21日
●明仁上皇陛下が歴代最長寿に並ぶ32,031日
明仁上皇:1933年12月23日の前日~2021年9月2日
昭和天皇:1901年4月29日の前日~1989年1月7日
●大阪万博まで1,000日
2022年7月18日~2025年4月13日
●阪神タイガース・才木浩人投手、1,159日ぶり勝利
2019年5月1日~2022年7月3日
●阪神・淡路大震災から10,000日
1995年1月17日~2022年6月4日
●中日ドラゴンズ、2,891日振りに単独首位
2016年5月10日~2024年4月9日
●阪神タイガース・湯浅京己投手、977日ぶりに2イニング目のピッチング
2022年9月21日~2025年5月25日
●LAドジャース・大谷翔平、663日ぶりに「二刀流」復帰
2023年8月24日~2025年6月17日
●LAドジャース・大谷翔平、749日ぶりに勝利
2023年8月9日~2025年8月27日
©2017 KONISHI, Shoichiro.