方法: 日付と時刻の演算でタイム ゾーンを使用します。How to: Use time zones in date and time arithmetic

通常とを実行して日付時刻の算術演算を使用してDateTimeまたはDateTimeOffset結果の値は、タイム ゾーン調整規則が反映されません。Ordinarily, when you perform date and time arithmetic using DateTime or DateTimeOffset values, the result does not reflect any time zone adjustment rules. 日付と時刻の値のタイム ゾーンが明確に識別する場合でもこれが true (場合など、Kindプロパティに設定されているLocal)。This is true even when the time zone of the date and time value is clearly identifiable (for example, when the Kind property is set to Local). このトピックでは、特定のタイム ゾーンに属している日付と時刻の値に対する算術演算を実行する方法を示します。This topic shows how to perform arithmetic operations on date and time values that belong to a particular time zone. 算術演算の結果には、タイム ゾーンの調整規則が反映されます。The results of the arithmetic operations will reflect the time zone's adjustment rules.

日付と時刻の演算に調整規則を適用するにはTo apply adjustment rules to date and time arithmetic

  1. なんらかの方法を実装して、日付と時刻の値と、その値が属するタイム ゾーンを密接に結び付けます。Implement some method of closely coupling a date and time value with the time zone to which it belongs. たとえば、日付と時刻の値とそのタイム ゾーンの両方を含む構造体を宣言します。For example, declare a structure that includes both the date and time value and its time zone. 次の例にリンクするこの方法を使用して、DateTimeそのタイム ゾーンを持つ値です。The following example uses this approach to link a DateTime value with its time zone.

    // Define a structure for DateTime values for internal use only
    internal struct TimeWithTimeZone
    {
       TimeZoneInfo TimeZone;
       DateTime Time;
    }
    
    ' Define a structure for DateTime values for internal use only
    Friend Structure TimeWithTimeZone
       Dim TimeZone As TimeZoneInfo
       Dim Time As Date
    End Structure
    
  2. 呼び出して、時刻を世界協定時刻 (UTC) を変換、ConvertTimeToUtcメソッドまたはConvertTimeメソッドです。Convert a time to Coordinated Universal Time (UTC) by calling either the ConvertTimeToUtc method or the ConvertTime method.

  3. UTC 時刻で算術演算を実行します。Perform the arithmetic operation on the UTC time.

  4. 時間を UTC から呼び出すことによって、元の時刻のタイム ゾーンに変換、TimeZoneInfo.ConvertTime(DateTime, TimeZoneInfo)メソッドです。Convert the time from UTC to the original time's associated time zone by calling the TimeZoneInfo.ConvertTime(DateTime, TimeZoneInfo) method.

Example

次の例では、中部標準時の 2008 年 3 月 9 日午前 1 時 30 分に、2 時間 30 分をThe following example adds two hours and thirty minutes to March 9, 2008, at 1:30 A.M. 加えます。Central Standard Time. 夏時間へのタイム ゾーンの切り替えは、30 分後の 2008 年 3 月 9 日午前 2 時にThe time zone's transition to daylight saving time occurs thirty minutes later, at 2:00 A.M. 発生します。on March 9, 2008. この例は前に示した 4 つの手順に従うため、結果は正しい時刻である 2008 年 3 月 9 日午前 5 時にBecause the example follows the four steps listed in the previous section, it correctly reports the resulting time as 5:00 A.M. 前のコードと似ています。on March 9, 2008.

using System;

public struct TimeZoneTime
{
   public TimeZoneInfo TimeZone;
   public DateTime Time;
   
   public TimeZoneTime(TimeZoneInfo tz, DateTime time)
   {
      if (tz == null) 
         throw new ArgumentNullException("The time zone cannot be a null reference.");
         
      this.TimeZone = tz;
      this.Time = time;   
   }

