Выполнение арифметических операций с датами и временемPerforming arithmetic operations with dates and times

Несмотря на то что как DateTime и DateTimeOffset структур предоставляют члены, выполняющие арифметические действия над их значениями, результаты арифметических операций очень различаются.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.

Сравнения и арифметические операции со значениями типа DateTimeComparisons 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 и местным временем для системы в США. США составляет семь часов.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. Тем не менее, поскольку эти значения дают различные представления одного и того же момента времени, в данном случае очевидно, что причина этого различия целиком кроется в смещении местного часового пояса относительно времени в формате 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 методов сравнения и арифметическими операциями (как показывает результат сравнения двух идентичных моментов времени), несмотря на то, что он может повлиять на интерпретацию этих результатов.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:

  • Результат любой арифметической операции над двумя значениями даты и времени, 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. Аналогичным образом результат сравнения двух таких значений даты и времени будет точно отражать соотношение между временами.Similarly, the comparison of two such date and time values accurately reflects the relationship between times.

  • Результат любой операции сравнения или арифметических операций над двумя значениями даты и времени, DateTime.Kind свойства DateTimeKind или над двумя значениями даты и времени с различными DateTime.Kind значения свойств отражает разницу во времени между двумя значениями.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.

  • Любая операция, которая сравнивает или вычисляет разницу между двумя неуказанными значениями времени, может включать неизвестный интервал, который отражает временную разницу между двумя различными часовыми поясами.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.

Сравнения и арифметические операции со значениями DateTimeOffsetComparisons 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 значение более точным и менее контекстно-зависимым при использовании в сравнении и в большинстве арифметических операций, которые определяют интервал между двумя значениями даты и времени.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. Следующий пример, который является DateTimeOffset эквивалентен предыдущий пример, в котором по сравнению с локальной и UTC 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) значения указывает, что разница между двумя значениями времени 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 соответствует смещению часового пояса от времени UTC, когда DateTimeOffset переменной сначала присваивается значение, впоследствии оно рассогласовывается с часовым поясом.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. 9 марта, 2008 г.on March 9, 2008. Это означает, что при прибавлении двух с половиной часов к 1:30 утра 9 марта 2008 г.This means that adding a two and a half hour interval to a Central Standard time of 1:30 A.M. центрального стандартного времени США должно получиться 5:00 утраon March 9, 2008, should produce a date and time of 5:00 A.M. 9 марта, 2008 г.on March 9, 2008. Однако, как показано в следующем примере, результатом сложения является 4:00 утраHowever, as the following example shows, the result of the addition is 4:00 A.M. 9 марта, 2008 г.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:

  • ConvertTime И ConvertTimeBySystemTimeZoneId методы, которые преобразуют значения времени между любыми двумя часовыми поясами.The ConvertTime and ConvertTimeBySystemTimeZoneId methods, which convert times between any two time zones.

  • ConvertTimeFromUtc И ConvertTimeToUtc методы, которые преобразовать время в заданном часовом поясе в формат UTC, или преобразовать во время в заданном часовом поясе UTC.The ConvertTimeFromUtc and ConvertTimeToUtc methods, which convert the time in a particular time zone to UTC, or convert UTC to the time in a particular time zone.

Дополнительные сведения см. в разделе преобразование времени из одного часового пояса.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.

Например, следующий код аналогичен предыдущему коду, в котором 2,5 часа добавлялись к 2:00 утраFor example, the following code is similar to the previous code that added two-and-a-half hours to 2:00 A.M. 9 марта, 2008 г.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