日付と時刻を使用した算術演算の実行Performing arithmetic operations with dates and times

DateTimeDateTimeOffset の構造体は両方とも、値に対して算術演算を実行するメンバーを提供しますが、算術演算の結果は大きく異なります。Although both the DateTime and the DateTimeOffset structures provide members that perform arithmetic operations on their values, the results of arithmetic operations are very different. このトピックでは、これらの相違点を確認し、日付と時刻のデータのタイムゾーン認識の程度に関連付けて、日付と時刻のデータを使用して完全なタイムゾーン対応操作を実行する方法について説明します。This topic examines those differences, relates them to degrees of time zone awareness in date and time data, and discusses how to perform fully time zone aware operations using date and time data.

DateTime 値を使用した比較と算術演算Comparisons and arithmetic operations with DateTime values

DateTime.Kind プロパティを使用すると、日付と時刻に DateTimeKind 値を割り当てて、現地時刻、世界協定時刻 (UTC)、または指定されていないタイムゾーンの時刻を表すかどうかを示すことができます。The DateTime.Kind property allows a DateTimeKind value to be assigned to the date and time to indicate whether it represents local time, Coordinated Universal Time (UTC), or the time in an unspecified time zone. ただし、この制限されたタイムゾーン情報は、DateTimeKind 値の日付と時刻の演算を比較または実行するときには無視されます。However, this limited time zone information is ignored when comparing or performing date and time arithmetic on DateTimeKind values. 次の例では、現在の現地時刻と現在の UTC 時刻を比較することで、この問題を示しています。The following example, which compares the current local time with the current UTC time, illustrates this.

using System;

public enum TimeComparison
{
   EarlierThan = -1,
   TheSameAs = 0,
   LaterThan = 1
}

public class DateManipulation
{
   public static void Main()
   {
      DateTime localTime = DateTime.Now;
      DateTime utcTime = DateTime.UtcNow;
      
      Console.WriteLine("Difference between {0} and {1} time: {2}:{3} hours", 
                        localTime.Kind.ToString(), 
                        utcTime.Kind.ToString(), 
                        (localTime - utcTime).Hours, 
                        (localTime - utcTime).Minutes);
      Console.WriteLine("The {0} time is {1} the {2} time.", 
                        localTime.Kind.ToString(), 
                        Enum.GetName(typeof(TimeComparison), localTime.CompareTo(utcTime)), 
                        utcTime.Kind.ToString());  
   }
}
// If run in the U.S. Pacific Standard Time zone, the example displays 
// the following output to the console:
//    Difference between Local and Utc time: -7:0 hours
//    The Local time is EarlierThan the Utc time.                                                    
Public Enum TimeComparison As Integer
   EarlierThan = -1
   TheSameAs = 0
   LaterThan = 1
End Enum

Module DateManipulation
   Public Sub Main()
      Dim localTime As Date = Date.Now
      Dim utcTime As Date = Date.UtcNow
      
      Console.WriteLine("Difference between {0} and {1} time: {2}:{3} hours", _
                        localTime.Kind.ToString(), _
                        utcTime.Kind.ToString(), _
                        (localTime - utcTime).Hours, _
                        (localTime - utcTime).Minutes)
      Console.WriteLine("The {0} time is {1} the {2} time.", _
                        localTime.Kind.ToString(), _ 
                        [Enum].GetName(GetType(TimeComparison), localTime.CompareTo(utcTime)), _
                        utcTime.Kind.ToString())  
      ' If run in the U.S. Pacific Standard Time zone, the example displays 
      ' the following output to the console:
      '    Difference between Local and Utc time: -7:0 hours
      '    The Local time is EarlierThan the Utc time.                                                    
   End Sub
End Module

CompareTo(DateTime) メソッドは、現地時刻が UTC 時刻よりも前 (またはそれ未満) であることを報告します。減算操作は、UTC と米国太平洋標準時ゾーンのシステムの現地時刻との差が7時間であることを示します。The CompareTo(DateTime) method reports that the local time is earlier than (or less than) the UTC time, and the subtraction operation indicates that the difference between UTC and the local time for a system in the U.S. Pacific Standard Time zone is seven hours. しかし、これら 2 つの値は、ある特定の時点を異なる表現で示したものであるため、この場合、時間差の原因は、UTC を基準としたローカル タイム ゾーンのオフセットにあることは明らかです。But because these two values provide different representations of a single point in time, it is clear in this case that this time interval is completely attributable to the local time zone's offset from UTC.

