Procedura: utilizzare fusi orari nella data e ora aritmeticoHow to: Use time zones in date and time arithmetic

In genere, quando si eseguire Data e ora utilizzando aritmetici DateTime o DateTimeOffset valori, il risultato non riflette le regole di regolazione del fuso orario.Ordinarily, when you perform date and time arithmetic using DateTime or DateTimeOffset values, the result does not reflect any time zone adjustment rules. Questo vale anche quando è chiaramente il fuso orario del valore di data e ora (ad esempio, quando il Kind è impostata su 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). In questo argomento viene illustrato come eseguire operazioni aritmetiche su valori di data e ora che appartengono a un particolare fuso orario.This topic shows how to perform arithmetic operations on date and time values that belong to a particular time zone. I risultati delle operazioni aritmetiche rifletteranno le regole di rettifica del fuso orario.The results of the arithmetic operations will reflect the time zone's adjustment rules.

Per applicare regole di rettifica ai calcoli aritmetici di data e oraTo apply adjustment rules to date and time arithmetic

  1. Implementare un metodo per vincolare un valore di data e ora al fuso orario al quale appartiene.Implement some method of closely coupling a date and time value with the time zone to which it belongs. Ad esempio, dichiarare una struttura che include sia il valore di data e ora sia il fuso orario al quale appartiene.For example, declare a structure that includes both the date and time value and its time zone. Nell'esempio seguente viene utilizzato questo approccio per collegare un DateTime valore al proprio fuso orario.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. Convertire un'ora nell'ora Coordinated Universal Time (UTC) con una chiamata di ConvertTimeToUtc metodo o ConvertTime (metodo).Convert a time to Coordinated Universal Time (UTC) by calling either the ConvertTimeToUtc method or the ConvertTime method.

  3. Eseguire l'operazione aritmetica sull'ora UTC.Perform the arithmetic operation on the UTC time.

  4. Convertire l'ora dall'ora UTC al fuso orario dell'ora originale chiamando il TimeZoneInfo.ConvertTime(DateTime, TimeZoneInfo) metodo.Convert the time from UTC to the original time's associated time zone by calling the TimeZoneInfo.ConvertTime(DateTime, TimeZoneInfo) method.

EsempioExample

L'esempio seguente aggiunge due ore e trenta minuti al 9 marzo 2008, alle 1.30The following example adds two hours and thirty minutes to March 9, 2008, at 1:30 A.M. ora solare fuso centrale (CST).Central Standard Time. La transizione del fuso orario all'ora legale si verifica trenta minuti dopo, alle 2.00The time zone's transition to daylight saving time occurs thirty minutes later, at 2:00 A.M. del 9 marzo 2008.on March 9, 2008. Poiché nell'esempio vengono seguiti i quattro passaggi elencati nella sezione precedente, l'orario corretto risultante corrisponderà alle 5.00Because the example follows the four steps listed in the previous section, it correctly reports the resulting time as 5:00 A.M. del 9 marzo 2008.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

Entrambi DateTime e DateTimeOffset associazione di valori viene annullata da un qualsiasi fuso orario in cui potrebbero appartenere.Both DateTime and DateTimeOffset values are disassociated from any time zone to which they might belong. Per eseguire operazioni aritmetiche di data ora con una modalità che applica automaticamente le regole di rettifica del fuso orario, il fuso orario di appartenenza di qualsiasi valore di data e ora deve essere immediatamente identificabile.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. Ciò significa che una data e ora e il fuso orario associato devono essere strettamente collegati.This means that a date and time and its associated time zone must be tightly coupled. Esistono diversi modi per ottenere questo risultato, tra cui i seguenti:There are several ways to do this, which include the following:

  • Presupporre che tutti gli orari usati in un'applicazione appartengano a un determinato fuso orario.Assume that all times used in an application belong to a particular time zone. Pur essendo appropriato in alcuni casi, questo approccio offre una flessibilità limitata e potenzialmente anche una portabilità limitata.Although appropriate in some cases, this approach offers limited flexibility and possibly limited portability.

  • Definire un tipo che vincoli in modo stretto una data e ora con il fuso orario associato, includendo entrambi come campi del tipo.Define a type that tightly couples a date and time with its associated time zone by including both as fields of the type. Questo approccio viene usato nell'esempio di codice, che definisce una struttura per l'archiviazione della data e ora e del fuso orario in due campi membro.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.

Nell'esempio viene illustrato come eseguire operazioni aritmetiche su DateTime valori in modo che le regole di regolazione fuso orario vengono applicate al risultato.The example illustrates how to perform arithmetic operations on DateTime values so that time zone adjustment rules are applied to the result. Tuttavia, DateTimeOffset valori possono essere utilizzati con la stessa facilità.However, DateTimeOffset values can be used just as easily. Nell'esempio seguente viene illustrato come il codice dell'esempio originale potrebbe essere adattato per l'utilizzo DateTimeOffset anziché DateTime valori.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

Si noti che se questa aggiunta viene eseguita semplicemente sul DateTimeOffset valore senza prima convertirlo nell'ora UTC, il risultato rifletterà il momento esatto in tempo ma l'offset non indicare di fuso orario definito per quell'ora.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.

Compilazione del codiceCompiling the code

L'esempio presenta i requisiti seguenti:This example requires:

  • Un riferimento a System.Core.dll essere aggiunto al progetto.That a reference to System.Core.dll be added to the project.

  • Che il System dello spazio dei nomi importati con il using istruzione (richiesto nel codice c#).That the System namespace be imported with the using statement (required in C# code).

Vedere ancheSee also

Date, ore e fusi orari eseguono operazioni aritmetiche con date e oreDates, times, and time zones Performing arithmetic operations with dates and times