0003. 日付の計算(C言語)

戻る

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> /* strlen(), strcmp(), strcpy(), strcat() */
#include <ctype.h>  /* isdigit() */

#define BUF_SIZE 256





/*
 * 自作のbool型の定義
 */
typedef enum {
    false, /* 0 */
    true   /* 1 */
} bool;





/*
 * 構造体dateの定義
 */
struct date {
    int year;
    int month;
    int day;
};





/*
 * ユーザー定義関数の関数原型宣言
 */
void main_menu(void);

void proc1_print_tile(void);
void proc1_input(void);
void proc1_calc(void);
void comma_sep(char *sp, int n);
void proc1_output(void);

void proc2_print_title(void);
void proc2_input(void);
void addsub_date(struct date date1, int days, char addsub, struct date *date2p);
bool is_out_of_range(struct date some_date);
void proc2_output(void);

bool retry(void);

void input_date(struct date *some_datep);
bool is_valid_number(char buf[]);

int get_days_to_the_year(int year);
int get_days_in_the_year(struct date some_date);
int get_days_to_the_date(struct date some_date);
int get_days_of_the_month(int year, int month);
bool is_leap_year(int year);

void output_result_dif(struct date date1, struct date date2, char s_days[]);
void foutput_result_dif(struct date date1, struct date date2,
 char s_days[], char filename[], char oldfilename[]);
void output_result_addsub(struct date date1, char addsub, char s_days[],
 struct date date2);
void foutput_result_addsub(struct date date1, char addsub, char s_days[],
 struct date date2, char filename[], char oldfilename[]);

void gen_filename(char filename[]);





/*
 * グローバル変数
 */
char sel_proc, addsub, s_days[BUF_SIZE];
char filename[BUF_SIZE]    = {1}, /* filenameとoldfilenameの初期値を */
     oldfilename[BUF_SIZE] = {0}; /* 異なるものに設定                */
                                  /* (ファイルへの追記の判断に使用)  */
int days;
struct date date1, date2, *date2p;
FILE *fp;





/*
 * メイン関数
 */
int main(void)
{
    
    /* 乱数系列の設定 */
    srand((unsigned int)time(NULL));
    
    while (1) {
        
        /* メインメニュー部 */
        main_menu();
        
        /* メインメニュー部からの処理の分岐 */
        switch (sel_proc) {
        
        /* 処理1(差の計算) */
        case '1':
            /* 処理1中の表題の表示 */
            proc1_print_tile();
            
            /* 処理1中の入力処理 */
            proc1_input();
            
            /* 処理1中の計算部 */
            proc1_calc();
            
            /* 処理1中の出力処理 */
            proc1_output();
            
            /* 操作を続けるかどうかの選択 */
            if (!retry())
                goto do_exit;
            break;
        
        /* 処理2(日数の足し算引き算) */
        case '2':
            /* 処理2中の表題の表示 */
            proc2_print_title();
            
            while (1) {
                /* 処理2中の入力処理 */
                proc2_input();
                
                /* 処理2中の計算部 */
                addsub_date(date1, days, addsub, &date2);
                
                /* 計算結果が計算対象の範囲外となった場合の処理 */
                if (!is_out_of_range(date2))
                    break;
            }
            
            /* 処理2中の出力処理 */
            proc2_output();
            
            /* 操作を続けるかどうかの選択 */
            if (!retry())
                goto do_exit;
            break;
        
        /* 処理0(終了) */
        case '0':
            return EXIT_SUCCESS;
        
        default:
            break;
        }
    }
    
    do_exit:
        return EXIT_SUCCESS;
}





/*
 * メインメニューの関数
 */
void main_menu(void)
{
    char buf[BUF_SIZE], zz;
    
    printf("【日付に関する2通りの計算を行います】\n\n");
    printf("次のいずれかを選択してください。\n\n");
    while (1) {
        printf("1.日付の間の差を計算する。\n");
        printf("2.日付に日数を足したり引いたりする。\n");
        printf("0.終了する。\n\n");
        printf("0、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");
            printf("0、1、2のいずれかを入力してください。\n\n");
            continue;
        } else
            break;
    }
}



/*
 * 処理1中の表題を表示する関数
 */
void proc1_print_tile(void)
{
    printf("\n【日付の間の差を計算します】\n\n");
    printf("「日付1」が過去、「日付2」が未来とします。\n");
    printf("各日付(西暦年月日)を入力してください。\n\n");
}



