DOBON.NET プログラミング道: .NET Framework, VB.NET, C#, Visual Basic, Visual Studio, インストーラ, ...

日時、時間の計算をする

.NET Frameworkでは、「2000年10月15日 午後2時30分15秒」のような日時を表現する型として、DateTime構造体が使われます。また、「1年間」や「3分間」のような時間を表現する型として、TimeSpan構造体が使われます。これだけ理解していれば、日時や時間の単純な計算は簡単です。

足し算、引き算を行う

DateTimeやTimeSpanの足し算と引き算は、「+」と「-」の算術演算子を使ってできます。

例えば、「2000年8月31日の10日後の日付を取得したい」という場合は、2000年8月31日を表すDateTimeと10日を表すTimeSpanを足します。「2000年8月31日の10日前の日付を取得したい」という場合は、DateTimeからTimeSpanを引きます。結果はDateTimeオブジェクトとして取得できます。

「2000年8月31日は2000年7月21日の何日後かを知りたい」という場合は、2000年8月31日を表すDateTimeから2000年7月21日を表すDateTimeを引きます。結果はTimeSpanオブジェクトとして取得できます。

同じように、時間と時間の足し算はTimeSpanとTimeSpanの足し算で、時間と時間の引き算はTimeSpanとTimeSpanの引き算でできます。

常識的に考えても日時と日時の足し算はできませんので、DateTimeとDateTimeの足し算はできません。

補足:DateTimeのKindプロパティの値は、計算結果に影響を与えません。

DateTimeオブジェクトやTimeSpanオブジェクトを作成する方法が分からない方は、「指定した日時のDateTimeオブジェクトを作成する」や「TimeSpanオブジェクトを作成する、情報を取得する」をご覧ください。

以下に足し算の例を示します。

VB.NET
コードを隠すコードを選択
'「2000/8/31 20:30:00」の「1日と2時間45分15秒」後を計算する
'「2000/8/31 20:30:00」を表すDateTimeオブジェクトを作成する
Dim dt1 As New DateTime(2000, 8, 31, 20, 30, 0)
'「1日と2時間45分15秒」を表すTimeSpanオブジェクトを作成する
Dim ts1 As New TimeSpan(1, 2, 45, 15)
'足し算を行う
Dim dt2 As DateTime = dt1 + ts1
'次のように加算代入演算子を使うこともできる
dt1 += ts1
'結果を表示する
Console.WriteLine(dt2)
'2000/09/01 23:15:15

'「1日と20時間40分」に「10時間30分40秒」を足す
'「1日と20時間40分」を表すTimeSpanオブジェクトを作成する
Dim ts2 As New TimeSpan(1, 20, 40, 0)
'「10時間30分40秒」を表すTimeSpanオブジェクトを作成する
Dim ts3 As New TimeSpan(10, 30, 40)
'足し算を行う
Dim ts4 As TimeSpan = ts2 + ts3
'次のように加算代入演算子を使うこともできる
ts2 += ts3
'結果を表示する
Console.WriteLine(ts4)
'2.07:10:40
C#
コードを隠すコードを選択
//「2000/8/31 20:30:00」の「1日と2時間45分15秒」後を計算する
//「2000/8/31 20:30:00」を表すDateTimeオブジェクトを作成する
DateTime dt1 = new DateTime(2000, 8, 31, 20, 30, 0);
//「1日と2時間45分15秒」を表すTimeSpanオブジェクトを作成する
TimeSpan ts1 = new TimeSpan(1, 2, 45, 15);
//足し算を行う
DateTime dt2 = dt1 + ts1;
//次のように加算代入演算子を使うこともできる
dt1 += ts1;
//結果を表示する
Console.WriteLine(dt2);
//2000/09/01 23:15:15

//「1日と20時間40分」に「10時間30分40秒」を足す
//「1日と20時間40分」を表すTimeSpanオブジェクトを作成する
TimeSpan ts2 = new TimeSpan(1, 20, 40, 0);
//「10時間30分40秒」を表すTimeSpanオブジェクトを作成する
TimeSpan ts3 = new TimeSpan(10, 30, 40);
//足し算を行う
TimeSpan ts4 = ts2 + ts3;
//次のように加算代入演算子を使うこともできる
ts2 += ts3;
//結果を表示する
Console.WriteLine(ts4);
//2.07:10:40

次に引き算の例を示します。

VB.NET
コードを隠すコードを選択
'「2000/9/1 10:30:00」と「2000/8/20 20:40:50」の間の時間を計算する
'「2000/9/1 10:30:00」を表すDateTimeを作成する
Dim dt1 As New DateTime(2000, 9, 1, 10, 30, 0)
'「2000/8/20 20:40:50」を表すDateTimeを作成する
Dim dt2 As New DateTime(2000, 8, 20, 20, 40, 50)
'引き算を行う
Dim ts0 As TimeSpan = dt1 - dt2
'結果を表示する
Console.WriteLine(ts0)
'11.13:49:10

