Wykonywanie operacji arytmetycznych na wartościach dat i godzinPerforming arithmetic operations with dates and times

Chociaż zarówno DateTime, jak i struktury DateTimeOffset zapewniają składowe, które wykonują operacje arytmetyczne na ich wartości, wyniki operacji arytmetycznych są bardzo różne.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. Ten temat zawiera informacje o różnicach, odniesieniu ich do stopni rozpoznawania strefy czasowej w danych daty i godziny. omówiono w nim wykonywanie operacji w pełni opartej na strefie czasowej przy użyciu danych daty i godziny.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.

Porównania i operacje arytmetyczne z wartościami DateTimeComparisons and arithmetic operations with DateTime values

Właściwość DateTime.Kind umożliwia przypisanie wartości DateTimeKind do daty i godziny w celu wskazania, czy reprezentuje ona czas lokalny, uniwersalny czas koordynowany (UTC), czy czas w nieokreślonej strefie czasowej.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. Jednak te ograniczone informacje o strefie czasowej są ignorowane podczas porównywania lub wykonywania operacji arytmetycznych daty i czasu na wartościach DateTimeKind.However, this limited time zone information is ignored when comparing or performing date and time arithmetic on DateTimeKind values. Poniższy przykład, który porównuje bieżący czas lokalny z bieżącym czasem UTC, ilustruje to.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

Metoda CompareTo(DateTime) zgłasza, że czas lokalny jest wcześniejszy niż czas UTC, a operacja odejmowania wskazuje, że różnica między czasem UTC a czasem lokalnym w systemie w strefie czasowej USA w Stanach Zjednoczonych jest równa siedem godzin.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. Jednak ponieważ te dwie wartości zapewniają różne reprezentacje pojedynczego punktu w czasie, w tym przypadku jest jasne, że ten przedział czasu jest całkowicie przypisany do przesunięcia lokalnej strefy czasowej z czasu 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.

Bardziej ogólnie rzecz biorąc, właściwość DateTime.Kind nie wpływa na wyniki zwrócone przez Kind metody porównania i arytmetyczne (w miarę jak porównanie dwóch identycznych punktów w czasie wskazuje), chociaż może to wpływać na interpretację tych wyników.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. Na przykład:For example:

  • Wynik każdej operacji arytmetycznej wykonywanej na dwóch wartościach daty i godziny, których właściwości DateTime.Kind obu równych DateTimeKind odzwierciedlają rzeczywisty przedział czasu między tymi dwiema wartościami.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. Podobnie porównanie dwóch takich wartości daty i godziny dokładnie odzwierciedla relacje między nimi.Similarly, the comparison of two such date and time values accurately reflects the relationship between times.

  • Wynik operacji arytmetycznych lub porównania wykonanych na dwóch wartościach daty i godziny, których właściwości DateTime.Kind obydwie równe DateTimeKind lub na dwóch wartościach daty i godziny z różnymi DateTime.Kind wartości właściwości odzwierciedlają różnicę w zegarach między nimi. wartością.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.

  • Operacje arytmetyczne lub porównania na lokalnych wartościach daty i godziny nie są brane pod uwagę, czy konkretna wartość jest niejednoznaczna, czy nieprawidłowa, ani nie podejmuje wpływu na skutki wszelkich reguł korekty wynikających ze przejścia lokalnej strefy czasowej do lub z czasu letniego. Oszczędność czasu.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.

  • Każda operacja, która porównuje lub oblicza różnicę między czasem UTC a czasem lokalnym, obejmuje przedział czasu równy przesunięciu strefy czasowej z UTC w wyniku.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.

  • Każda operacja, która porównuje lub oblicza różnicę między nieokreślonym czasem a czasem UTC lub czasem lokalnym odzwierciedla prosty czas zegara.Any operation that compares or calculates the difference between an unspecified time and either UTC or the local time reflects simple clock time. Różnice między strefami czasowymi nie są brane pod uwagę, a wynik nie odzwierciedla zastosowania reguł dostosowania strefy czasowej.Time zone differences are not considered, and the result does not reflect the application of time zone adjustment rules.

  • Każda operacja, która porównuje lub oblicza różnicę między dwoma nieokreślonymi czasami może obejmować nieznany interwał, który odzwierciedla różnicę między czasem w dwóch różnych strefach czasowych.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.

Istnieje wiele scenariuszy, w których różnice między strefami czasowymi nie wpływają na obliczenia daty i godziny (w przypadku omówienia niektórych z nich, zobacz Wybieranie między elementami DateTime, DateTimeOffset, TimeSpan i TimeZoneInfo) lub w których kontekście danych daty i godziny definiuje znaczenie operacji porównania lub arytmetycznych.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.

Porównania i operacje arytmetyczne z wartościami DateTimeOffsetComparisons and arithmetic operations with DateTimeOffset values