/*
 * 処理1中の入力処理をする関数
 * input_date()関数を使用する。
 */
void proc1_input(void)
{
    while (1) {
        printf("日付1を入力してください。\n");
        input_date(&date1);
        
        printf("日付2を入力してください。\n");
        input_date(&date2);
        
        if (10000*date1.year+100*date1.month+date1.day >
         10000*date2.year+100*date2.month+date2.day) {
            printf("日付1と日付2の順序が逆です。\n");
            printf("日付1が過去、日付2が未来となるように");
            printf("入力してください。\n\n");
            continue;
        } else
            break;
    }
}



/*
 * 処理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(s_days, days);
}



/*
 * 数値を3桁ずつコンマで区切られた文字列に変換する関数
 */
void comma_sep(char *sp, int n)
{
    char *p = sp,        /* 作業用のポインタpを宣言し、spに初期化 */
         c,              /* 文字入れ替え時の作業用変数            */
         ss_n[BUF_SIZE]; /* nの10進数表記の文字列の格納用         */
    int digit = 0,       /* 10進桁数のカウント用変数              */
        len;             /* nの10進数表記での桁数の格納用         */
    
    /* nの10進数表記での桁数をlenに取得 */
    sprintf(ss_n, "%d", n);
    len = strlen(ss_n);
    
    /* nが0の場合は文字0をp(=sp)に格納 */
    if (n == 0)
        sprintf(p, "0");
    
    /* nが0より大の場合、1の位からコンマで区切ってp(=sp)に格納 */
    else {
        while (n > 0) {
            sprintf(p++, "%d", n % 10);
            n /= 10;
            digit++;
            if (digit % 3 == 0 && digit != len)
                sprintf(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(date1, date2, s_days);
    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(date1, date2, s_days, filename, oldfilename);
            break;
        } else if (((ch == 'n') || (ch == 'N')) && (zz == '\n'))
            break;
        else {
            printf("無効な入力です。\n");
            printf("yまたはnを入力してください。\n\n");
            continue;
        }
    }
}



/*
 * 操作を続けるかどうかを選択する関数
 * true: 繰り返す、false: 終了する
 */
bool retry(void)
{
    bool ret;
    char buf[BUF_SIZE], ch, zz;
    
    while (1) {
        
        printf("続けますか?(y/n) ");
        
        fgets(buf, sizeof buf, stdin);
        sscanf(buf, "%c%c", &ch, &zz);
        
        if (((ch == 'y') || (ch == 'Y')) && (zz == '\n')) {
            printf("\n+++++\n\n");
            ret = true;
            break;
        } else if (((ch == 'n') || (ch == 'N')) && (zz == '\n')) {
            ret = false;
            break;
        }
        printf("無効な入力です。\n");
        printf("yまたはnを入力してください。\n\n");
    }
    
    return ret;
}



/*
 * 処理2中の表題を表示する関数
 */
void proc2_print_title(void)
{
    printf("\n【日付に日数を足したり引いたりします】\n\n");
}



/*
 * 処理2中の入力処理をする関数
 * input_date()関数とis_valid_number()関数を使用する。
 */
void proc2_input(void)
{
    char buf[BUF_SIZE], zz;
    
    printf("日付(西暦年月日)を入力してください。\n");
    input_date(&date1);
    
    while (1) {
        
        printf("足し算(+)か引き算(-)かを入力してください: ");
        
        fgets(buf, sizeof buf, stdin);
        sscanf(buf, "%c%c", &addsub, &zz);
        
        if (((addsub != '+') && (addsub != '-')) || (zz != '\n')) {
            printf("無効な入力です。\n");
            printf("+または-を入力してください。\n\n");
            continue;
        } else
            break;
    }
    
    while (1) {
        
        printf("日数 = ? ");
        
        fgets(buf, sizeof buf, stdin);
        sscanf(buf, "%d%c", &days, &zz);
        buf[strlen(buf) - 1] = '\0';
        
        if (!is_valid_number(buf)) {
            printf("無効な入力です。\n");
            printf("半角整数値を入力してください。\n\n");
            continue;
        } else if (days < 0) {
            printf("負の日数の入力は受け付けません。\n");
            printf("0以上の整数を入力してください。\n\n");
            continue;
        } else
            break;
    }
}



/*
 * 日付に日数を足したり引いたりする関数
 * get_days_of_the_month()関数とcomma_sep()関数を使用する。
 */
void addsub_date(struct date date1, int days, char addsub, struct date *date2p)
{
    /* 初期化 */
    date2p->year = date1.year;
    date2p->month = date1.month;
    date2p->day = date1.day;
    
    /* 足し算か引き算か */
    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;
    }
    
    /* 日数を3桁ずつコンマで区切った文字列に変換 */
    comma_sep(s_days, days);
}