一般に、DateTime.Kind プロパティは、Kind の比較および算術メソッドによって返される結果には影響しません (2 つの同じ時点の比較が示されます)。ただし、これらの結果の解釈に影響する可能性があります。More generally, the DateTime.Kind property does not affect the results returned by Kind comparison and arithmetic methods (as the comparison of two identical points in time indicates), although it can affect the interpretation of those results. (例:For example:

  • 2つの日付と時刻の値に対して実行された、2つの値の間の実際の時間間隔を反映する DateTime.Kind DateTimeKind プロパティを持つ、算術演算の結果。The result of any arithmetic operation performed on two date and time values whose DateTime.Kind properties both equal DateTimeKind reflects the actual time interval between the two values. 同様に、そのような 2 つの日付と時刻の値を比較した結果には、2 つの時間の関係が正確に反映されます。Similarly, the comparison of two such date and time values accurately reflects the relationship between times.

  • 2つの日付と時刻の値に対して実行される算術演算または比較演算の結果では、DateTime.Kind プロパティの両方が DateTimeKind 同じであるか、または異なる DateTime.Kind プロパティ値を持つ2つの日付と時刻の値が、2つの間のクロック時間の差を反映しています。値.The result of any arithmetic or comparison operation performed on two date and time values whose DateTime.Kind properties both equal DateTimeKind or on two date and time values with different DateTime.Kind property values reflects the difference in clock time between the two values.

  • ローカルの日付と時刻の値に対する算術演算または比較操作では、特定の値があいまいであるかや、無効であるかどうかは考慮されず、ローカル タイム ゾーンでの夏時間の開始や終了による調整規則の影響についても考慮されません。Arithmetic or comparison operations on local date and time values do not consider whether a particular value is ambiguous or invalid, nor do they take account of the effect of any adjustment rules that result from the local time zone's transition to or from daylight saving time.

  • UTC と現地時刻の差を比較または計算する操作の結果には、UTC を基準としたローカル タイム ゾーンのオフセットに等しい時間差が含まれます。Any operation that compares or calculates the difference between UTC and a local time includes a time interval equal to the local time zone's offset from UTC in the result.

  • タイム ゾーンが指定されていない時刻と UTC または現地時刻との差を比較または計算する操作では、単純な時刻差が反映されます。Any operation that compares or calculates the difference between an unspecified time and either UTC or the local time reflects simple clock time. タイム ゾーンの違いは考慮されず、結果にはタイム ゾーン調整規則の適用が反映されません。Time zone differences are not considered, and the result does not reflect the application of time zone adjustment rules.

  • タイム ゾーンが指定されていない 2 つの時刻の差を比較または計算する操作の結果には、2 つの異なるタイム ゾーンの時刻の差を反映した未知の時間差が含まれる場合があります。Any operation that compares or calculates the difference between two unspecified times may include an unknown interval that reflects the difference between the time in two different time zones.

タイムゾーンの違いが日付と時刻の計算に影響しないシナリオは多数あります (これらのいくつかの詳細については、「 DateTime、DateTimeOffset、TimeSpan、TimeZoneInfo の選択」を参照してください)。または日付と時刻のデータのコンテキストについても説明します。比較または算術演算の意味を定義します。There are many scenarios in which time zone differences do not affect date and time calculations (for a discussion of some of these, see Choosing between DateTime, DateTimeOffset, TimeSpan, and TimeZoneInfo) or in which the context of the date and time data defines the meaning of comparison or arithmetic operations.

DateTimeOffset 値を使用した比較と算術演算Comparisons and arithmetic operations with DateTimeOffset values

DateTimeOffset 値には、日付と時刻だけでなく、UTC を基準とする日付と時刻を明確に定義するオフセットも含まれます。A DateTimeOffset value includes not only a date and time, but also an offset that unambiguously defines that date and time relative to UTC. これにより、DateTimeOffset の値とは異なる方法で等しいかどうかを定義できます。This makes it possible to define equality somewhat differently than for DateTimeOffset values. DateTime の値は同じ日付と時刻の値を持つ場合は同じですが、両者が同じ時点を参照している場合、DateTimeOffset 値は等しいと見なされます。Whereas DateTime values are equal if they have the same date and time value, DateTimeOffset values are equal if they both refer to the same point in time. これにより、DateTimeOffset の値の精度が向上し、比較で使用する場合は解釈が不要になり、2つの日付と時刻の間の間隔を決定するほとんどの算術演算にもなります。This makes a DateTimeOffset value more accurate and less in need of interpretation when used in comparisons and in most arithmetic operations that determine the interval between two dates and times. 次の例は、ローカルと UTC DateTimeOffset の値を比較した前の例と同等の DateTimeOffset であり、動作の違いを示しています。The following example, which is the DateTimeOffset equivalent to the previous example that compared local and UTC DateTimeOffset values, illustrates this difference in behavior.

using System;

public enum TimeComparison
{
   EarlierThan = -1,
   TheSameAs = 0,
   LaterThan = 1
}

public class DateTimeOffsetManipulation
{
   public static void Main()
   {
      DateTimeOffset localTime = DateTimeOffset.Now;
      DateTimeOffset utcTime = DateTimeOffset.UtcNow;
      
      Console.WriteLine("Difference between local time and UTC: {0}:{1:D2} hours", 
                        (localTime - utcTime).Hours, 
                        (localTime - utcTime).Minutes);
      Console.WriteLine("The local time is {0} UTC.", 
                        Enum.GetName(typeof(TimeComparison), localTime.CompareTo(utcTime)));  
   }
}
// Regardless of the local time zone, the example displays 
// the following output to the console:
//    Difference between local time and UTC: 0:00 hours.
//    The local time is TheSameAs UTC.
Public Enum TimeComparison As Integer
   EarlierThan = -1
   TheSameAs = 0
   LaterThan = 1
End Enum

Module DateTimeOffsetManipulation
   Public Sub Main()
      Dim localTime As DateTimeOffset = DateTimeOffset.Now
      Dim utcTime As DateTimeOffset = DateTimeOffset.UtcNow
      
      Console.WriteLine("Difference between local time and UTC: {0}:{1:D2} hours.", _
                        (localTime - utcTime).Hours, _
                        (localTime - utcTime).Minutes)
      Console.WriteLine("The local time is {0} UTC.", _
                        [Enum].GetName(GetType(TimeComparison), localTime.CompareTo(utcTime)))  
   End Sub
End Module
' Regardless of the local time zone, the example displays 
' the following output to the console:
'    Difference between local time and UTC: 0:00 hours.
'    The local time is TheSameAs UTC.
'          Console.WriteLine(e.GetType().Name)

この例では、CompareTo メソッドは、現在の現地時刻と現在の UTC 時刻が等しいことを示し、CompareTo(DateTimeOffset) 値を減算することで、2つの時刻の差が TimeSpan.Zeroことを示します。In this example, the CompareTo method indicates that the current local time and the current UTC time are equal, and subtraction of CompareTo(DateTimeOffset) values indicates that the difference between the two times is TimeSpan.Zero.

日付と時刻の演算で DateTimeOffset 値を使用する場合の主な制限事項は、DateTimeOffset 値にはタイムゾーンの認識があるものの、完全なタイムゾーンを認識していないことです。The chief limitation of using DateTimeOffset values in date and time arithmetic is that although DateTimeOffset values have some time zone awareness, they are not fully time zone aware. DateTimeOffset 値のオフセットは、DateTimeOffset 変数に最初に値が割り当てられたときの UTC からのタイムゾーンのオフセットを反映しますが、それ以降はタイムゾーンとの関連付けが解除されます。Although the DateTimeOffset value's offset reflects a time zone's offset from UTC when a DateTimeOffset variable is first assigned a value, it becomes disassociated from the time zone thereafter. 特定可能な時刻との直接の関連付けは失われるため、日付と時刻の間隔に対して加算や減算を行っても、タイム ゾーンの調整規則は考慮されません。Because it is no longer directly associated with an identifiable time, the addition and subtraction of date and time intervals does not consider a time zone's adjustment rules.

例として、米国中部標準時ゾーンの夏時間への移行は午前2:00 に行われます。To illustrate, the transition to daylight saving time in the U.S. Central Standard Time zone occurs at 2:00 A.M. 前のコードと似ています。on March 9, 2008. つまり、中部標準時の 2008 年 3 月 9 日の午前 1 時 30 分にThis means that adding a two and a half hour interval to a Central Standard time of 1:30 A.M. 2 時間 30 分の間隔を加算すると、日付と時刻は 2008 年 3 月 9 日のon March 9, 2008, should produce a date and time of 5:00 A.M. 前のコードと似ています。on March 9, 2008. しかし、次の例に示すように、加算の結果は 2008 年 3 月 9 日のHowever, as the following example shows, the result of the addition is 4:00 A.M. 前のコードと似ています。on March 9, 2008. この操作の結果は正しい時点を表していますが、目的のタイム ゾーンの時刻ではありません (つまり、予想されるタイム ゾーンのオフセットが適用されていません)。Note that this result of this operation does represent the correct point in time, although it is not the time in the time zone in which we are interested (that is, it does not have the expected time zone offset).

using System;

public class IntervalArithmetic
{
   public static void Main()
   {
      DateTime generalTime = new DateTime(2008, 3, 9, 1, 30, 0);
      const string tzName = "Central Standard Time";
      TimeSpan twoAndAHalfHours = new TimeSpan(2, 30, 0);

      // Instantiate DateTimeOffset value to have correct CST offset
      try
      {
         DateTimeOffset centralTime1 = new DateTimeOffset(generalTime, 
                    TimeZoneInfo.FindSystemTimeZoneById(tzName).GetUtcOffset(generalTime));
      
         // Add two and a half hours      
         DateTimeOffset centralTime2 = centralTime1.Add(twoAndAHalfHours);
         // Display result
         Console.WriteLine("{0} + {1} hours = {2}", centralTime1, 
                                                    twoAndAHalfHours.ToString(), 
                                                    centralTime2);  
      }
      catch (TimeZoneNotFoundException)
      {
         Console.WriteLine("Unable to retrieve Central Standard Time zone information.");
      }
   }
}
// The example displays the following output to the console:
//    3/9/2008 1:30:00 AM -06:00 + 02:30:00 hours = 3/9/2008 4:00:00 AM -06:00
Module IntervalArithmetic
   Public Sub Main()
      Dim generalTime As Date = #03/09/2008 1:30AM#
      Const tzName As String = "Central Standard Time"
      Dim twoAndAHalfHours As New TimeSpan(2, 30, 0)

      ' Instantiate DateTimeOffset value to have correct CST offset
      Try
         Dim centralTime1 As New DateTimeOffset(generalTime, _
                    TimeZoneInfo.FindSystemTimeZoneById(tzName).GetUtcOffset(generalTime))
      
         ' Add two and a half hours      
         Dim centralTime2 As DateTimeOffset = centralTime1.Add(twoAndAHalfHours)
         ' Display result
         Console.WriteLine("{0} + {1} hours = {2}", centralTime1, _
                                                    twoAndAHalfHours.ToString(), _
                                                    centralTime2)   
      Catch e As TimeZoneNotFoundException
         Console.WriteLine("Unable to retrieve Central Standard Time zone information.")
      End Try
   End Sub
End Module
' The example displays the following output to the console:
'    3/9/2008 1:30:00 AM -06:00 + 02:30:00 hours = 3/9/2008 4:00:00 AM -06:00

タイムゾーンの時刻を使用した算術演算Arithmetic operations with times in time zones

TimeZoneInfo クラスには、あるタイムゾーンから別のタイムゾーンに時刻を変換するときに調整を自動的に適用する多くの変換メソッドが含まれています。The TimeZoneInfo class includes a number of conversion methods that automatically apply adjustments when they convert times from one time zone to another. 次に例を示します。These include the following:

詳細については、「タイムゾーン間での時刻の変換」を参照してください。For details, see Converting times between time zones.

ConvertTimeToUtc(DateTime) クラスには、日付と時刻の演算を実行するときに調整規則を自動的に適用するメソッドは用意されていません。The ConvertTimeToUtc(DateTime) class does not provide any methods that automatically apply adjustment rules when you perform date and time arithmetic. ただし、あるタイム ゾーンの時刻を UTC に変換してから算術演算を実行し、その後 UTC から元のタイム ゾーンの時刻に再変換することで、調整規則を適用したときと同じ結果を得ることができます。However, you can do this by converting the time in a time zone to UTC, performing the arithmetic operation, and then converting from UTC back to the time in the time zone. 詳細については、「方法: 日付と時刻の演算でタイムゾーンを使用する」を参照してください。For details, see How to: Use time zones in date and time arithmetic.

たとえば、次のコードは、2008 年 3 月 9 日の午前 2 時に 2 時間 30 分を加算するFor example, the following code is similar to the previous code that added two-and-a-half hours to 2:00 A.M. 前のコードと似ています。on March 9, 2008. ただし、中部標準時を UTC に変換した後に日付と時刻の算術演算を実行し、その結果を UTC から中部標準時に変換するため、得られた時刻は中部標準時タイム ゾーンの夏時間への移行を反映しています。However, because it converts a Central Standard time to UTC before it performs date and time arithmetic, and then converts the result from UTC back to Central Standard time, the resulting time reflects the Central Standard Time Zone's transition to daylight saving time.

using System;

public class TimeZoneAwareArithmetic
{
   public static void Main()
   {
      const string tzName = "Central Standard Time";
      
      DateTime generalTime = new DateTime(2008, 3, 9, 1, 30, 0);
      TimeZoneInfo cst = TimeZoneInfo.FindSystemTimeZoneById(tzName);
      TimeSpan twoAndAHalfHours = new TimeSpan(2, 30, 0);

      // Instantiate DateTimeOffset value to have correct CST offset
      try
      {
         DateTimeOffset centralTime1 = new DateTimeOffset(generalTime, 
                                       cst.GetUtcOffset(generalTime));
      
         // Add two and a half hours
         DateTimeOffset utcTime = centralTime1.ToUniversalTime();
         utcTime += twoAndAHalfHours;
               
         DateTimeOffset centralTime2 = TimeZoneInfo.ConvertTime(utcTime, cst);
         // Display result
         Console.WriteLine("{0} + {1} hours = {2}", centralTime1, 
                                                    twoAndAHalfHours.ToString(), 
                                                    centralTime2);  
      }
      catch (TimeZoneNotFoundException)
      {
         Console.WriteLine("Unable to retrieve Central Standard Time zone information.");
      }
   }
}
// The example displays the following output to the console:
//    3/9/2008 1:30:00 AM -06:00 + 02:30:00 hours = 3/9/2008 5:00:00 AM -05:00
Module TimeZoneAwareArithmetic
   Public Sub Main()
      Const tzName As String = "Central Standard Time"
      
      Dim generalTime As Date = #03/09/2008 1:30AM#
      Dim cst As TimeZoneInfo = TimeZoneInfo.FindSystemTimeZoneById(tzName) 
      Dim twoAndAHalfHours As New TimeSpan(2, 30, 0)

      ' Instantiate DateTimeOffset value to have correct CST offset
      Try
         Dim centralTime1 As New DateTimeOffset(generalTime, _
                    cst.GetUtcOffset(generalTime))
      
         ' Add two and a half hours 
         Dim utcTime As DateTimeOffset = centralTime1.ToUniversalTime()
         utcTime += twoAndAHalfHours
         
         Dim centralTime2 As DateTimeOffset = TimeZoneInfo.ConvertTime(utcTime, cst)
         ' Display result
         Console.WriteLine("{0} + {1} hours = {2}", centralTime1, _
                                                    twoAndAHalfHours.ToString(), _
                                                    centralTime2)   
      Catch e As TimeZoneNotFoundException
         Console.WriteLine("Unable to retrieve Central Standard Time zone information.")
      End Try
   End Sub
End Module
' The example displays the following output to the console:
'    3/9/2008 1:30:00 AM -06:00 + 02:30:00 hours = 3/9/2008 5:00:00 AM -05:00

関連項目See also