C#にはDateTime構造体とTimeSpan構造体があり、両者を利用することで現在時刻を取得したり、ある時刻Aからある時刻Bまでの時間を調べることができます。○時○分○秒の1000秒後は何時何分何秒なのか、○年○月○日の1000日後は何年何月何日なのかとか、○年○月○日と×年×月×日のあいだは何日離れているのかなどがわかります。

では最初に現在時刻を取得するコンソールアプリケーションをつくってみましょう。最後にこれらを組み合わせて実用的なWindowsアプリケーションやWebアプリをつくることにします。

現在時刻を取得して表示させる

現在時刻を取得して表示させるだけならこれでOKです。

DateTime.ToString(“~”)の引数のなかで使えるものは他にもあります。各自で調べてみてください。

時刻と時刻のあいだの時間

時刻と時刻のあいだの時間を表示させます。この場合はTimeSpan構造体を使います。

ここでは現在時刻は2022年1月1日0時0分0秒からどれだけ経過しているのかを表示させてみましょう。

指定された時間が経過したあとの時刻

指定された時間が経過したあと、または以前の時刻は以下のように取得できます。

時間の四則計算

100秒は1分40秒です。では12345秒なら何時間何分何秒でしょうか? 小学校の算数ででてきそうな問題ですが、C#が使えるならコンピュータに計算させましょう。

一人でやろうとすると50日かかる作業を7人で手分けしておこなう場合、何日必要だろうか?
また一人でやろうとすると50日かかる作業を数人で手分けして15日で終わらせたい。この場合、何人必要だろうか?

計算上は以下のようになります。ただこれは机上の空論であって実際にそうなるとはいえません。

以下のようにTimeSpan構造体を使うと、時間の四則演算も簡単にできます。

Windows フォームアプリを作ってみる

それではWindows フォームアプリで同じようなものをつくってみましょう。

指定された2つの時刻のあいだの時間、指定された時刻から指定された時間の前後の時刻を求める機能をひとつのアプリにまとめます。

デザイナで以下のようなものをつくります。

NumericUpDownを操作してボタンをクリックすると年、月、日の値を設定できるようにしています。設定後に[計算][加算][減算]のボタンをクリックすると開始時として設定されている時刻と終了時として設定されている時刻との時間や、開始時として設定されている時刻にある時間を加算もしくは減算した時刻を知ることができます。

フィールド変数とコンストラクタは以下のようになっています。アプリケーションが起動したらSetStartNowメソッドとSetEndNowメソッドを呼び出して、フィールド変数に現在の年月日、時刻を格納します。

SetStartNowメソッドとSetEndNowメソッドは以下のようになっています。

SetLabelTextメソッドはフォーム上のLabelにこれから調べようとしている開始時刻と終了時刻、加算減算しようとしている時刻の情報を表示させるためのものです。

RadioButtonがふたつあります。上のRadioButtonが選択されているときは二つの時刻(開始時刻と終了時刻の時間の差)を時間を計算します。下のRadioButtonが選択されている場合は開始時刻にある時間を加算または減算することで得られる時刻を計算します。

ボタンがクリックされたらNumericUpDownの値から開始時刻を設定するための値を設定します。

現在時刻を計算の起点にしたい場合が多いと思うので、[開始年月日に今日の日付をセット]、[開始年月日に現在時刻をセット]のボタンをクリックしたらフィールド変数に一気に値を設定できるようにしています。

ふたつの時刻の差を計算するときの終了時刻を設定するボタンをクリックしたときの処理を示します。これもやっていることは先に示したものと同じです。値を格納するフィールド変数が違うだけでやっていることは一緒です。

現在時刻に加算または減算する時間を設定するボタンをクリックしたときの処理を示します。これもやっていることはほとんどかわりません。どのボタンをクリックしたのか、その場合、どのフィールド変数に値を格納するのかが違うだけです。

開始時刻と終了時刻の差の時間を計算する処理を示します。DateTime構造体のインスタンスを生成して引き算をすればTimeSpan構造体のインスタンスが返されます。これを文字列に変換して結果をLabelに表示します。このとき不適切な値が設定されていると例外が発生するので、例外処理をおこなっています。

開始時刻に時間を加算または減算したときの処理を示します。DateTime構造体のインスタンスを生成してここにTimeSpan構造体のインスタンスを加算、または減算するとDateTime構造体のインスタンスが返されます。これを文字列に変換して結果をLabelに表示します。この場合も開始時刻に不適切な値が設定されていると例外が発生するので、例外処理をおこなっています。

どのRadioButtonが選択かでボタンをクリックしても処理がおこなわれない場合があります。その場合は最初からボタンをクリックできないようにしたほうがユーザーに対しては新設設計といえます。どのRadioButtonが選択されているかでボタンやNumericUpDownコントロールを操作不能にしています。