/*
 * 計算結果が計算対象の範囲外となった場合の処理をする関数
 * true: 入力を繰り返す、false: 次に進む
 */
bool is_out_of_range(struct date some_date)
{
    bool ret;
    int num_date =
     10000*some_date.year+100*some_date.month+some_date.day;
    
    if (num_date < 15821015) {                    /* グレゴリオ暦の範囲外の場合 */
        printf("1582年10月15日より過去の日付は");
        printf("計算できません。\n");
        printf("(グレゴリオ暦の範囲外です。)\n");
        printf("入力をやり直してください。\n\n");
        ret = true;
    } else if (num_date > 99991231) {             /* 9999年12月31日より未来の場合 */
        printf("9999年12月31日より未来の日付は");
        printf("計算できません。\n");
        printf("入力をやり直してください。\n\n");
        ret = true;
    } else                                        /* 計算対象の範囲内の場合 */
        ret = false;
    
    return ret;
}



/*
 * 処理2中の出力処理をする関数
 * output_result_addsub()関数とfoutput_result_addsub()関数を使用する。
 */
void proc2_output(void)
{
    char buf[BUF_SIZE], ch, zz;
    
    output_result_addsub(date1, addsub, s_days, date2);
    
    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(date1, addsub, s_days,
             date2, filename, oldfilename);
            break;
        } else if (((ch == 'n') || (ch == 'N')) && (zz == '\n'))
            break;
        else {
            printf("無効な入力です。\n");
            printf("yまたはnを入力してください。\n\n");
            continue;
        }
    }
}



/*
 * 日付を入力する関数
 * is_valid_number()関数とget_days_of_the_month()関数を使用する。
 */
void input_date(struct date *some_datep)
{
    char buf[BUF_SIZE], zz;
    
    while (1) {
        
        /* 年の入力 */
        while (1) {
            printf("年 = ?(西暦で) ");
            fgets(buf, sizeof buf, stdin);
            sscanf(buf, "%d%c", &some_datep->year, &zz);
            buf[strlen(buf) - 1] = '\0';
            if (!is_valid_number(buf)) {
                printf("無効な入力です。\n");
                printf("半角整数値を入力してください。\n\n");
                continue;
            } else if (some_datep->year < 1582) {
                printf("%d年はグレゴリオ暦の範囲外です。\n", some_datep->year);
                printf("1582年以降の年を入力してください。\n\n");
                continue;
            } else if (some_datep->year > 9999) {
                printf("無効な入力です。\n");
                printf("9999年以前の年を入力してください。\n\n");
                continue;
            } else
                break;
        }
        
        /* 月の入力 */
        while (1) {
            printf("月 = ? ");
            fgets(buf, sizeof buf, stdin);
            sscanf(buf, "%d%c", &some_datep->month, &zz);
            buf[strlen(buf) - 1] = '\0';
            if (!is_valid_number(buf)) {
                printf("無効な入力です。\n");
                printf("半角整数値を入力してください。\n\n");
                continue;
            } else if ((some_datep->month < 1) || (12 < some_datep->month)) {
                printf("無効な入力です。\n");
                printf("1から12の整数値を入力してください。\n\n");
                continue;
            } else
                break;
        }
        
        /* 日の入力 */
        while (1) {
            printf("日 = ? ");
            fgets(buf, sizeof buf, stdin);
            sscanf(buf, "%d%c", &some_datep->day, &zz);
            buf[strlen(buf) - 1] = '\0';
            if (!is_valid_number(buf)) {
                printf("無効な入力です。\n");
                printf("半角整数値を入力してください。\n\n");
                continue;
            }
            if ((some_datep->day < 1)
             || (get_days_of_the_month(some_datep->year, some_datep->month)
             < some_datep->day)) {
                printf("無効な入力です。\n");
                printf("%d年%d月は、1日から%d日までです。\n",
                 some_datep->year, some_datep->month,
                 get_days_of_the_month(some_datep->year, some_datep->month));
                printf("1から%dまでの値を入力してください。\n\n",
                 get_days_of_the_month(some_datep->year, some_datep->month));
                continue;
            } else
                break;
        }
        
        /* 入力結果がグレゴリオ暦の範囲外となった場合の処理 */
        if (10000*some_datep->year+100*some_datep->month+some_datep->day
         < 15821015) {
            printf("%d年%d月%d日はグレゴリオ暦の範囲外です。\n",
             some_datep->year, some_datep->month, some_datep->day);
            printf("1582年10月15日以降の日付を入力してください。\n\n");
            continue;
        } else
            break;
    }
}