'「20時間30分40秒」から「2日と10時間40分30秒」を引く
'「20時間30分40秒」を表すTimeSpanオブジェクトを作成する
Dim ts1 As New TimeSpan(20, 30, 40)
'「2日と10時間40分30秒」を表すTimeSpanオブジェクトを作成する
Dim ts2 As New TimeSpan(2, 10, 40, 30)
'引き算を行う
Dim ts3 As TimeSpan = ts1 - ts2
'次のように減算代入演算子を使うこともできる
ts1 -= ts2
'結果を表示する
Console.WriteLine(ts3)
'-1.14:09:50

'「2000年3月1日」の3日前を取得する
'「2000年3月1日」を表すDateTimeオブジェクトを作成する
Dim dt3 As New DateTime(2000, 3, 1)
'「3日間」を表すTimeSpanオブジェクトを作成する
Dim ts4 As New TimeSpan(3, 0, 0, 0)
'引き算を行う
Dim dt4 As DateTime = dt3 - ts4
'次のように減算代入演算子を使うこともできる
dt3 -= ts4
'結果を表示する
Console.WriteLine(dt4)
'2000/02/27 0:00:00
C#
コードを隠すコードを選択
//「2000/9/1 10:30:00」と「2000/8/20 20:40:50」の間の時間を計算する
//「2000/9/1 10:30:00」を表すDateTimeを作成する
DateTime dt1 = new DateTime(2000, 9, 1, 10, 30, 0);
//「2000/8/20 20:40:50」を表すDateTimeを作成する
DateTime dt2 = new DateTime(2000, 8, 20, 20, 40, 50);
//引き算を行う
TimeSpan ts0 = dt1 - dt2;
//結果を表示する
Console.WriteLine(ts0);
//11.13:49:10

//「20時間30分40秒」から「2日と10時間40分30秒」を引く
//「20時間30分40秒」を表すTimeSpanオブジェクトを作成する
TimeSpan ts1 = new TimeSpan(20, 30, 40);
//「2日と10時間40分30秒」を表すTimeSpanオブジェクトを作成する
TimeSpan ts2 = new TimeSpan(2, 10, 40, 30);
//引き算を行う
TimeSpan ts3 = ts1 - ts2;
//次のように減算代入演算子を使うこともできる
ts1 -= ts2;
//結果を表示する
Console.WriteLine(ts3);
//-1.14:09:50

//「2000年3月1日」の3日前を取得する
//「2000年3月1日」を表すDateTimeオブジェクトを作成する
DateTime dt3 = new DateTime(2000, 3, 1);
//「3日間」を表すTimeSpanオブジェクトを作成する
TimeSpan ts4 = new TimeSpan(3, 0, 0, 0);
//引き算を行う
DateTime dt4 = dt3 - ts4;
//次のように減算代入演算子を使うこともできる
dt3 -= ts4;
//結果を表示する
Console.WriteLine(dt4);
//2000/02/27 0:00:00

メソッドを利用して、足し算、引き算を行う

上記のように算術演算子で足し算や引き算を行う以外に、メソッドを使っても同じことができます。

DateTimeにTimeSpanを足すには、DateTime.Addメソッドを使います。DateTimeからDateTimeやTimeSpanを引くには、DateTime.Subtractメソッドを使います。

同様に、TimeSpanにTimeSpanを足すには、TimeSpan.Addメソッドを使います。TimeSpanからTimeSpanを引くには、TimeSpan.Subtractメソッドを使います。

VB.NET
コードを隠すコードを選択
Dim dt1 As New DateTime(2000, 8, 31, 20, 30, 0)
Dim ts1 As New TimeSpan(1, 2, 45, 15)

'DateTimeとTimeSpanの足し算を行う
Dim dt2 As DateTime = dt1.Add(ts1)

'DateTimeとDateTimeの引き算を行う
Dim ts2 As TimeSpan = dt2.Subtract(dt1)
C#
コードを隠すコードを選択
DateTime dt1 = new DateTime(2000, 8, 31, 20, 30, 0);
TimeSpan ts1 = new TimeSpan(1, 2, 45, 15);

//DateTimeとTimeSpanの足し算を行う
DateTime dt2 = dt1.Add(ts1);

//DateTimeとDateTimeの引き算を行う
TimeSpan ts2 = dt2.Subtract(dt1);

例えばDateTimeに3年足したいとか、10時間引きたいというように、年数、月数、日数、時間数、分数、秒数を数値で指定して足したり引いたりする時は、もっと簡単なメソッドが用意されています。そのようなメソッドには、名前の頭に「Add」が付いています。

