Exportar (0) Imprimir
Expandir todo
Este artículo proviene de un motor de traducción automática. Mueva el puntero sobre las frases del artículo para ver el texto original. Más información.
Traducción
Original

Efectuar operaciones aritméticas con fechas y horas

Aunque tanto las estructuras DateTime como DateTimeOffset proporcionan miembros que efectúan operaciones aritméticas con sus valores, los resultados que arrojan estas operaciones son muy diferentes. En este tema se estudian esas diferencias, se relacionan con los grados de conocimiento de la zona horaria en los datos de fecha y hora, y se explica cómo realizar operaciones con conocimiento pleno de la zona horaria utilizando datos de fecha y hora.

A partir de la versión 2.0 de .NET Framework, los valores de DateTime poseen un grado limitado de conocimiento de la zona horaria. La propiedad DateTime.Kind permite asignar un valor de DateTimeKind a la fecha y la hora para indicar si representa la hora local, la hora universal coordinada (UTC) o la hora de una zona horaria no especificada. Sin embargo, esta información de zona horaria limitada se omite al efectuar comparaciones u operaciones aritméticas de fecha y hora con valores de DateTime. En el ejemplo siguiente, donde se compara la hora local actual con la hora UTC actual, se ilustra este punto.


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.                                                    


Los informes del método de CompareTo(DateTime) que la hora local es anterior a (o menor que) la hora UTC, y la operación de resta indica que la diferencia entre la hora utc y la hora local para un sistema de la zona horaria estándar del Pacífico de EE.UU. es siete horas. Sin embargo, debido a que estos dos valores proporcionan representaciones diferentes de un mismo punto de tiempo, en este caso está claro que este intervalo de tiempo es totalmente atribuible a la diferencia entre la zona horaria local con respecto a la hora UTC.

De modo más general, la propiedad DateTime.Kind no afecta a los resultados devueltos por la comparación DateTime ni a los métodos aritméticos (tal como lo indica la comparación de dos puntos de tiempo idénticos), aunque puede afectar a la interpretación de esos resultados. Por ejemplo:

  • El resultado de cualquier operación aritmética efectuada con dos valores de fecha y hora cuyas propiedades DateTime.Kind sean iguales a Utc en ambos casos, refleja el intervalo de tiempo real entre los dos valores. De igual forma, la comparación de dos valores de fecha y hora de este tipo refleja con precisión la relación entre ambas horas.

  • El resultado de cualquier operación aritmética o comparativa realizada con dos valores de fecha y hora cuyas propiedades DateTime.Kind sean Local en ambos casos o con dos valores de fecha y hora que tengan valores de propiedad DateTime.Kind diferentes refleja la diferencia de la hora que marca el reloj entre los dos valores.

  • Las operaciones aritméticas o comparativas con valores de fecha y hora locales no tienen en cuenta si un valor concreto es ambiguo o no válido, ni tampoco el efecto de ninguna regla de ajuste resultante de la transición de la zona horaria local al horario de verano o de invierno.

  • Cualquier operación que compara o calcula la diferencia entre la hora UTC y una hora local incluye en el resultado un intervalo de tiempo igual a la diferencia de la zona horaria local con respecto a la hora UTC.

  • Cualquier operación que compare o calcule la diferencia entre una hora no especificada y la hora UTC o la hora local refleja simplemente la hora del reloj. Las diferencias de zonas horarias no se tienen en cuenta y el resultado no refleja la aplicación de reglas de ajuste de la zona horaria.

  • Cualquier operación que compare o calcule la diferencia entre dos horas no especificadas puede incluir un intervalo desconocido que refleje las diferencias horarias en dos zonas horarias diferentes.

Hay muchos escenarios en los que las diferencias de zona horaria no afectan a los cálculos de fecha y hora (para obtener una explicación de algunos de ellos, consulte Elegir entre DateTime, DateTimeOffset y TimeZoneInfo) o en los que el contexto de los datos de fecha y hora define el significado de las operaciones comparativas o aritméticas.

Un valor de DateTimeOffset incluye no sólo una fecha y hora, sino también una diferencia que define sin ambigüedad esa fecha y hora con respecto a la hora UTC. Esto permite definir la igualdad de un modo diferente que para los valores de DateTime. Mientras que los valores de DateTime son iguales si tienen el mismo valor de fecha y hora, los valores de DateTimeOffset son iguales si ambos hacen referencia al mismo punto temporal. Esto hace que un valor de DateTimeOffset sea más preciso y su interpretación menos necesaria cuando se utiliza en comparaciones y en la mayoría de las operaciones aritméticas que determinan el intervalo entre dos fechas y horas. En el ejemplo siguiente, que es el equivalente de DateTimeOffset al ejemplo anterior en el que se comparaban los valores de DateTime local y UTC, se muestra esta diferencia de comportamiento.


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.


En este ejemplo, el método CompareTo indica que la hora local y la hora UTC actuales son iguales, y la resta de los valores de DateTimeOffset indica que la diferencia entre las dos horas es TimeSpan.Zero.

La limitación principal de utilizar valores de DateTimeOffset en las operaciones aritméticas con valores de fecha y hora reside en que, si bien los valores de DateTimeOffset tienen algún conocimiento de la zona horaria, no tienen conocimiento pleno de ella. Aunque la diferencia del valor de DateTimeOffset refleja la diferencia de una zona horaria con respecto a la hora UTC cuando se asigna un valor por primera vez a una variable DateTimeOffset, en lo sucesivo deja de estar asociada a la zona horaria. Al no seguir estando directamente asociada con una hora identificable, la adición y resta de intervalos de fecha y hora no tiene en cuenta las reglas de ajuste de la zona horaria.

Para mostrar, la transición al horario de verano en la zona horaria estándar de EE.UU. Central aparece a las 2:00 a.m. el 9 de marzo de 2008. Esto significa que agregando dos y un intervalo de media hora a una hora estándar Central de 1:30 a.m. el 9 de marzo de 2008, debe generar una fecha y hora de 5:00 a.m. el 9 de marzo de 2008. Sin embargo, como se muestra en el ejemplo siguiente, el resultado de la suma es 4:00 a.m. el 9 de marzo de 2008. Tenga en cuenta que este último resultado de la operación sí representa el punto de tiempo correcto, aunque no sea la hora correcta en la zona horaria que nos interesa (es decir, no tiene la diferencia esperada de la zona horaria).


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


La clase TimeZoneInfo incluye varios métodos de conversión que aplican ajustes automáticamente cuando convierten las horas de una zona horaria en otra. Entre ellos, se incluyen los siguientes:

Para obtener información detallada, vea Convertir horas entre zonas horarias.

La clase TimeZoneInfo no proporciona ningún método que aplique automáticamente reglas de ajuste cuando se realizan operaciones aritméticas con valores de fecha y hora. Sin embargo, para hacerlo basta con convertir la hora de una zona horaria en la hora UTC, realizar la operación aritmética y, a continuación, volver a convertir la hora UTC en la hora correspondiente de la zona horaria. Para obtener información detallada, vea Cómo: Utilizar zonas horarias en aritmética de fecha y hora.

Por ejemplo, el código siguiente es similar al código anterior en el que se sumaban dos horas y media a las 2:00 a.m. el 9 de marzo de 2008. Sin embargo, como convierte la hora CST en hora UTC antes de realizar la operación aritmética y, a continuación, vuelve a convertir el resultado de la hora UTC en la hora CST, la hora resultante sí refleja la transición de la zona horaria CST al horario de verano.


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


Adiciones de comunidad

AGREGAR
Mostrar:
© 2014 Microsoft