/*
 * 文字列が正しい形式の数値かどうかを判定する関数
 * true: 正しい形式、false: 無効な形式
 */
bool is_valid_number(char buf[])
{
    int i = 0;
    
    /* 最初は符号(省略可) */
    if (buf[i] == '+' || buf[i] == '-')
        i++;
    /* 次に数字(省略不可) */
    if (!isdigit(buf[i]))
        return false;
    i++;
    /* 次に数字列(省略可) */
    while (isdigit(buf[i]))
        i++;
    
    return buf[i] == '\0';
}



/*
 * 西暦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;
    
    some_date.day--;
    for (i = 1; i < some_date.month; i++)
        some_date.day += get_days_of_the_month(some_date.year, i);
    
    return some_date.day;
}



/*
 * 西暦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);
}



/*
 * year年month月に含まれる日数を返す関数
 * is_leap_year()関数を使用する。
 */
int get_days_of_the_month(int year,int month)
{
    int days;
    if (is_leap_year(year) && (month == 2))         /* うるう年の2月           */
        days = 29;
    else if ((!is_leap_year(year)) && (month == 2)) /* うるう年でない2月       */
        days = 28;
    else if ((month == 4) || (month == 6) ||        /* 4、6、9、11月           */
     (month == 9) || (month == 11))
        days = 30;
    else if ((month == 1) || (month == 3) ||        /* 1、3、5、7、8、10、12月 */
     (month == 5) || (month == 7) ||
     (month == 8) || (month == 10) ||
     (month == 12))
        days = 31;
    else {                                          /* 上記以外                */
        printf("月の日数の計算ができません。終了します。\n");
        exit(EXIT_FAILURE);
    }
    return days;
}



/*
 * うるう年の判定をする関数
 * true: うるう年である、false: うるう年でない。
 */
bool is_leap_year(int year)
{
    /* 400で割り切れればうるう年                        */
    /* 400で割り切れず、100で割り切れればうるう年でない */
    /* 100で割り切れず、4で割り切れればうるう年         */
    /* 4で割り切れなければうるう年でない                */
    
    return ((year % 400 == 0) || ((year % 100) && (year % 4 == 0)));
}



/*
 * 差の計算の結果を画面に出力する関数
 */
void output_result_dif(struct date date1, struct date date2, char s_days[])
{
    printf("%d年%d月%d日と", date1.year, date1.month, date1.day);
    printf("%d年%d月%d日の差は、", date2.year, date2.month, date2.day);
    printf("%s日です。\n", s_days);
}



/*
 * 差の計算の結果をファイルに出力する関数
 * gen_filename()関数を使用する。
 */
void foutput_result_dif(struct date date1, struct date date2,
 char s_days[], char filename[], char oldfilename[])
{
    /* ifによる分岐は、2行目以降を同一ファイルに追記出力させるため                      */
    if (strcmp(filename, oldfilename) == 0) { /* ファイル名が同じなら(2行目以降なら)    */
        fp = fopen(oldfilename, "a");         /* oldfilenameを開く                      */
        if (fp == NULL) {
            printf("ファイルを開けません。ファイル出力を中断します。\n");
            return;
        }
    } else {                                  /* ファイル名が違うなら(初めての出力なら) */
        gen_filename(filename);               /* 新規にファイル名を生成して             */
        fp = fopen(filename, "a");            /* そのファイル(filename)を開いて         */
        strcpy(oldfilename, filename);        /* oldfilenameを更新する                  */
        if (fp == NULL) {
            printf("ファイルを開けません。ファイル出力を中断します。\n");
            return;
        }
    }
    
    fprintf(fp, "%d年%d月%d日と", date1.year, date1.month, date1.day);
    fprintf(fp, "%d年%d月%d日の差は、", date2.year, date2.month, date2.day);
    fprintf(fp, "%s日です。\n", s_days);
    
    fclose(fp);
}



