0023. 日付の計算(C++)

戻る

2026年4月5日掲載

datecalc.cppのソースコード】


// 日付の間の計算を行うプログラム
// datecalc.cpp(date calculation)
//
// 1582年10月15日以降(グレゴリオ暦上)、9999年12月31日以前で動作する。
// 西暦0年1月1日((*)拡張したグレゴリオ暦による)からの日数で計算する。
#include <iostream>
#include <cstdlib>
#include <ctime>
#include <string>
#include <cctype>
#include <algorithm>
#include <sstream>
#include <fstream>
#include <iomanip>
#include <ostream>

using namespace std;





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





// ユーザー定義関数の関数宣言
void initialize();
void menu(char &sel_proc);
void input_enter();
void proc1_print_title();
bool proc1_input(Date &d1, Date &d2);
bool input_date(Date &d);
bool input_year(int &year);
bool is_valid_integer(const string &buf);
bool input_month(int &month);
bool input_day(int year, int month, int &day);
int get_days_of_the_month(int year, int month);
bool is_leap_year(int year);
int calc_date_diff(Date d1, Date d2);
int get_days_to_the_date(Date d);
int get_days_to_the_year(int year);
int get_days_in_the_year(Date d);
void proc1_output(Date d1, Date d2, int days,
    string &filename, bool &is_first_output);
void output_result_diff(ostream &os, Date d1, Date d2, int days);
string comma_sep(int n);
string gen_filename();
bool retry();
void proc2_print_title();
bool proc2_input(Date &d1, int &days, char &op);
Date calc_addsub(Date base, int days, char op);
bool is_out_of_range(Date d);
void proc2_output(Date d1, Date d2, int days, char op,
    string &filename, bool &is_first_output);
void output_result_addsub(ostream &os, Date d1, Date d2, int days, char op);





// メイン関数
int main()
{
    Date date1, date2;
    int days;
    char addsub, sel_proc;
    string filename;
    bool is_first_output = true;
    
    // 初期化
    initialize();
    
    while (true) {
        do_menu:
            // メニュー
            menu(sel_proc);
        
        // メニューからの処理の分岐
        switch (sel_proc) {
        
            // 処理1(差の計算)
            case '1':
                // 処理1中の標題の表示
                proc1_print_title();
                
                // 処理1中の入力
                if (!proc1_input(date1, date2))
                    // qが押されたらメニューへ
                    goto do_menu;
                
                // 処理1中の計算
                days = calc_date_diff(date1, date2);
                
                // 処理1中の出力
                proc1_output(date1, date2, days, filename, is_first_output);
                
                // 操作を繰り返すかどうかの選択
                if (!retry())
                    goto do_end;
                break;
            
            // 処理2(日数の足し算引き算)
            case '2':
                // 処理2中の標題の表示
                proc2_print_title();
                
                while (true) {
                    // 処理2中の入力
                    if (!proc2_input(date1, days, addsub))
                        // qが押されたらメニューへ
                        goto do_menu;
                    
                    // 処理2中の計算
                    date2 = calc_addsub(date1, days, addsub);
                    
                    // 計算結果の日付が計算対象の範囲外かどうかで分岐
                    if (!is_out_of_range(date2))
                        break;
                }
                
                // 処理2中の出力
                proc2_output(date1, date2, days, addsub,
                    filename, is_first_output);
                
                // 操作を繰り返すかどうかの選択
                if (!retry())
                    goto do_end;
                break;
            
            // 処理0(プログラムの終了)
                case '0':
                    goto do_end;
        }
    }
    do_end:
        cout << "\nプログラムを終了します。\n";
}





// 初期化を行う関数
void initialize()
{
    // 乱数系列の設定
    srand(time(NULL));
}