   public TimeZoneTime AddTime(TimeSpan interval)
   {
      // Convert time to UTC
      DateTime utcTime = TimeZoneInfo.ConvertTimeToUtc(this.Time, this.TimeZone);
      // Add time interval to time
      utcTime = utcTime.Add(interval);
      // Convert time back to time in time zone
      return new TimeZoneTime(this.TimeZone, TimeZoneInfo.ConvertTime(utcTime, 
                              TimeZoneInfo.Utc, this.TimeZone));
   }
}

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

         cstTime1 = new TimeZoneTime(cst, time1);
         cstTime2 = cstTime1.AddTime(twoAndAHalfHours);
         Console.WriteLine("{0} + {1} hours = {2}", cstTime1.Time, 
                                                    twoAndAHalfHours.ToString(),  
                                                    cstTime2.Time);
      }
      catch
      {
         Console.WriteLine("Unable to find {0}.", tzName);
      }
   }
}
Public Structure TimeZoneTime
   Public TimeZone As TimeZoneInfo
   Public Time As Date
  
   Public Sub New(tz As TimeZoneInfo, time As Date)
      If tz Is Nothing Then _
         Throw New ArgumentNullException("The time zone cannot be a null reference.")
       
      Me.TimeZone = tz
      Me.Time = time
   End Sub
   
   Public Function AddTime(interval As TimeSpan) As TimeZoneTime
      ' Convert time to UTC
      Dim utcTime As DateTime = TimeZoneInfo.ConvertTimeToUtc(Me.Time, _
                                                              Me.TimeZone)      
      ' Add time interval to time
      utcTime = utcTime.Add(interval)
      ' Convert time back to time in time zone
      Return New TimeZoneTime(Me.TimeZone, TimeZoneInfo.ConvertTime(utcTime, _
                              TimeZoneInfo.Utc, Me.TimeZone))
   End Function
End Structure

Module TimeArithmetic
   Public Const tzName As String = "Central Standard Time"
   
   Public Sub Main()
      Try
         Dim cstTime1, cstTime2 As TimeZoneTime
         
         Dim cst As TimeZoneInfo = TimeZoneInfo.FindSystemTimeZoneById(tzName)
         Dim time1 As Date = #03/09/2008 1:30AM#
         Dim twoAndAHalfHours As New TimeSpan(2, 30, 0)
   
         cstTime1 = New TimeZoneTime(cst, time1)
         cstTime2 = cstTime1.AddTime(twoAndAHalfHours)

         Console.WriteLine("{0} + {1} hours = {2}", cstTime1.Time, _
                                                    twoAndAHalfHours.ToString(), _ 
                                                    cstTime2.Time)  
      Catch
         Console.WriteLine("Unable to find {0}.", tzName)
      End Try   
   End Sub   
End Module

両方DateTimeDateTimeOffset値関連付けが解除され、タイム ゾーンが属している可能性があります。Both DateTime and DateTimeOffset values are disassociated from any time zone to which they might belong. タイム ゾーンの調整規則が自動的に適用されるような方法で日付と時刻の演算を実行するには、日付と時刻の値の属するタイム ゾーンがすぐに識別できる状態でなければなりません。To perform date and time arithmetic in a way that automatically applies a time zone's adjustment rules, the time zone to which any date and time value belongs must be immediately identifiable. つまり、日時と関連付けられているタイム ゾーンを密に結合する必要があります。This means that a date and time and its associated time zone must be tightly coupled. これは、次のようないくつかの方法で行うことができます。There are several ways to do this, which include the following:

  • アプリケーションで使用されるすべての時刻が、特定のタイム ゾーンに属するものと仮定します。Assume that all times used in an application belong to a particular time zone. この方法は、適切な場合もありますが、柔軟性が限られ、移植性が制限される可能性もあります。Although appropriate in some cases, this approach offers limited flexibility and possibly limited portability.

  • 日時と関連付けられているタイム ゾーンを型のフィールドとして組み込むことで、両者を密に結合する型を定義します。Define a type that tightly couples a date and time with its associated time zone by including both as fields of the type. コード例ではこの方法を使用して、日時とタイム ゾーンを 2 つのメンバー フィールドに格納する構造体を定義しています。This approach is used in the code example, which defines a structure to store the date and time and the time zone in two member fields.

例での算術演算を実行する方法を示していますDateTime値を結果にタイム ゾーン調整規則が適用されるようにします。The example illustrates how to perform arithmetic operations on DateTime values so that time zone adjustment rules are applied to the result. ただし、DateTimeOffset値を簡単に使用できます。However, DateTimeOffset values can be used just as easily. どの例では元のコード可能性がありますを使用する次の例を示していますDateTimeOffsetの代わりにDateTime値。The following example illustrates how the code in the original example might be adapted to use DateTimeOffset instead of DateTime values.

using System;

public struct TimeZoneTime
{
   public TimeZoneInfo TimeZone;
   public DateTimeOffset Time;
   