以下に、名前に「Add」の付いたDateTimeのメソッドを列挙します。

メソッド名 説明
AddYears 年数を加算する。
AddMonths 月数を追加する。「8月31日」に1ヶ月追加すると「9月30日」になり、「9月30日」に1ヶ月追加すると「10月30日」になる。
AddDays 日数を追加する。小数を指定できる。
AddHours 時間数を追加する。小数を指定できる。
AddMinutes 分数を追加する。小数を指定できる。
AddSeconds 秒数を追加する。小数を指定できる。
AddMilliseconds ミリ秒数を追加する。小数を指定できる。
AddTicks タイマー刻み数(詳しくは後述)を追加する。

上の表の説明欄に「小数を指定できる」とあるものは、パラメータの型がDoubleで、小数を指定することができます。例えば日数に「0.5」を指定すると、「12時間」が指定されたことになります。

以下にこれらのメソッドを使用した例を示します。

VB.NET
コードを隠すコードを選択
'「2000/3/31 15:30:00」を表すDateTimeオブジェクトを作成する
Dim dt1 As New DateTime(2000, 3, 31, 15, 30, 0)

'10年追加する
Dim dt2 As DateTime = dt1.AddYears(10)
'2010/03/31 15:30:00

'1ヶ月追加する
Dim dt3 As DateTime = dt1.AddMonths(1)
'2000/04/30 15:30:00

'1.5日(1日と12時間)引く
Dim dt4 As DateTime = dt1.AddDays(-1.5)
'2000/03/30 3:30:00
C#
コードを隠すコードを選択
//「2000/3/31 15:30:00」を表すDateTimeオブジェクトを作成する
DateTime dt1 = new DateTime(2000, 3, 31, 15, 30, 0);

//10年追加する
DateTime dt2 = dt1.AddYears(10);
//2010/03/31 15:30:00

//1ヶ月追加する
DateTime dt3 = dt1.AddMonths(1);
//2000/04/30 15:30:00

//1.5日(1日と12時間)引く
DateTime dt4 = dt1.AddDays(-1.5);
//2000/03/30 3:30:00

タイマ刻み数で計算する

DateTimeやTimeSpanオブジェクトは、「タイマ刻み数」と呼ばれる時間を表すInt64型の数値によって日時や時間の情報を保持しています。1タイマ刻み数は100ナノ秒(0.0000001秒)です。

タイマ刻み数はTicksプロパティで取得できます。DateTimeのタイマ刻み数は、西暦1年1月1日0時0分0秒からの経過時間となります。

ほとんどの場合、タイマ刻み数を直接使って計算する必要はありません。ただし、タイマ刻み数の精度が必要なケースや、タイマ刻み数を使って計算した方が効率的なケースもあります。

タイマ刻み数について詳しくは「タイマ刻み数を指定してDateTimeを作成する」で説明していますので、ここでは簡単な例だけを示します。下の例では、ある処理にかかる時間をタイマ刻み数単位の細かさで計測しています。なお、これより高精度で計測する方法を、「より高い精度で時間を計測する」で紹介しています。

VB.NET
コードを隠すコードを選択
'開始時刻を取得する
Dim startDt As DateTime = DateTime.Now

'どのくらい時間がかかるか調べたい処理がここにあるものとする
System.Threading.Thread.Sleep(1000)

'終了時刻を取得する
Dim endDt As DateTime = DateTime.Now

'かかった時間を表示する
Console.WriteLine("{0}タイマ刻み数かかりました", endDt.Ticks - startDt.Ticks)

'次のようにしても同じ
Console.WriteLine("{0}タイマ刻み数かかりました", (endDt - startDt).Ticks)
C#
コードを隠すコードを選択
//開始時刻を取得する
DateTime startDt = DateTime.Now;

//どのくらい時間がかかるか調べたい処理がここにあるものとする
System.Threading.Thread.Sleep(1000);

//終了時刻を取得する
DateTime endDt = DateTime.Now;

//かかった時間を表示する
Console.WriteLine("{0}タイマ刻み数かかりました", endDt.Ticks - startDt.Ticks);

//次のようにしても同じ
Console.WriteLine("{0}タイマ刻み数かかりました", (endDt - startDt).Ticks);

DateTimeOffsetの計算

.NET Framework 2.0 SP1から日時を表す型として、DateTimeOffset構造体が追加されました。DateTimeOffsetの計算はDateTimeとほぼ同じですが、違いもあります。詳しくは、「DateTimeの代わりにDateTimeOffsetを使用する」で説明します。

  • 履歴:
  • 2013/7/28 誤字修正。

注意:この記事では、基本的な事柄の説明が省略されているかもしれません。初心者の方は、特に以下の点にご注意ください。

  • .NET Tipsをご利用いただく際は、注意事項をお守りください。