Partilhar via


Escolhendo entre DateTime, DateTimeOffset e TimeZoneInfo

Aplicativos .NET Framework que usam as informações de data e hora são muito diferentes e podem usar essas informações de diversas maneiras.Os usos mais comuns de informações de data e hora incluem uma ou mais dos seguintes:

  • Para refletir somente uma data, já que essa informação de hora não é importante.

  • Para refletir somente uma hora, já que essa informação de data não é importante.

  • Para refletir uma data abstrata e um tempo que não está vinculado a uma hora específica e local (por exemplo, a maioria dos armazéns em um âmbito internacional abre no dias da semana às 9: 00).

  • Para recuperar as informações de data e hora de fontes de fora do .NET Framework, normalmente no qual as informações de data e hora estão armazenadas em um tipo de dados simples.

  • Para identificar um único ponto no tempo exclusivamente e sem ambiguidade.Alguns aplicativos exigem que data e hora não sejam ambíguos somente no sistema host; outros requerem que ele não seja ambíguo entre sistemas (ou seja, uma data serializada em um sistema pode ser significantemente desserializada e usada em outro sistema em qualquer lugar no mundo).

  • Para preservar várias horas relacionadas (como o horário local do requisitor e hora de recebimento de uma solicitação Web do servidor).

  • Para executar data e hora aritméticas, possivelmente com um resultado que exclusivamente e sem ambiguidade identifica um único ponto no tempo.

O .NET Framework inclui os tipos DateTime, DateTimeOffset e TimeZoneInfo, sedo que todos podem ser usados para criar aplicativos que funcionam com as datas e horas.

Observação:

Este tópico não aborda um tipo de quarto TimeZone, porque sua funcionalidade é quase inteiramente incorporada a TimeZoneInfo classe. Sempre que possível, os desenvolvedores devem usar a classe TimeZoneInfo ao invés da classe TimeZone.

A Estrutura DateTime

Um valor DateTime define uma determinada data e hora.Iniciando com a versão 2.0 do .NET Framework, ele inclui uma propriedade Kind que fornece informações limitadas sobre a zona de tempo para o qual a data e a hora pertencem.O valor DateTimeKind retornado pela propriedade de Kind indica se o valor DateTime representa a hora local (DateTimeKind.Local), Tempo Universal Coordenado (UTC) (DateTimeKind.Utc) ou um tempo não especificado (DateTimeKind.Unspecified).

A estrutura DateTime é adequada para aplicativos que façam o seguinte:

  • Trabalha apenas com datas.

  • Trabalha somente com horas.

  • Trabalha com datas e horas abstratas.

  • Recupera as informações de fontes fora do .NET Framework, como bancos de dados SQL de data e hora.Normalmente, essas fontes armazenam informações sobre data e hora em um formato simples que é compatível com a estrutura DateTime.

  • Executa data e hora aritméticas, mas é preocupado com resultados gerais.Por exemplo, em uma operação de adição que soma seis meses a uma determinada data e hora, geralmente não é importante se o resultado é ajustado para horário de verão.

A menos que um determinado valor DateTime represente UTC, a data e valor de tempo são geralmente ambíguos ou limitados na sua portabilidade.Por exemplo, se um valor DateTime representa a hora local, ele é portátil dentro zona de tempo desse local (isto é, se o valor é desserializado em outro sistema na mesma zona de tempo, esse valor ainda identifica sem ambiguidade um único ponto no tempo).Fora da zona de tempo local, esse valor DateTime pode ter vários interpretações.Se Kind propriedade é DateTimeKind.Unspecified, é ainda menos portátil: Agora é ambíguo no mesmo fuso horário e possivelmente até mesmo no mesmo sistema em que foi serializado pela primeira vez.Somente se um valor DateTime representa o UTC esse valor identifica sem ambiguidade um único ponto no tempo, independentemente do sistema ou zona de tempo em que o valor é usado.

Observação importante:

Quando salvar ou compartilhar DateTime dados, UTC devem ser usados e o DateTime do valor Kind propriedade deve ser definida como DateTimeKind.Utc.

A Estrutura DateTimeOffset

A estrutura DateTimeOffset representa os valores de data e hora, junto com um valor de offset que indica quanto aquele valor diferencia o UTC.Assim, o valor sempre identifica sem ambiguidade um único ponto no tempo.

