Efectuar operaciones aritméticas con fechas y horasPerforming arithmetic operations with dates and times

Aunque las DateTime estructuras y las DateTimeOffset proporcionan miembros que realizan operaciones aritméticas en sus valores, los resultados de las operaciones aritméticas son muy diferentes.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. En este tema se examinan esas diferencias, se relacionan con grados de reconocimiento de zona horaria en los datos de fecha y hora y se describe cómo realizar operaciones de reconocimiento de zona horaria completa mediante datos de fecha y hora.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.

Comparaciones y operaciones aritméticas con valores DateTimeComparisons and arithmetic operations with DateTime values

La DateTime.Kind propiedad DateTimeKind permite asignar un valor a la fecha y hora para indicar si representa la hora local, la hora universal coordinada (UTC) o la hora en una zona horaria no especificada.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. Sin embargo, esta información de zona horaria limitada se DateTimeKind omite al comparar o realizar la aritmética de fecha y hora en los valores.However, this limited time zone information is ignored when comparing or performing date and time arithmetic on DateTimeKind values. Esto se muestra en el ejemplo siguiente, que compara la hora local actual con la hora UTC actual.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

El CompareTo(DateTime) método informa de que la hora local es anterior (o menor que) la hora UTC y la operación de resta indica que la diferencia entre UTC y la hora local para un sistema en la zona horaria estándar del Pacífico de EE. UU. es de siete horas.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. Pero debido a que estos dos valores proporcionan diferentes representaciones de un solo punto en el tiempo, está claro en este caso que el intervalo de tiempo es completamente atribuible al desplazamiento de la zona horaria local de UTC.But because these two values provide different representations of a single point in time, it is clear in this case that the time interval is completely attributable to the local time zone's offset from UTC.

En términos DateTime.Kind más generales, la propiedad Kind no afecta a los resultados devueltos por métodos de comparación y aritméticos (como indica la comparación de dos puntos idénticos en el tiempo), aunque puede afectar a la interpretación de esos resultados.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. Por ejemplo:For example:

  • El resultado de cualquier operación aritmética DateTime.Kind realizada DateTimeKind en dos valores de fecha y hora cuyas propiedades sean iguales refleja el intervalo de tiempo real entre los dos valores.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. Del mismo modo, la comparación de estos dos valores de fecha y hora refleja con exactitud la relación entre los tiempos.Similarly, the comparison of two such date and time values accurately reflects the relationship between times.

  • El resultado de cualquier operación aritmética o DateTime.Kind de DateTimeKind comparación realizada en dos DateTime.Kind valores de fecha y hora cuyas propiedades sean iguales o en dos valores de fecha y hora con valores de propiedad diferentes refleja la diferencia en el tiempo de reloj entre los dos valores.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.

  • Las operaciones aritméticas o de comparación en valores de fecha y hora local no tienen en cuenta si un valor concreto es ambiguo o no válido, ni tienen en cuenta el efecto de las reglas de ajuste que son consecuencia de la transición de la zona horaria local hacia o desde el horario de verano.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.

  • Las operaciones que comparen o calculen la diferencia entre la hora UTC y una hora local incluyen en el resultado un intervalo de tiempo igual a la diferencia horaria de la zona horaria local respecto de la hora 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.

  • Las operaciones que comparen o calculen la diferencia entre una hora no especificada y la hora UTC o la hora local reflejan la hora de reloj simple.Any operation that compares or calculates the difference between an unspecified time and either UTC or the local time reflects simple clock time. No se consideran las diferencias de zona horaria y el resultado no refleja la aplicación de reglas de ajuste de zona horaria.Time zone differences are not considered, and the result does not reflect the application of time zone adjustment rules.

  • Las operaciones que comparen o calculen la diferencia entre dos horas no especificadas pueden incluir un intervalo desconocido que refleje la diferencia entre la hora de dos zonas horarias diferentes.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.

Hay muchos escenarios en los que las diferencias de zona horaria no afectan a los cálculos de fecha y hora (para una explicación de algunos de estos, vea Elegir entre DateTime, DateTimeOffset, TimeSpan y TimeZoneInfo) o en los que el contexto de los datos de fecha y hora define el significado de las operaciones de comparación o aritméticas.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.

Comparaciones y operaciones aritméticas con valores DateTimeOffsetComparisons and arithmetic operations with DateTimeOffset values