// メニューの関数
// input_enter関数を使用する。
void menu(char &sel_proc)
{
    string buf;
    
    // 標題の表示
    cout << "【日付に関する2通りの計算を行います】\n\n";
    input_enter();
    cout << "次のいずれかを選択してください。\n\n";
    
    // 処理の選択
    while (true) {
        cout << "1.2つの日付の間の差を計算する。\n"
            "2.ある日付に日数を足したり引いたりする。\n"
            "0.終了する。\n\n0、1、2のどれですか? ";
        
        getline(cin, buf);
        sel_proc = buf[0];
        
        if ((sel_proc != '0' && sel_proc != '1' && sel_proc != '2') ||
            buf.size() != 1) {
            cout << "\n無効な入力です。\n\n";
            input_enter();
            cout << "0、1、2のいずれかを入力してください。\n\n";
            continue;
        }
        break;
    }
}



// エンターキーの入力を受け付ける関数
void input_enter()
{
    string buf;
    
    while (true) {
        cout << "エンターキーを押してください・・・";
        getline(cin, buf);
        
        if (!buf.empty())
            continue;
        break;
    }
    cout << '\n';
}



// 処理1中の標題を表示する関数
// input_enter関数を使用する。
void proc1_print_title()
{
    cout << "\n【2つの日付の間の差を計算します】\n\n";
    input_enter();
    cout << "「日付1」をより古い日付、「日付2」をより新しい日付とします。\n\n";
    input_enter();
}



// 処理1中の入力処理をする関数
// true: 次に進む、false: 中断してメニューに戻る。
// input_date関数およびinput_enter関数を使用する。
bool proc1_input(Date &d1, Date &d2)
{
    while (true) {
        cout << "まず、日付1を入力してください。\n"
            "入力を中断したい場合は、qを入力してください。\n\n";
        if (!input_date(d1)) {
            cout << "\n+++++\n\n";
            return false;
        }
        
        cout << "次に、日付2を入力してください。\n\n"
            "入力を中断したい場合は、qを入力してください。\n\n";
        if (!input_date(d2)) {
            cout << "\n+++++\n\n";
            return false;
        }
        
        if (10000*d1.year + 100*d1.month + d1.day >
            10000*d2.year + 100*d2.month + d2.day) {
            cout << "日付1と日付2の順序が逆です。\n\n";
            input_enter();
            cout << "日付1がより古い日付、日付2がより新しい日付となるように"
                "入力してください。\n\n";
            continue;
        }
        break;
    }
    return true;
}



// 日付を入力する関数
// true: 次に進む、false: 中断してメニューに戻る。
// input_year関数、input_month関数、input_day関数および
// input_enter関数を使用する。
bool input_date(Date &d)
{
    while (true) {
        // 年の入力
        if (!input_year(d.year))
            return false;
        
        // 月の入力
        if (!input_month(d.month))
            return false;
        
        // 日の入力
        if (!input_day(d.year, d.month, d.day))
            return false;
        
        // 入力結果がグレゴリオ暦の範囲内かどうかで分岐
        if (10000*d.year + 100*d.month + d.day < 15821015) {
            cout << "\n無効な入力です。\n\n";
            input_enter();
            cout << d.year << "年" << d.month << "月" << d.day << "日は"
                "グレゴリオ暦の範囲外です。\n"
                "本プログラムは、グレゴリオ暦上でしか動作しません。\n"
                "1582年10月15日以降の日付を入力してください。\n"
                "入力を中断したい場合は、qを入力してください。\n\n";
            continue;
        }
        break;
    }
    return true;
}