   public TimeZoneTime(TimeZoneInfo tz, DateTimeOffset time)
   {
      if (tz == null) 
         throw new ArgumentNullException("The time zone cannot be a null reference.");
         
      this.TimeZone = tz;
      this.Time = time;   
   }

   public TimeZoneTime AddTime(TimeSpan interval)
   {
      // Convert time to UTC
      DateTimeOffset utcTime = TimeZoneInfo.ConvertTime(this.Time, TimeZoneInfo.Utc);      
      // Add time interval to time
      utcTime = utcTime.Add(interval);
      // Convert time back to time in time zone
      return new TimeZoneTime(this.TimeZone, TimeZoneInfo.ConvertTime(utcTime, this.TimeZone));
   }
}

public class TimeArithmetic
{
   public const string tzName = "Central Standard Time";
   
   public static void Main()
   {
      try
      {
         TimeZoneTime cstTime1, cstTime2;
         
         TimeZoneInfo cst = TimeZoneInfo.FindSystemTimeZoneById(tzName);
         DateTime time1 = new DateTime(2008, 3, 9, 1, 30, 0);          
         TimeSpan twoAndAHalfHours = new TimeSpan(2, 30, 0);
         
         cstTime1 = new TimeZoneTime(cst, 
                        new DateTimeOffset(time1, cst.GetUtcOffset(time1)));
         cstTime2 = cstTime1.AddTime(twoAndAHalfHours);
         Console.WriteLine("{0} + {1} hours = {2}", cstTime1.Time, 
                                                    twoAndAHalfHours.ToString(),  
                                                    cstTime2.Time);
      }
      catch
      {
         Console.WriteLine("Unable to find {0}.", tzName);
      }
   }
}
Public Structure TimeZoneTime
   Public TimeZone As TimeZoneInfo
   Public Time As DateTimeOffset
  
   Public Sub New(tz As TimeZoneInfo, time As DateTimeOffset)
      If tz Is Nothing Then _
         Throw New ArgumentNullException("The time zone cannot be a null reference.")
       
      Me.TimeZone = tz
      Me.Time = time
   End Sub
   
   Public Function AddTime(interval As TimeSpan) As TimeZoneTime
      ' Convert time to UTC
      Dim utcTime As DateTimeOffset = TimeZoneInfo.ConvertTime(Me.Time, TimeZoneInfo.Utc)      
      ' Add time interval to time
      utcTime = utcTime.Add(interval)
      ' Convert time back to time in time zone
      Return New TimeZoneTime(Me.TimeZone, TimeZoneInfo.ConvertTime(utcTime, Me.TimeZone))
   End Function
End Structure

Module TimeArithmetic
   Public Const tzName As String = "Central Standard Time"
   
   Public Sub Main()
      Try
         Dim cstTime1, cstTime2 As TimeZoneTime
         
         Dim cst As TimeZoneInfo = TimeZoneInfo.FindSystemTimeZoneById(tzName)
         Dim time1 As Date = #03/09/2008 1:30AM#
         Dim twoAndAHalfHours As New TimeSpan(2, 30, 0)
   
         cstTime1 = New TimeZoneTime(cst, _
                        New DateTimeOffset(time1, cst.GetUtcOffset(time1)))
         cstTime2 = cstTime1.AddTime(twoAndAHalfHours)

         Console.WriteLine("{0} + {1} hours = {2}", cstTime1.Time, _
                                                    twoAndAHalfHours.ToString(), _ 
                                                    cstTime2.Time)  
      Catch
         Console.WriteLine("Unable to find {0}.", tzName)
      End Try   
   End Sub   
End Module

この追加を実行するだけの場合、DateTimeOffset最初 UTC に変換する、結果、適切な時点の反映しますが、そのオフセットは反映されませんを指定されたタイム ゾーンの時点のなしの値します。Note that if this addition is simply performed on the DateTimeOffset value without first converting it to UTC, the result reflects the correct point in time but its offset does not reflect that of the designated time zone for that time.

コードのコンパイルCompiling the code

この例で必要な要素は次のとおりです。This example requires:

  • される System.Core.dll への参照をプロジェクトに追加します。That a reference to System.Core.dll be added to the project.

  • Systemと共に名前空間をインポートする、usingステートメント (c# コードで必要です)。That the System namespace be imported with the using statement (required in C# code).

関連項目See also

日付、時刻、およびタイム ゾーン 日付と時刻の算術演算を実行します。Dates, times, and time zones Performing arithmetic operations with dates and times