Un DateTimeOffset valor incluye no solo una fecha y hora, sino también un desplazamiento que define inequívocamente esa fecha y hora en relación con 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. Esto permite definir la igualdad de forma DateTimeOffset algo diferente que para los valores.This makes it possible to define equality somewhat differently than for DateTimeOffset values. Mientras DateTime que los valores son iguales si DateTimeOffset tienen el mismo valor de fecha y hora, los valores son iguales si ambos hacen referencia al mismo punto en el tiempo.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. Esto hace DateTimeOffset que un valor sea más preciso y menos necesita interpretación cuando se utiliza en comparaciones y en la mayoría de las operaciones aritméticas que determinan el intervalo entre dos fechas y horas.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. El ejemplo siguiente, DateTimeOffset que es el equivalente al DateTimeOffset ejemplo anterior que comparó los valores locales y UTC, ilustra esta diferencia de comportamiento.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)

En este ejemplo, el CompareTo método indica que la hora local actual y CompareTo(DateTimeOffset) la hora UTC actual son iguales, y la resta de valores indica que la diferencia entre las dos veces es 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.

La principal limitación del uso DateTimeOffset de valores DateTimeOffset en la aritmética de fecha y hora es que aunque los valores tienen cierta conciencia de zona horaria, no son plenamente conscientes de la zona horaria.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. Aunque DateTimeOffset el desplazamiento del valor refleja el desplazamiento de DateTimeOffset una zona horaria de UTC cuando se asigna un valor a una variable por primera vez, se desasocia de la zona horaria a partir de entonces.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. Dado que ya no está directamente asociada con una hora identificable, la suma y resta de intervalos de fecha y hora no tiene en cuenta las reglas de ajuste de una zona horaria.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.

Para ilustrar, la transición al horario de verano en la zona horaria estándar central de EE. UU. se produce a las 2:00 a.m.To illustrate, the transition to daylight saving time in the U.S. Central Standard Time zone occurs at 2:00 A.M. del 9 de marzo de 2008.on March 9, 2008. Esto significa que la suma de un intervalo de dos horas y media a la hora estándar central 1:30 a. m.This means that adding a two and a half hour interval to a Central Standard time of 1:30 A.M. del día 9 de marzo de 2008 debería generar la siguiente fecha y hora: 5:00 a. m.on March 9, 2008, should produce a date and time of 5:00 A.M. del 9 de marzo de 2008.on March 9, 2008. Pero como se muestra en el ejemplo siguiente, el resultado de la suma es 4:00 a. m.However, as the following example shows, the result of the addition is 4:00 A.M. del 9 de marzo de 2008.on March 9, 2008. Tenga en cuenta que el resultado de esta operación representa el punto correcto en el tiempo, aunque no es la hora en la zona horaria en la que estamos interesados (es decir, no tiene el desplazamiento de zona horaria esperado).Note that the 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

Operaciones aritméticas con horarios en zonas horariasArithmetic operations with times in time zones

La TimeZoneInfo clase incluye una serie de métodos de conversión que aplican ajustes automáticamente cuando convierten tiempos de una zona horaria a otra.The TimeZoneInfo class includes a number of conversion methods that automatically apply adjustments when they convert times from one time zone to another. Entre ellas, figuran:These include the following:

Para obtener más información, consulte Conversión de horas entre zonas horarias.For details, see Converting times between time zones.

La TimeZoneInfo clase no proporciona ningún método que aplique automáticamente reglas de ajuste al realizar la aritmética de fecha y hora.The TimeZoneInfo class does not provide any methods that automatically apply adjustment rules when you perform date and time arithmetic. Para hacerlo, puede convertir la hora de una zona horaria a la hora UTC, realizar la operación aritmética y, después, convertir la hora UTC de nuevo a la hora de la zona horaria.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. Para obtener más información, consulte Cómo: Usar zonas horarias en la aritméticade fecha y hora .For details, see How to: Use time zones in date and time arithmetic.

Por ejemplo, el código siguiente se parece al código anterior que sumaba dos horas y media a la fecha y hora 2:00 a. m.For example, the following code is similar to the previous code that added two-and-a-half hours to 2:00 A.M. del 9 de marzo de 2008.on March 9, 2008. Pero, dado que convierte una hora estándar central a la hora UTC antes de realizar la operación aritmética de fecha y hora y, después, convierte el resultado en hora UTC de nuevo a la hora estándar central, la hora resultante refleja la transición de la zona de la hora estándar central al horario de verano.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

Vea tambiénSee also