// 年を入力する関数
// true: 次に進む、false: 中断してメニューに戻る。
// is_valid_integer関数およびinput_enter関数を使用する。
bool input_year(int &year)
{
    string buf;
    
    while (true) {
        cout << "年 = ?(西暦で) ";
        getline(cin, buf);
        
        // 中断判定
        if (buf == "q" || buf == "Q")
            return false;
        
        if (!is_valid_integer(buf)) {
            cout << "\n無効な入力です。\n\n";
            input_enter();
            cout << "半角整数値を入力してください。\n"
                 "入力を中断したい場合は、qを入力してください。\n\n";
            continue;
        }
        
        stringstream ss(buf);
        ss >> year;
        
        if (year < 0) {
            cout << "\n無効な入力です。\n\n";
            input_enter();
            cout << "負の値は受け付けません。\n"
                "入力をやり直してください。\n"
                "入力を中断したい場合は、qを入力してください。\n\n";
            continue;
        }
        if (year < 1582) {
            cout << "\n無効な入力です。\n\n";
            input_enter();
            cout << "西暦" << year << "年はグレゴリオ暦の範囲外です。\n"
                "1582年以降の年を入力してください。\n"
                "入力を中断したい場合は、qを入力してください。\n\n";
            continue;
        }
        if (9999 < year) {
            cout << "\n無効な入力です。\n\n";
            input_enter();
            cout << "本プログラムは9999年までにしか対応していません。\n"
                "9999年以前の年を入力してください。\n"
                "入力を中断したい場合は、qを入力してください。\n\n";
            continue;
        }
        break;
    }
    return true;
}



// 文字列が正しい形式の整数値かどうかを判定する関数
// true: 正しい形式である、false: 無効な形式である。
bool is_valid_integer(const string &buf)
{
    int i = 0;
    
    // 空文字列ならば偽を返す
    if (buf.empty())
        return false;
    
    // 最初は符号(省略可)
    if (buf[i] == '+' || buf[i] == '-')
        i++;
    
    // 次に数字(省略不可)
    if (i >= static_cast<int>(buf.size()) ||
        !isdigit(static_cast<unsigned char>(buf[i])))
        return false;
    i++;
    
    // 次に数字列(省略可)
    while (i < static_cast<int>(buf.size()) &&
        isdigit(static_cast<unsigned char>(buf[i])))
        i++;
    
    // 他に余計な文字がなければ真、あれば偽を返す
    return i == static_cast<int>(buf.size());
}



// 月を入力する関数
// true: 次に進む、false: 中断してメニューに戻る。
// is_valid_integer関数およびinput_enter関数を使用する。
bool input_month(int &month)
{
    string buf;
    
    while (true) {
        cout << "月 = ? ";
        getline(cin, buf);
        
        // 中断判定
        if (buf == "q" || buf == "Q")
            return false;
        
        if (!is_valid_integer(buf)) {
            cout << "\n無効な入力です。\n\n";
            input_enter();
            cout << "半角整数値を入力してください。\n"
                "入力を中断したい場合は、qを入力してください。\n\n";
            continue;
        }
        
        stringstream ss(buf);
        ss >> month;
        
        if (month < 1 || 12 < month) {
            cout << "\n無効な入力です。\n\n";
            input_enter();
            cout << "月は1から12までです。\n"
                "1から12の整数値を入力してください。\n"
                "入力を中断したい場合は、qを入力してください。\n\n";
            continue;
        }
        break;
    }
    return true;
}



