次のページへ4.うるう年のバグを防ぐポイント前回、うるう年を防ぐポイント、うるう年バグの兆候を示しました。下記に、詳細を記します。うるう年のバグを防ぐためのポイントを下記に示します。仕様でうるう年を考慮しているかコードにうるう年の処理を記述しているかうるう年の2月29日周辺のテストができているかうるう年の12月31日のテストができているか今回は、例題として、以下のプログラムを用いて考えてみましょう(リスト1)。曜日取得プログラムこのリスト1は、曜日取得関数です。ツェラー公式は、年、月、日から曜日を求める公式です。この公式では、1月と2月は、前年の13月、14月と考えて計算します。main関数から呼び出しをかける場合は、以下のように記述します。week_of_the_day(2000,1,19);この例題を用いて、以下に詳細を示します。仕様書、設計書にうるう年の場合の異常処理を書いていない可能性があり得ます(仕様担当者には、プログラマーがうるう年のことを考えるのが当たり前との思いもあるようです)。その場合、リスト1のようなうるう年の判定処理が抜け落ち、うるう年の日にちの加算処理ができない場合があります。コードにうるう年の処理を記述しているかうるう年のバグを防ぐには、最低限、うるう年の判定処理が書いてあるか確認しましょう。リスト1では、以下の処理です。{day_table[month-1]++;}}入力した年がうるう年で、2月の場合は、日を+1して日数を調整しています。日付に関連したコードレビューや単体テストを行う際は、うるう年の処理が記載してあることを確認しましょう。うるう年の2月29日周辺のテストができているかうるう年のテストをする工程は、単体テストです※1)。その際、うるう年の2月28日、2月29日のテストができているか確認しましょう。リスト1で単体テストをするには、例えば、以下のように行います。29);これにより、うるう年の1日が機能しているか確認できますね。※1)単体テストの後の工程で、うるう年のテストをしても構いませんが、時間がかかりすぎます。単体テストを過ぎると、うるう年のバグを見つけるのは困難でしょう。うるう年の12月31日のテストができているかうるう年のテストでは、2月29日以外にも12月31日を確認しましょう。今回の例では、下記のようにテストします。31);今回のプログラムでは、12月31にしても影響はありませんが、日数を配列で確保している場合は、予期せぬ1日でバッファーオーバーランとなる可能性があります。2月29日だけではなく、12月31日にも着目しましょう。完璧な人間が存在しないのと同じように、完璧なプログラムも存在しません。ソフトウェアには、一定程度のバグがあると認識したうえで、何をするべきかを考えることが大事です。2月29日、12月31日にバグが発生する2月29日、12月31日にバグが発生しているか確認しましょう。筆者もそうなのですが、バグの現象ばかりに目が行ってしまい、日付が関係していると推察できない可能性があります※2)。発生事象も大事ですが、日時にも着目しましょう。※2)必ずしも、この日になるとは限りませんが、この日が多いようです。前回の記事でも紹介しました公衆電話のバグでは1月31日に発生しています。それまでは普通に動作しているプログラムが突然動かなくなるうるう年バグは、時限爆弾と同じです。数年間、「何事もなく動いていた」場合は、うるう年のバグを疑いましょう。ただのハードウェアの故障も考えられますので、数あるバグの1つとしてください。一定時間が経過すると正しく動作するうるう年のバグの特徴的なところは、存在しない日付を過ぎると、プログラムが元通りになることです。プログラムが2月29日を存在しない日と判定したとします。24時間後、プログラムが3月1日となった場合、通常の動作に戻ります。バグが自然治癒するのです(したように見える)。一定時間で自然治癒し、発生日時が2月29日か12月31日だと、うるう年バグの可能性が高まります。SNSfacebooktwitterITmediaはアイティメディア株式会社の登録商標です。