Embora o tipo DateTimeOffset inclui a maior parte da funcionalidade do tipo DateTime, ele não se destina a substituir o tipo DateTime no desenvolvimento de aplicativos.Em vez disso, ele é adequado para aplicativos que façam o seguinte:

  • Para identificar um único ponto no tempo exclusivamente e sem ambiguidade.O tipo DateTimeOffset pode ser usado para definir sem ambiguidade o significado de "agora", para log de transação de horários, para os horários de eventos do sistema ou aplicativo e para registrar horários de criação e modificação de arquivos.

  • Executar aritmética geral de data e hora.

  • Preserva várias horas relacionadas, enquanto aqueles horários são armazenados como dois valores separados ou como dois membros de uma estrutura.

Observação:

O SAR usa Para DateTimeOffset os valores são muito mais comuns que os DateTime valores. Como resultado, DateTimeOffset deve ser considerado o tipo padrão de data e hora para o desenvolvimento de aplicativos.

Um valor DateTimeOffset não está vinculado a uma determinada zona de tempo, mas pode ser originado de qualquer um dos vários fusos horários.Para ilustrar isso, o exemplo a seguir lista os fusos horários aos quais um número de valores DateTimeOffset (incluindo um horário local da Hora Oficial do Pacífico) pode pertencer.

Imports System.Collections.ObjectModel