/*
 * 足し算引き算の結果を画面に出力する関数
 */
void output_result_addsub(struct date date1, char addsub, char s_days[],
 struct date date2)
{
    switch (addsub) {
    case '+':
        printf("%d年%d月%d日足す%s日は、",
         date1.year, date1.month, date1.day, s_days);
        break;
    case '-':
        printf("%d年%d月%d日引く%s日は、",
         date1.year, date1.month, date1.day, s_days);
        break;
    default:
        break;
    }
    printf("%d年%d月%d日です。\n", date2.year, date2.month, date2.day);
}



/*
 * 足し算引き算の結果をファイルに出力する関数
 * gen_filename()関数を使用する。
 */
void foutput_result_addsub(struct date date1, char addsub, char s_days[],
 struct date date2, char filename[], char oldfilename[])
{
    /* ifによる分岐は、2行目以降を同一ファイルに追記出力させるため                       */
    if (strcmp(filename, oldfilename) == 0) { /* ファイル名が同じなら(2行目以降なら)     */
        fp = fopen(oldfilename, "a");         /* oldfilenameを開く                       */
        if (fp == NULL) {
            printf("ファイルを開けません。ファイル出力を中断します。\n");
            return;
        }
    } else {                                   /* ファイル名が違うなら(初めての出力なら) */
        gen_filename(filename);                /* 新規にファイル名を生成して             */
        fp = fopen(filename, "a");             /* そのファイル(filename)を開いて         */
        strcpy(oldfilename, filename);         /* oldfilenameを更新する                  */
        if (fp == NULL) {
            printf("ファイルを開けません。ファイル出力を中断します。\n");
            return;
        }
    }
    
    switch (addsub) {
    case '+':
        fprintf(fp, "%d年%d月%d日足す%s日は、",
         date1.year, date1.month, date1.day, s_days);
        break;
    case '-':
        fprintf(fp, "%d年%d月%d日引く%s日は、",
         date1.year, date1.month, date1.day, s_days);
        break;
    default:
        break;
    }
    fprintf(fp, "%d年%d月%d日です。\n", date2.year, date2.month, date2.day);
    
    fclose(fp);
}



/*
 * 現在日付時刻からファイル名を生成する関数
 */
void gen_filename(char filename[])
{
    struct tm *t;
    time_t tt;
    char snumrand[10];
    
    time(&tt);
    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(snumrand, "%04d", rand() % 10000);
    filename = strcat(filename, snumrand);
    filename = strcat(filename, ".txt");
}


datecalcの実行時画面表示】赤字はキーボードからの入力を表す。

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

【日付に日数を足したり引いたりします】

日付(西暦年月日)を入力してください。
年 = ?(西暦で) 1
1年はグレゴリオ暦の範囲外です。                             ←1,581年以前の年は無効。
1582年以降の年を入力してください。

年 = ?(西暦で) 1582y
無効な入力です。                                            ←数値以外は無効。
半角整数値を入力してください。

年 = ?(西暦で) 15820
無効な入力です。                                            ←10,000年以降の年は無効。
9999年以前の年を入力してください。

年 = ?(西暦で) 1582
月 = ? 1
日 = ? 1
1582年1月1日はグレゴリオ暦の範囲外です。                    ←日付はグレゴリオ暦の範囲内に限る。
1582年10月15日以降の日付を入力してください。

年 = ?(西暦で) 1582
月 = ? 10
日 = ? 15
足し算(+)か引き算(-)かを入力してください: -
日数 = ? 1
1582年10月15日より過去の日付は計算できません。              ←計算結果がグレゴリオ暦から外れる場合のエラー処理。
(グレゴリオ暦の範囲外です。)
入力をやり直してください。

日付(西暦年月日)を入力してください。
年 = ?(西暦で) 1582
月 = ? 10
日 = ? 15
足し算(+)か引き算(-)かを入力してください: -
日数 = ? -1
負の日数の入力は受け付けません。                            ←負の日数が入力された場合のエラー処理。
0以上の整数を入力してください。

日数 = ? 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

【日付に日数を足したり引いたりします】

日付(西暦年月日)を入力してください。
年 = ?(西暦で) 9999
月 = ? 12
日 = ? 31
足し算(+)か引き算(-)かを入力してください: +
日数 = ? 1
9999年12月31日より未来の日付は計算できません。              ←計算結果が9,999年12月31日より未来になる場合のエラー処理。
入力をやり直してください。