// 日を入力する関数
// true: 次に進む、false: 中断してメニューに戻る。
// get_days_of_the_month関数、is_valid_integer関数および
// input_enter関数を使用する。
bool input_day(int year, int month, int &day)
{
    string buf;
    int days = get_days_of_the_month(year, month);
    
    while (true) {
        cout << "日 = ? ";
        getline(cin, buf);
        
        // 中断判定
        if (buf == "q" || buf == "Q")
            return false;
        
        if (!is_valid_integer(buf)) {
            cout << "\n無効な入力です。\n\n";
            input_enter();
            cout << "半角整数値を入力してください。\n"
                "入力を中断したい場合は、qを入力してください。\n\n";
            continue;
        }
        
        stringstream ss(buf);
        ss >> day;
        
        if (day < 1 || days < day) {
            cout << "\n無効な入力です。\n\n";
            input_enter();
            cout << year << "年" << month << "月は、1日から"
                << days << "日までです。\n"
                "1から" << days << "の整数値を入力してください。\n"
                "入力を中断したい場合は、qを入力してください。\n\n";
            continue;
        }
        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;
    }
    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関数を使用する。
int calc_date_diff(Date d1, Date d2)
{
    return
        get_days_to_the_date(d2) -
        get_days_to_the_date(d1);
}



// 西暦0年1月1日(*)からその日までの日数を返す関数
// ((*)拡張したグレゴリオ暦による)
// get_days_to_the_year関数とget_days_in_the_year関数を使用する。
int get_days_to_the_date(Date d)
{
    return
        get_days_to_the_year(d.year) +
        get_days_in_the_year(d);
}



// 西暦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(Date d)
{
    int i, temp_days = d.day - 1;
    
    for (i = d.month - 1; i > 0; i--)
        temp_days += get_days_of_the_month(d.year, i);
    return temp_days;
}



// 処理1中の出力処理をする関数
// output_result_diff関数、gen_filename関数および
// input_enter関数を使用する。
void proc1_output(Date d1, Date d2, int days,
    string &filename, bool &is_first_output)
{
    string buf;
    char ch;
    
    // 画面への出力
    output_result_diff(cout, d1, d2, days);
    
    while (true) {
        cout << "\nファイルに出力しますか?(y/n) ";
        
        // EOF対策
        if (!getline(cin, buf)) {
            cout << "\n無効な入力です。\n"
                "ファイル出力を中断します。\n\n";
            break;
        }
        
        // 入力が1文字の場合
        if (buf.size() == 1) {
            char ch = tolower(buf[0]);
            
            // ファイルに出力するかどうかの分岐、ファイルに出力する場合
            if (ch == 'y') {
                ofstream ofs;
                
                // 新規ファイル出力かどうかの分岐、新規の場合
                if (is_first_output) {
                    filename = gen_filename();
                    ofs.open(filename);
                    if (!ofs) {
                        cout << "\nファイルを開けません。"
                            "ファイル出力を中断します。\n\n";
                        return;
                    }
                    is_first_output = false; // 以降は追記状態になる
                }
                // 2回目以降のファイル出力は追記
                else {
                    ofs.open(filename, ios::app);
                    if (!ofs) {
                        cout << "ファイルを開けません。"
                            "ファイル出力を中断します。\n\n";
                        return;
                    }
                }
                
                // ファイルへの出力
                output_result_diff(ofs, d1, d2, days);
                break;
            }
            
            // ファイルに出力しない場合
            else if (ch == 'n')
                break;
        }
        
        // 入力が「y」でも「n」でもない場合
        cout << "\n無効な入力です。\n\n";
        input_enter();
        cout << "yまたはnを入力してください。\n";
    }
}



// 差の計算の結果を画面に出力する関数
// comma_sep関数を使用する。
void output_result_diff(ostream &os, Date d1, Date d2, int days)
{
    os << d1.year << "年" << d1.month << "月" << d1.day << "日と"
        << d2.year << "年" << d2.month << "月" << d2.day << "日の差は、"
        << comma_sep(days) << "日です。\n";
}



// 数値を3桁ずつコンマで区切った文字列に変換する関数
string comma_sep(int n)
{
    // nが0の場合は"0"を返す
    if (n == 0)
        return "0";
    
    string tmp;
    int digit = 0;
    
    // n>0の場合は1の位からコンマで区切って格納
    while (n > 0) {
        tmp.push_back('0' + (n % 10));
        n /= 10;
        digit++;
        
        if (digit % 3 == 0 && n > 0)
            tmp.push_back(',');
    }
    
    // 文字列を逆順に並べ替え
    reverse(tmp.begin(), tmp.end());
    
    return tmp;
}



// 現在日付時刻からファイル名を生成する関数
string gen_filename()
{
    time_t tt = time(nullptr);
    tm *t = localtime(&tt);
    
    ostringstream oss;
    
    oss << "datecalc"
        << setw(4) << setfill('0') << (1900 + t->tm_year)
        << setw(2) << setfill('0') << (1 + t->tm_mon)
        << setw(2) << setfill('0') << t->tm_mday
        << "_"
        << setw(2) << setfill('0') << t->tm_hour
        << setw(2) << setfill('0') << t->tm_min
        << setw(2) << setfill('0') << t->tm_sec
        << "_";
        
    oss << setw(4) << setfill('0') << (rand() % 10000);
    oss << ".txt";
    
    return oss.str();
}



// 操作を繰り返すかどうかを選択する関数
// true: 繰り返す、false: 終了する。
// input_enter関数を使用する。
bool retry()
{
    string buf;
    
    while (true) {
        cout << "\n繰り返しますか?(y/n) ";
        
        // EOF対策
        if (!getline(cin, buf)) {
            cout << "\n無効な入力です。\n";
            return false;
        }
        
        if (buf.size() == 1) {
            char ch = tolower(buf[0]);
            
            if (ch == 'y') {
                cout << "\n+++++\n\n";
                return true;
            }
            else if (ch == 'n')
                return false;
        }
        
        cout << "\n無効な入力です。\n\n";
        input_enter();
        cout << "yまたはnを入力してください。\n";
    }
}



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



// 処理2中の入力処理をする関数
// true: 次に進む、false: 中断してメニューに戻る。
// input_date関数、input_enter関数およびis_valid_integer関数を使用する。
bool proc2_input(Date &d1, int &days, char &op)
{
    string buf;
    
    // 日付の入力
    cout << "日付を入力してください。\n"
        "入力を中断したい場合は、qを入力してください。\n";
    if (!input_date(d1)) {
        cout << "\n+++++\n\n";
        return false;
    }
    
    // +か-かの入力
    while (true) {
        cout << "足し算(+)か引き算(-)かを入力してください。\n"
            "入力を中断したい場合は、qを入力してください。\n"
            "「+」ですか、「-」ですか? ";
        
        // EOF対策
        if (!getline(cin, buf)) {
            cout << "\n無効な入力です。\n\n";
            return false;
        }
        
        // 中断判定
        if (buf == "q" || buf == "Q") {
            cout << "";
            return false;
        }
        
        if (buf.size() == 1) {
            op = buf[0];
            if (op != '+' && op != '-') {
                cout << "\n無効な入力です。\n\n";
                input_enter();
                cout << "半角の「+」または「-」を入力してください。\n\n";
                continue;
            }
            break;
        }
    }
    
    // 日数の入力
    while (true) {
        cout << "日数を入力してください。\n"
            "入力を中断したい場合は、qを入力してください。\n"
            "日数 = ? ";
        
        // EOF対策
        if (!getline(cin, buf)) {
            cout << "\n無効な入力です。\n\n";
            return false;
        }
        
        // 中断判定
        if (buf == "q" || buf == "Q") {
            cout << "";
            return false;
        }
        
        if (!is_valid_integer(buf)) {
            cout << "\n無効な入力です。\n\n";
            input_enter();
            cout << "半角整数値を入力してください。\n\n";
            continue;
        }
        
        stringstream ss(buf);
        ss >> days;
        
        if (days < 0) {
            cout << "\n無効な入力です。\n\n";
            input_enter();
            cout << "負の日数の入力は受け付けません。\n"
                "0以上の整数を入力してください。\n\n";
            continue;
        }
        break;
    }
    return true;
}



// 日付に日数を足したり引いたりする関数
// get_days_of_the_month関数を使用する。
Date calc_addsub(Date base, int days, char op)
{
    Date result = base;
    
    // 足し算か引き算か
    switch (op) {
        
        // 足し算の場合
        case '+':
            result.day += days;
            while (result.day >
                get_days_of_the_month(result.year, result.month)) {
                
                result.day -=
                    get_days_of_the_month(result.year, result.month);
                
                result.month++;
                
                // 年をまたぐ場合
                if (result.month > 12) {
                    result.year++;
                    result.month = 1;
                }
            }
            break;
        
        // 引き算の場合
        case '-':
            result.day -= days;
            while (result.day < 1) {
                
                result.month--;
                
                // 年をまたぐ場合
                if (result.month < 1) {
                    result.year--;
                    result.month = 12;
                }
                
                result.day +=
                    get_days_of_the_month(result.year, result.month);
            }
            break;
    }
    return result;
}



// 計算結果の日付が計算対象の範囲外かどうかを判定する関数
// true: 範囲外である、false: 範囲内である。
// input_enter関数を使用する。
bool is_out_of_range(Date d)
{
    int dvalue = 10000*d.year + 100*d.month + d.day;
    
    // グレゴリオ暦の範囲外の場合
    if (dvalue < 15821015) {
        cout << "\n無効な入力です。\n\n";
        input_enter();
        cout << "1582年10月15日より古い日付は計算できません。\n"
            "(グレゴリオ暦の範囲外です。)\n入力をやり直してください。\n\n";
    }
    
    // 9999年12月31日より新しい日付の場合
    else if (99991231 < dvalue) {
        cout << "\n無効な入力です。\n\n";
        input_enter();
        cout << "9999年12月31日より新しい日付は計算できません。\n"
            "入力をやり直してください。\n\n";
    }
    
    // 計算対象の範囲内の場合
    else
        return false;
    
    return true;
}



// 処理2の出力処理をする関数
// output_result_addsub_fp関数、gen_filename関数および
// input_enter関数を使用する。
void proc2_output(Date d1, Date d2, int days, char op,
    string &filename, bool &is_first_output)
{
    string buf;
    char ch;
    
    // 画面への出力
    output_result_addsub(cout, d1, d2, days, op);
    
    while (true) {
        cout << "\nファイルに出力しますか?(y/n) ";
        
        // EOF対策
        if (!getline(cin, buf)) {
            cout << "\n無効な入力です。\n"
                "ファイル出力を中断します。\n\n";
            break;
        }
        
        // 入力が1文字の場合
        if (buf.size() == 1) {
            char ch = tolower(buf[0]);
            
            // ファイルに出力するかどうかの分岐、ファイルに出力する場合
            if (ch == 'y') {
                ofstream ofs;
                
                // 新規ファイル出力かどうかの分岐、新規の場合
                if (is_first_output) {
                    filename = gen_filename();
                    ofs.open(filename);
                    if (!ofs) {
                        cout << "\nファイルを開けません。"
                            "ファイル出力を中断します。\n\n";
                        return;
                    }
                    is_first_output = false; // 以降は追記状態になる
                }
                // 2回目以降のファイル出力は追記
                else {
                    ofs.open(filename, ios::app);
                    if (!ofs) {
                        cout << "\nファイルを開けません。"
                            "ファイル出力を中断します。\n\n";
                        return;
                    }
                }
                
                // ファイルへの出力
                output_result_addsub(ofs, d1, d2, days, op);
                break;
            }
            
            // ファイルに出力しない場合
            else if (ch == 'n')
                break;
        }
        
        // 入力が「y」でも「n」でもない場合
        cout << "\n無効な入力です。\n\n";
        input_enter();
        cout << "yまたはnを入力してください。\n";
    }
}



// 足し算引き算の結果を画面またはファイルに出力する関数
// comma_sep関数を使用する。
void output_result_addsub(ostream &os, Date d1, Date d2, int days, char op)
{
    if (op == '+') {
        os << d1.year << "年" << d1.month << "月" << d1.day << "日足す"
            << comma_sep(days) << "日は、";
    }
    else if (op == '-') {
        os << d1.year << "年" << d1.month << "月" << d1.day << "日引く"
            << comma_sep(days) << "日は、";
    }
    
    os << d2.year << "年" << d2.month << "月" << d2.day << "日です。\n";
}


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

C:\Users\skonishi\Documents>datecalc
【日付に関する2通りの計算を行います】

エンターキーを押してください・・・1
エンターキーを押してください・・・[エンター]キー                                ←[エンター]キー以外の入力なら入力繰り返し。

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

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

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

無効な入力です。                                                                ←0、1、2のいずれでもなければ入力繰り返し。

エンターキーを押してください・・・[エンター]キー

0、1、2のいずれかを入力してください。

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

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

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

日付を入力してください。
入力を中断したい場合は、qを入力してください。
年 = ?(西暦で) 1

無効な入力です。                                                                ←1581年以前の年は無効。

エンターキーを押してください・・・[エンター]キー

西暦1年はグレゴリオ暦の範囲外です。
1582年以降の年を入力してください。
入力を中断したい場合は、qを入力してください。

年 = ?(西暦で) -1

無効な入力です。                                                                ←負の値の入力は無効。

エンターキーを押してください・・・[エンター]キー

負の値は受け付けません。
入力をやり直してください。
入力を中断したい場合は、qを入力してください。

年 = ?(西暦で) 1582y

無効な入力です。                                                                ←数値以外は無効。

エンターキーを押してください・・・[エンター]キー

半角整数値を入力してください。
入力を中断したい場合は、qを入力してください。

年 = ?(西暦で) 15820

無効な入力です。                                                                ←10000年以降の年は無効。

エンターキーを押してください・・・[エンター]キー

本プログラムは9999年までにしか対応していません。
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つの日付の間の差を計算する。
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つの日付の間の差を計算する。
2.ある日付に日数を足したり引いたりする。
0.終了する。

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

無効な入力です。                                                                ←間違えて日付を入力しようとしてもエラー処理される。

エンターキーを押してください・・・[エンター]キー

0、1、2のいずれかを入力してください。

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

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

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

日付を入力してください。
入力を中断したい場合は、qを入力してください。
年 = ?(西暦で) 2000
月 = ? 13

無効な入力です。                                                                ←「13月」はありえない。

エンターキーを押してください・・・[エンター]キー

月は1から12までです。
1から12の整数値を入力してください。
入力を中断したい場合は、qを入力してください。

月 = ? 2
日 = ? 30

無効な入力です。                                                                ←「2000年2月30日」はありえない(2000年はうるう年で、2000年2月は29日まで)。

エンターキーを押してください・・・[エンター]キー

2000年2月は、1日から29日までです。
1から29の整数値を入力してください。
入力を中断したい場合は、qを入力してください。

日 = ? q                                                                        ←qを入力すると入力操作が中断される。

+++++

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

エンターキーを押してください・・・[エンター]キー

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

1.2つの日付の間の差を計算する。
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つの日付の間の差を計算する。
2.ある日付に日数を足したり引いたりする。
0.終了する。

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

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

エンターキーを押してください・・・[エンター]キー

「日付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つの日付の間の差を計算する。
2.ある日付に日数を足したり引いたりする。
0.終了する。

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

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

エンターキーを押してください・・・[エンター]キー

「日付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つの日付の間の差を計算する。
2.ある日付に日数を足したり引いたりする。
0.終了する。

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

プログラムを終了します。


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

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日

●嵐、1,768日ぶりに5人そろって生配信
2020年12月31日~2025年11月3日

●嵐、1,948日ぶりに新作ミュージックビデオ公開
2020年11月3日~2026年3月5日

●阪神タイガース・高橋遥人投手、1,638日ぶりに完封勝利
2021年10月2日~2026年3月28日

●楽天イーグルス・前田健太投手、3,828日ぶりに日本球界に復帰
2015年10月7日~2026日3月31日


戻る

©2017 KONISHI, Shoichiro.