Module TimeOffsets
   Public Sub Main()
      Dim thisTime As DateTimeOffset 

      thisTime = New DateTimeOffset(#06/10/2007#, New TimeSpan(-7, 0, 0))
      ShowPossibleTimeZones(thisTime) 

      thisTime = New DateTimeOffset(#03/10/2007#, New TimeSpan(-6, 0, 0))  
      ShowPossibleTimeZones(thisTime)

      thisTime = New DateTimeOffset(#03/10/2007#, New TimeSpan(+1, 0, 0))
      ShowPossibleTimeZones(thisTime)
   End Sub

   Private Sub ShowPossibleTimeZones(offsetTime As DateTimeOffset)
      Dim offset As TimeSpan = offsetTime.Offset
      Dim timeZones As ReadOnlyCollection(Of TimeZoneInfo)

      Console.WriteLine("{0} could belong to the following time zones:", _
                        offsetTime.ToString())
      ' Get all time zones defined on local system
      timeZones = TimeZoneInfo.GetSystemTimeZones()     
      ' Iterate time zones
      For Each timeZone As TimeZoneInfo In timeZones
         ' Compare offset with offset for that date in that time zone
         If timeZone.GetUtcOffset(offsetTime.DateTime).Equals(offset) Then
            Console.WriteLine("   {0}", timeZone.DisplayName)
         End If   
      Next
      Console.WriteLine()
   End Sub
End Module
' This example displays the following output to the console:
'       6/10/2007 12:00:00 AM -07:00 could belong to the following time zones:
'          (GMT-07:00) Arizona
'          (GMT-08:00) Pacific Time (US & Canada)
'          (GMT-08:00) Tijuana, Baja California
'       
'       3/10/2007 12:00:00 AM -06:00 could belong to the following time zones:
'          (GMT-06:00) Central America
'          (GMT-06:00) Central Time (US & Canada)
'          (GMT-06:00) Guadalajara, Mexico City, Monterrey - New
'          (GMT-06:00) Guadalajara, Mexico City, Monterrey - Old
'          (GMT-06:00) Saskatchewan
'       
'       3/10/2007 12:00:00 AM +01:00 could belong to the following time zones:
'          (GMT+01:00) Amsterdam, Berlin, Bern, Rome, Stockholm, Vienna
'          (GMT+01:00) Belgrade, Bratislava, Budapest, Ljubljana, Prague
'          (GMT+01:00) Brussels, Copenhagen, Madrid, Paris
'          (GMT+01:00) Sarajevo, Skopje, Warsaw, Zagreb
'          (GMT+01:00) West Central Africa
using System;
using System.Collections.ObjectModel;

public class TimeOffsets
{
   public static void Main()
   {
      DateTime thisDate = new DateTime(2007, 3, 10, 0, 0, 0);
      DateTime dstDate = new DateTime(2007, 6, 10, 0, 0, 0);
      DateTimeOffset thisTime;

      thisTime = new DateTimeOffset(dstDate, new TimeSpan(-7, 0, 0));
      ShowPossibleTimeZones(thisTime);

      thisTime = new DateTimeOffset(thisDate, new TimeSpan(-6, 0, 0));  
      ShowPossibleTimeZones(thisTime);

      thisTime = new DateTimeOffset(thisDate, new TimeSpan(+1, 0, 0));
      ShowPossibleTimeZones(thisTime);
   }

   private static void ShowPossibleTimeZones(DateTimeOffset offsetTime)
   {
      TimeSpan offset = offsetTime.Offset;
      ReadOnlyCollection<TimeZoneInfo> timeZones;

      Console.WriteLine("{0} could belong to the following time zones:", 
                        offsetTime.ToString());
      // Get all time zones defined on local system
      timeZones = TimeZoneInfo.GetSystemTimeZones();     
      // Iterate time zones 
      foreach (TimeZoneInfo timeZone in timeZones)
      {
         // Compare offset with offset for that date in that time zone
         if (timeZone.GetUtcOffset(offsetTime.DateTime).Equals(offset))
            Console.WriteLine("   {0}", timeZone.DisplayName);
      }
      Console.WriteLine();
   } 
}
// This example displays the following output to the console:
//       6/10/2007 12:00:00 AM -07:00 could belong to the following time zones:
//          (GMT-07:00) Arizona
//          (GMT-08:00) Pacific Time (US & Canada)
//          (GMT-08:00) Tijuana, Baja California
//       
//       3/10/2007 12:00:00 AM -06:00 could belong to the following time zones:
//          (GMT-06:00) Central America
//          (GMT-06:00) Central Time (US & Canada)
//          (GMT-06:00) Guadalajara, Mexico City, Monterrey - New
//          (GMT-06:00) Guadalajara, Mexico City, Monterrey - Old
//          (GMT-06:00) Saskatchewan
//       
//       3/10/2007 12:00:00 AM +01:00 could belong to the following time zones:
//          (GMT+01:00) Amsterdam, Berlin, Bern, Rome, Stockholm, Vienna
//          (GMT+01:00) Belgrade, Bratislava, Budapest, Ljubljana, Prague
//          (GMT+01:00) Brussels, Copenhagen, Madrid, Paris
//          (GMT+01:00) Sarajevo, Skopje, Warsaw, Zagreb
//          (GMT+01:00) West Central Africa

A saída mostra que cada valor de data e tempo nesse exemplo pode pertencer a pelo menos três fusos horários diferentes.O valor DateTimeOffset de 6/10/2007 mostra que se um valor de data e hora representa um horário de verão, seu deslocamento do UTC não corresponde necessariamente a origem do deslocamento base do UTC ou do deslocamento do UTC encontrado no seu nome de exibição.Isso significa que, como um único valor DateTimeOffset não é rigidamente aliado a sua zona de tempo, não é possível refletir uma transição da zona de tempo para e a partir do horário de verão.Isso poderá ser particularmente problemático quando a aritmética de data e hora é usada para manipular um valor DateTimeOffset.(Para uma discussão sobre como executar aritmética de data e hora de forma que leve em conta as regras de ajuste de uma zona de tempo, consulte Executando Operações Aritméticas com Datas e Horas.)

A Classe TimeZoneInfo

A classe TimeZoneInfo representa qualquer um dos fusos horários da terra e permite a conversão de qualquer data e hora em um zona de tempo para seu equivalente em outro zona de tempo.A classe TimeZoneInfo possibilita trabalhar com datas e horas de modo que qualquer valor de data e hora especificamente identifica um único ponto no tempo.A classe TimeZoneInfo também é extensível.Embora ele depende da zona de tempo as informações fornecidas pelos sistemas Windows e definidas no registro, ele oferece suporte à criação de fusos horários personalizados.Ele também oferece suporte a serialização e desserialização de informações de zonas de tempo.

Em alguns casos, tirar todo o proveito da classe TimeZoneInfo pode exige mais trabalho de desenvolvimento.Primeiro, valores de data e hora não são rigidamente agrupados com as zonas de tempo às quais elas pertencem.Como resultado, a menos que seu aplicativo forneça algum mecanismo para vincular uma data e hora com sua respectiva zona de tempo, é fácil para determinados valores de data e hora se tornarem desassociadas da sua zona de tempo.(Um método de vincular essa informação é definir uma classe ou estrutura que contenha o valor de data e valor de tempo e seu respectivo objeto de zona de tempo.) Em segundo lugar, o Windows XP e versões anteriores do Windows não oferecem suporte para informações históricas de zona de tempo, e Windows Vista possui somente suporte limitado.Aplicativos que são criados para lidar com datas e horas históricas devem fazer uso extensivo de fusos horários personalizados.

É possível tirar vantagem do suporte da zona de tempo no .NET Framework somente se a zona de tempo para qual valores de data e hora pertencem for conhecido quando esse objeto de data e hora é instanciado.Isso geralmente não é o caso, especialmente na Web ou aplicativos de rede.

Consulte também

Outros recursos

Horários e Zonas de Tempo