日付(西暦年月日)を入力してください。
年 = ?(西暦で) 9999
月 = ? 12
日 = ? 31
足し算(+)か引き算(-)かを入力してください: +
日数 = ? 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

【日付に日数を足したり引いたりします】

日付(西暦年月日)を入力してください。
年 = ?(西暦で) 2000
月 = ? 13
無効な入力です。                                            ←「13月」はありえない。
1から12の整数値を入力してください。

月 = ? 2
日 = ? 30
無効な入力です。                                            ←「2,000年2月30日」はありえない。
2000年2月は、1日から29日までです。                            暦から自動計算により正しい日付入力を促される。
1から29までの値を入力してください。

日 = ? 29
足し算(+)か引き算(-)かを入力してください: +
日数 = ? 1a
無効な入力です。                                            ←数値以外の入力は無効。
半角整数値を入力してください。

日数 = ? 1
2000年2月29日足す1日は、2000年3月1日です。
ファイルに出力しますか?(y/n) y
続けますか?(y/n) y

+++++

【日付に関する2通りの計算を行います】

次のいずれかを選択してください。

1.日付の間の差を計算する。
2.日付に日数を足したり引いたりする。
0.終了する。

0、1、2のどれですか? 2

【日付に日数を足したり引いたりします】

日付(西暦年月日)を入力してください。
年 = ?(西暦で) 2021
月 = ? 7
日 = ? 23
足し算(+)か引き算(-)かを入力してください: -
日数 = ? 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を入力してください。
年 = ?(西暦で) 2021
月 = ? 4
日 = ? 16
日付2を入力してください。
年 = ?(西暦で) 2017
月 = ? 4
日 = ? 27
日付1と日付2の順序が逆です。                                ←過去の日付から順番に入力するように促される。
日付1が過去、日付2が未来となるように入力してください。

日付1を入力してください。
年 = ?(西暦で) 2017
月 = ? 4
日 = ? 27
日付2を入力してください。
年 = ?(西暦で) 2021
月 = ? 4
日 = ? 16
2017年4月27日と2021年4月16日の差は、1,450日です。           ←阪神タイガース・藤浪晋太郎投手、1,450日ぶりの甲子園勝ち星。
ファイルに出力しますか?(y/n) y                                数値が3桁ずつコンマで区切って出力されている。
続けますか?(y/n) y

+++++

【日付に関する2通りの計算を行います】

次のいずれかを選択してください。

1.日付の間の差を計算する。
2.日付に日数を足したり引いたりする。
0.終了する。

0、1、2のどれですか? 2

【日付に日数を足したり引いたりします】

日付(西暦年月日)を入力してください。
年 = ?(西暦で) 2021
月 = ? 4
日 = ? 16
足し算(+)か引き算(-)かを入力してください: -
日数 = ? 1450
2021年4月16日引く1,450日は、2017年4月27日です。             ←阪神タイガース・藤浪晋太郎投手、1,450日ぶりの甲子園勝ち星。
ファイルに出力しますか?(y/n) y                                数値が3桁ずつコンマで区切って出力されている。
続けますか?(y/n) y

+++++

【日付に関する2通りの計算を行います】

次のいずれかを選択してください。

1.日付の間の差を計算する。
2.日付に日数を足したり引いたりする。
0.終了する。

0、1、2のどれですか? 1

【日付の間の差を計算します】

「日付1」が過去、「日付2」が未来とします。
各日付(西暦年月日)を入力してください。

日付1を入力してください。
年 = ?(西暦で) 1582
月 = ? 10
日 = ? 15
日付2を入力してください。
年 = ?(西暦で) 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


【出力されたファイルdatecalc20241201_011544_9501.txtの内容】 ←現在日付時刻から取得されたファイル名となっている。

1582年10月15日引く0日は、1582年10月15日です。
9999年12月31日足す0日は、9999年12月31日です。     ←2行目以降が、最初に作成された出力ファイルに追記されている。
2000年2月29日足す1日は、2000年3月1日です。
2021年7月23日引く100日は、2021年4月14日です。
2017年4月27日と2021年4月16日の差は、1,450日です。
2021年4月16日引く1,450日は、2017年4月27日です。
1582年10月15日と9999年12月31日の差は、3,074,323日です。


【日数の計算例】

●阪神タイガース・藤浪晋太郎投手、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日


戻る