Wartość DateTimeOffset zawiera nie tylko datę i godzinę, ale również przesunięcie, które jednoznacznie definiuje datę i godzinę względem czasu 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. Dzięki temu można zdefiniować równość nieco inaczej niż w przypadku wartości DateTimeOffset.This makes it possible to define equality somewhat differently than for DateTimeOffset values. Wartości DateTime są równe, jeśli mają taką samą wartość daty i godziny, DateTimeOffset wartości są równe, jeśli oba odnoszą się do tego samego punktu w czasie.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. Dzięki temu DateTimeOffset wartość dokładniejszą i mniejszą do interpretacji w przypadku użycia podczas porównywania i w większości operacji arytmetycznych, które określają interwał między dwiema datami i godzinami.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. Poniższy przykład, który jest DateTimeOffset odpowiednikiem poprzedniego przykładu, w porównaniu wartości lokalnych i UTC DateTimeOffset, ilustruje tę różnicę w zachowaniu.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)

W tym przykładzie metoda CompareTo wskazuje, że bieżący czas lokalny i bieżący czas UTC są równe, a odejmowanie wartości CompareTo(DateTimeOffset) wskazuje, że różnica między dwoma wartościami jest 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.

Głównym ograniczeniem korzystania z DateTimeOffset wartości w operacji arytmetycznych daty i czasu jest to, że choć DateTimeOffset wartości mają pewną świadomość strefy czasowej, nie są w pełni świadome strefy czasowej.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. Chociaż przesunięcie wartości DateTimeOffset odzwierciedla przesunięcie strefy czasowej z UTC, gdy do zmiennej DateTimeOffset zostanie przypisana wartość, zostanie ona oddzielona od strefy czasowej.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. Ponieważ nie jest już bezpośrednio skojarzony z możliwym do zidentyfikowania czasem, Dodawanie i odejmowanie interwałów daty i czasu nie uwzględnia reguł korekty strefy czasowej.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.

Aby zilustrować, przejście do czasu letniego w środkowej strefie czasowej w stanie USA występuje o godz. 2:00To illustrate, the transition to daylight saving time in the U.S. Central Standard Time zone occurs at 2:00 A.M. 9 marca 2008.on March 9, 2008. Oznacza to, że dodanie interwału dwóch i pół godziny do środkowego czasu standardowego o 1:30 ranoThis means that adding a two and a half hour interval to a Central Standard time of 1:30 A.M. 9 marca 2008 powinien utworzyć datę i godzinę 5:00 ranoon March 9, 2008, should produce a date and time of 5:00 A.M. 9 marca 2008.on March 9, 2008. Jednak, jak pokazano na poniższym przykładzie, wynikiem dodania jest 4:00 ranoHowever, as the following example shows, the result of the addition is 4:00 A.M. 9 marca 2008.on March 9, 2008. Należy zauważyć, że ten wynik operacji reprezentuje właściwy punkt w czasie, chociaż nie jest to godzina w strefie czasowej, w której jesteśmy zainteresowani (czyli nie ma oczekiwanego przesunięcia strefy czasowej).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

Operacje arytmetyczne z czasami w strefach czasowychArithmetic operations with times in time zones

Klasa TimeZoneInfo obejmuje wiele metod konwersji, które automatycznie stosują korekty podczas konwertowania czasu z jednej strefy czasowej na inną.The TimeZoneInfo class includes a number of conversion methods that automatically apply adjustments when they convert times from one time zone to another. Należą do nich między innymi:These include the following:

Aby uzyskać szczegółowe informacje, zobacz konwertowanie czasów między strefami czasowymi.For details, see Converting times between time zones.

Klasa ConvertTimeToUtc(DateTime) nie udostępnia żadnych metod, które automatycznie stosują reguły korekty podczas wykonywania operacji arytmetycznych daty i czasu.The ConvertTimeToUtc(DateTime) class does not provide any methods that automatically apply adjustment rules when you perform date and time arithmetic. Można to zrobić przez przekonwertowanie czasu w strefie czasowej na UTC, wykonanie operacji arytmetycznej, a następnie konwersję z powrotem na godzinę w strefie czasowej.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. Aby uzyskać szczegółowe informacje, zobacz How to: use Time Zones in Data i Time arytmetyczne.For details, see How to: Use time zones in date and time arithmetic.

Na przykład poniższy kod jest podobny do poprzedniego kodu, który dodał dwie i pół godziny do 2:00 ranoFor example, the following code is similar to the previous code that added two-and-a-half hours to 2:00 A.M. 9 marca 2008.on March 9, 2008. Jednak ze względu na to, że konwertuje środkowy czas standardowy na UTC przed wykonaniem operacji arytmetycznych daty i godziny, a następnie konwertuje wynik z z powrotem do centralnego czasu standardowego, a wynikowy czas odzwierciedla centralne przejście standardowej strefy czasowej do czasu letniego. pierwszym.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

Zobacz takżeSee also