Convertendo horários entre fusos horáriosConverting times between time zones

Está se tornando cada vez mais importante para qualquer aplicativo que trabalha com datas e horas lidar com diferenças entre fusos horários.It is becoming increasingly important for any application that works with dates and times to handle differences between time zones. Um aplicativo não pode mais supor que todos os horários possam ser expressos na hora local, que é o tempo disponível da DateTime estrutura.An application can no longer assume that all times can be expressed in the local time, which is the time available from the DateTime structure. Por exemplo, uma página da Web que exibe a hora atual no leste dos Estados Unidos não terá credibilidade para um cliente no leste da Ásia.For example, a Web page that displays the current time in the eastern part of the United States will lack credibility to a customer in eastern Asia. Este tópico explica como converter horários de um fuso horário para outro, bem como converter DateTimeOffset valores que têm reconhecimento de fuso horário limitado.This topic explains how to convert times from one time zone to another, as well as how to convert DateTimeOffset values that have limited time zone awareness.

Convertendo para o Tempo Universal CoordenadoConverting to Coordinated Universal Time

O UTC (Tempo Universal Coordenado) é um padrão de tempo atômico de alta precisão.Coordinated Universal Time (UTC) is a high-precision, atomic time standard. Os fusos horários do mundo são expressos como deslocamentos positivos ou negativos do UTC.The world's time zones are expressed as positive or negative offsets from UTC. Sendo assim, o UTC fornece uma espécie de hora livre de fuso horário ou com fuso horário neutro.Thus, UTC provides a kind of time-zone free or time-zone neutral time. O uso da hora em UTC é recomendado quando a portabilidade da data e hora entre computadores é importante.The use of UTC time is recommended when a date and time's portability across computers is important. (Para obter detalhes e outras práticas recomendadas usando datas e horas, confira codificando práticas recomendadas usando DateTime no .NET Framework.) Converter fusos horários individuais em UTC facilita as comparações de tempo.(For details and other best practices using dates and times, see Coding best practices using DateTime in the .NET Framework.) Converting individual time zones to UTC makes time comparisons easy.

Observação

Você também pode serializar uma DateTimeOffset estrutura para representar de forma não ambígua um único ponto no tempo.You can also serialize a DateTimeOffset structure to unambiguously represent a single point in time. Como DateTimeOffset os objetos armazenam um valor de data e hora junto com seu deslocamento do UTC, eles sempre representam um determinado ponto no tempo em relação ao UTC.Because DateTimeOffset objects store a date and time value along with its offset from UTC, they always represent a particular point in time in relationship to UTC.

A maneira mais fácil de converter uma hora em UTC é chamar o static método ( Shared no Visual Basic) TimeZoneInfo.ConvertTimeToUtc(DateTime) .The easiest way to convert a time to UTC is to call the static (Shared in Visual Basic) TimeZoneInfo.ConvertTimeToUtc(DateTime) method. A conversão exata executada pelo método depende do valor da dateTime Propriedade do parâmetro Kind , como mostra a tabela a seguir.The exact conversion performed by the method depends on the value of the dateTime parameter's Kind property, as the following table shows.

DateTime.Kind ConversãoConversion
DateTimeKind.Local Converte a hora local para UTC.Converts local time to UTC.
DateTimeKind.Unspecified Presume que o parâmetro dateTime é a hora local e converte a hora local para UTC.Assumes the dateTime parameter is local time and converts local time to UTC.
DateTimeKind.Utc Retorna o parâmetro dateTime inalterado.Returns the dateTime parameter unchanged.

O código a seguir converte a hora local atual para UTC e exibe o resultado no console.The following code converts the current local time to UTC and displays the result to the console.

DateTime dateNow = DateTime.Now;
Console.WriteLine("The date and time are {0} UTC.",
                   TimeZoneInfo.ConvertTimeToUtc(dateNow));
Dim dateNow As Date = Date.Now
Console.WriteLine("The date and time are {0} UTC.", _
                  TimeZoneInfo.ConvertTimeToUtc(dateNow))

Se o valor de data e hora não representar a hora local ou UTC, o ToUniversalTime método provavelmente retornará um resultado errado.If the date and time value does not represent either the local time or UTC, the ToUniversalTime method will likely return an erroneous result. No entanto, você pode usar o TimeZoneInfo.ConvertTimeToUtc método para converter a data e a hora de um fuso horário especificado.However, you can use the TimeZoneInfo.ConvertTimeToUtc method to convert the date and time from a specified time zone. (Para obter detalhes sobre como recuperar um TimeZoneInfo objeto que representa o fuso horário de destino, consulte localizando os fusos horários definidos em um sistema local.) O código a seguir usa o TimeZoneInfo.ConvertTimeToUtc método para converter o horário padrão do leste para UTC.(For details on retrieving a TimeZoneInfo object that represents the destination time zone, see Finding the time zones defined on a local system.) The following code uses the TimeZoneInfo.ConvertTimeToUtc method to convert Eastern Standard Time to UTC.

DateTime easternTime = new DateTime(2007, 01, 02, 12, 16, 00);
string easternZoneId = "Eastern Standard Time";
try
{
   TimeZoneInfo easternZone = TimeZoneInfo.FindSystemTimeZoneById(easternZoneId);
   Console.WriteLine("The date and time are {0} UTC.",
                     TimeZoneInfo.ConvertTimeToUtc(easternTime, easternZone));
}
catch (TimeZoneNotFoundException)
{
   Console.WriteLine("Unable to find the {0} zone in the registry.",
                     easternZoneId);
}
catch (InvalidTimeZoneException)
{
   Console.WriteLine("Registry data on the {0} zone has been corrupted.",
                     easternZoneId);
}
Dim easternTime As New Date(2007, 01, 02, 12, 16, 00)
Dim easternZoneId As String = "Eastern Standard Time"
Try
    Dim easternZone As TimeZoneInfo = TimeZoneInfo.FindSystemTimeZoneById(easternZoneId)
    Console.WriteLine("The date and time are {0} UTC.", _
                      TimeZoneInfo.ConvertTimeToUtc(easternTime, easternZone))
Catch e As TimeZoneNotFoundException
    Console.WriteLine("Unable to find the {0} zone in the registry.", _
                      easternZoneId)
Catch e As InvalidTimeZoneException
    Console.WriteLine("Registry data on the {0} zone has been corrupted.", _
                      easternZoneId)
End Try

Observe que esse método gera um ArgumentException se a DateTime Propriedade do objeto Kind e o fuso horário não forem correspondentes.Note that this method throws an ArgumentException if the DateTime object's Kind property and the time zone are mismatched. Uma incompatibilidade ocorrerá se a Kind propriedade for DateTimeKind.Local , mas o TimeZoneInfo objeto não representar o fuso horário local ou se a Kind propriedade for DateTimeKind.Utc , mas o objeto não for TimeZoneInfo igual TimeZoneInfo.Utc .A mismatch occurs if the Kind property is DateTimeKind.Local but the TimeZoneInfo object does not represent the local time zone, or if the Kind property is DateTimeKind.Utc but the TimeZoneInfo object does not equal TimeZoneInfo.Utc.

Todos esses métodos usam DateTime valores como parâmetros e retornam um DateTime valor.All of these methods take DateTime values as parameters and return a DateTime value. Para DateTimeOffset valores, a DateTimeOffset estrutura tem um ToUniversalTime método de instância que converte a data e a hora da instância atual em UTC.For DateTimeOffset values, the DateTimeOffset structure has a ToUniversalTime instance method that converts the date and time of the current instance to UTC. O exemplo a seguir chama o ToUniversalTime método para converter uma hora local e várias outras vezes em UTC (tempo Universal Coordenado).The following example calls the ToUniversalTime method to convert a local time and several other times to Coordinated Universal Time (UTC).

DateTimeOffset localTime, otherTime, universalTime;

// Define local time in local time zone
localTime = new DateTimeOffset(new DateTime(2007, 6, 15, 12, 0, 0));
Console.WriteLine("Local time: {0}", localTime);
Console.WriteLine();

// Convert local time to offset 0 and assign to otherTime
otherTime = localTime.ToOffset(TimeSpan.Zero);
Console.WriteLine("Other time: {0}", otherTime);
Console.WriteLine("{0} = {1}: {2}",
                  localTime, otherTime,
                  localTime.Equals(otherTime));
Console.WriteLine("{0} exactly equals {1}: {2}",
                  localTime, otherTime,
                  localTime.EqualsExact(otherTime));
Console.WriteLine();

// Convert other time to UTC
universalTime = localTime.ToUniversalTime();
Console.WriteLine("Universal time: {0}", universalTime);
Console.WriteLine("{0} = {1}: {2}",
                  otherTime, universalTime,
                  universalTime.Equals(otherTime));
Console.WriteLine("{0} exactly equals {1}: {2}",
                  otherTime, universalTime,
                  universalTime.EqualsExact(otherTime));
Console.WriteLine();
// The example produces the following output to the console:
//    Local time: 6/15/2007 12:00:00 PM -07:00
//
//    Other time: 6/15/2007 7:00:00 PM +00:00
//    6/15/2007 12:00:00 PM -07:00 = 6/15/2007 7:00:00 PM +00:00: True
//    6/15/2007 12:00:00 PM -07:00 exactly equals 6/15/2007 7:00:00 PM +00:00: False
//
//    Universal time: 6/15/2007 7:00:00 PM +00:00
//    6/15/2007 7:00:00 PM +00:00 = 6/15/2007 7:00:00 PM +00:00: True
//    6/15/2007 7:00:00 PM +00:00 exactly equals 6/15/2007 7:00:00 PM +00:00: True
Dim localTime, otherTime, universalTime As DateTimeOffset

' Define local time in local time zone
localTime = New DateTimeOffset(#6/15/2007 12:00:00PM#)
Console.WriteLine("Local time: {0}", localTime)
Console.WriteLine()

' Convert local time to offset 0 and assign to otherTime
otherTime = localTime.ToOffset(TimeSpan.Zero)
Console.WriteLine("Other time: {0}", otherTime)
Console.WriteLine("{0} = {1}: {2}", _
                  localTime, otherTime, _
                  localTime.Equals(otherTime))
Console.WriteLine("{0} exactly equals {1}: {2}", _
                  localTime, otherTime, _
                  localTime.EqualsExact(otherTime))
Console.WriteLine()

' Convert other time to UTC
universalTime = localTime.ToUniversalTime()
Console.WriteLine("Universal time: {0}", universalTime)
Console.WriteLine("{0} = {1}: {2}", _
                  otherTime, universalTime, _
                  universalTime.Equals(otherTime))
Console.WriteLine("{0} exactly equals {1}: {2}", _
                  otherTime, universalTime, _
                  universalTime.EqualsExact(otherTime))
Console.WriteLine()
' The example produces the following output to the console:
'    Local time: 6/15/2007 12:00:00 PM -07:00
'    
'    Other time: 6/15/2007 7:00:00 PM +00:00
'    6/15/2007 12:00:00 PM -07:00 = 6/15/2007 7:00:00 PM +00:00: True
'    6/15/2007 12:00:00 PM -07:00 exactly equals 6/15/2007 7:00:00 PM +00:00: False
'    
'    Universal time: 6/15/2007 7:00:00 PM +00:00
'    6/15/2007 7:00:00 PM +00:00 = 6/15/2007 7:00:00 PM +00:00: True
'    6/15/2007 7:00:00 PM +00:00 exactly equals 6/15/2007 7:00:00 PM +00:00: True   

Convertendo UTC em um fuso horário designadoConverting UTC to a designated time zone

Para converter UTC em hora local, consulte a seção "convertendo UTC para a hora local" a seguir.To convert UTC to local time, see the "Converting UTC to Local Time" section that follows. Para converter o UTC para a hora em qualquer fuso horário que você designar, chame o ConvertTimeFromUtc método.To convert UTC to the time in any time zone that you designate, call the ConvertTimeFromUtc method. O método utiliza dois parâmetros:The method takes two parameters:

  • O UTC a ser convertido.The UTC to convert. Deve ser um DateTime valor cuja Kind propriedade seja definida como Unspecified ou Utc .This must be a DateTime value whose Kind property is set to Unspecified or Utc.

  • O fuso horário no qual o UTC deve ser convertido.The time zone to convert the UTC to.

O código a seguir converte o UTC para o Horário Padrão Central.The following code converts UTC to Central Standard Time.

DateTime timeUtc = DateTime.UtcNow;
try
{
   TimeZoneInfo cstZone = TimeZoneInfo.FindSystemTimeZoneById("Central Standard Time");
   DateTime cstTime = TimeZoneInfo.ConvertTimeFromUtc(timeUtc, cstZone);
   Console.WriteLine("The date and time are {0} {1}.",
                     cstTime,
                     cstZone.IsDaylightSavingTime(cstTime) ?
                             cstZone.DaylightName : cstZone.StandardName);
}
catch (TimeZoneNotFoundException)
{
   Console.WriteLine("The registry does not define the Central Standard Time zone.");
}
catch (InvalidTimeZoneException)
{
   Console.WriteLine("Registry data on the Central Standard Time zone has been corrupted.");
}
Dim timeUtc As Date = Date.UtcNow
Try
    Dim cstZone As TimeZoneInfo = TimeZoneInfo.FindSystemTimeZoneById("Central Standard Time")
    Dim cstTime As Date = TimeZoneInfo.ConvertTimeFromUtc(timeUtc, cstZone)
    Console.WriteLine("The date and time are {0} {1}.", _
                      cstTime, _
                      IIf(cstZone.IsDaylightSavingTime(cstTime), _
                          cstZone.DaylightName, cstZone.StandardName))
Catch e As TimeZoneNotFoundException
    Console.WriteLine("The registry does not define the Central Standard Time zone.")
Catch e As InvalidTimeZoneException
    Console.WriteLine("Registry data on the Central Standard Time zone has been corrupted.")
End Try

Convertendo UTC em hora localConverting UTC to local time

Para converter UTC em hora local, chame o ToLocalTime método do DateTime objeto cujo tempo você deseja converter.To convert UTC to local time, call the ToLocalTime method of the DateTime object whose time you want to convert. O comportamento exato do método depende do valor da Propriedade do objeto Kind , como mostra a tabela a seguir.The exact behavior of the method depends on the value of the object's Kind property, as the following table shows.

DateTime.Kind ConversãoConversion
DateTimeKind.Local Retorna o DateTime valor inalterado.Returns the DateTime value unchanged.
DateTimeKind.Unspecified Pressupõe que o DateTime valor é UTC e converte o UTC para a hora local.Assumes that the DateTime value is UTC and converts the UTC to local time.
DateTimeKind.Utc Converte o DateTime valor em hora local.Converts the DateTime value to local time.

Observação

O TimeZone.ToLocalTime método se comporta de forma idêntica ao DateTime.ToLocalTime método.The TimeZone.ToLocalTime method behaves identically to the DateTime.ToLocalTime method. Ele usa um único parâmetro, que é o valor de data e hora a ser convertido.It takes a single parameter, which is the date and time value to convert.

Você também pode converter a hora em qualquer fuso horário designado para a hora local usando o static Shared método (no Visual Basic) TimeZoneInfo.ConvertTime .You can also convert the time in any designated time zone to local time by using the static (Shared in Visual Basic) TimeZoneInfo.ConvertTime method. Essa técnica é discutida na próxima seção.This technique is discussed in the next section.

Convertendo entre dois fusos horáriosConverting between any two time zones

Você pode converter entre dois fusos horários usando um dos dois static Shared métodos (em Visual Basic) a seguir da TimeZoneInfo classe:You can convert between any two time zones by using either of the following two static (Shared in Visual Basic) methods of the TimeZoneInfo class:

  • ConvertTime

    Os parâmetros desse método são o valor de data e hora a ser convertido, um TimeZoneInfo objeto que representa o fuso horário do valor de data e hora e um TimeZoneInfo objeto que representa o fuso horário para o qual converter o valor de data e hora.This method's parameters are the date and time value to convert, a TimeZoneInfo object that represents the time zone of the date and time value, and a TimeZoneInfo object that represents the time zone to convert the date and time value to.

  • ConvertTimeBySystemTimeZoneId

    Os parâmetros do método são o valor de data e hora a ser convertido, o identificador do fuso horário do valor de data e hora e o identificador do fuso horário para o qual converter o valor de data e hora.This method's parameters are the date and time value to convert, the identifier of the date and time value's time zone, and the identifier of the time zone to convert the date and time value to.

Os dois métodos exigem que a Kind Propriedade do valor de data e hora para converter e o TimeZoneInfo identificador de objeto ou de fuso horário que representa seu fuso horário correspondam uns aos outros.Both methods require that the Kind property of the date and time value to convert and the TimeZoneInfo object or time zone identifier that represents its time zone correspond to one another. Caso contrário, um ArgumentException será gerado.Otherwise, an ArgumentException is thrown. Por exemplo, se a Kind Propriedade do valor de data e hora for DateTimeKind.Local , uma exceção será gerada se o TimeZoneInfo objeto passado como um parâmetro para o método não for igual a TimeZoneInfo.Local .For example, if the Kind property of the date and time value is DateTimeKind.Local, an exception is thrown if the TimeZoneInfo object passed as a parameter to the method is not equal to TimeZoneInfo.Local. Uma exceção também será gerada se o identificador passado como um parâmetro para o método não for igual a TimeZoneInfo.Local.Id .An exception is also thrown if the identifier passed as a parameter to the method is not equal to TimeZoneInfo.Local.Id.

O exemplo a seguir usa o ConvertTime método para converter do horário padrão do Havaí para a hora local.The following example uses the ConvertTime method to convert from Hawaiian Standard Time to local time.

DateTime hwTime = new DateTime(2007, 02, 01, 08, 00, 00);
try
{
   TimeZoneInfo hwZone = TimeZoneInfo.FindSystemTimeZoneById("Hawaiian Standard Time");
   Console.WriteLine("{0} {1} is {2} local time.",
           hwTime,
           hwZone.IsDaylightSavingTime(hwTime) ? hwZone.DaylightName : hwZone.StandardName,
           TimeZoneInfo.ConvertTime(hwTime, hwZone, TimeZoneInfo.Local));
}
catch (TimeZoneNotFoundException)
{
   Console.WriteLine("The registry does not define the Hawaiian Standard Time zone.");
}
catch (InvalidTimeZoneException)
{
   Console.WriteLine("Registry data on the Hawaiian Standard Time zone has been corrupted.");
}
Dim hwTime As Date = #2/01/2007 8:00:00 AM#
Try
    Dim hwZone As TimeZoneInfo = TimeZoneInfo.FindSystemTimeZoneById("Hawaiian Standard Time")
    Console.WriteLine("{0} {1} is {2} local time.", _
                      hwTime, _
                      IIf(hwZone.IsDaylightSavingTime(hwTime), hwZone.DaylightName, hwZone.StandardName), _
                      TimeZoneInfo.ConvertTime(hwTime, hwZone, TimeZoneInfo.Local))
Catch e As TimeZoneNotFoundException
    Console.WriteLine("The registry does not define the Hawaiian Standard Time zone.")
Catch e As InvalidTimeZoneException
    Console.WriteLine("Registry data on the Hawaiian Standard Time zone has been corrupted.")
End Try

Convertendo valores de DateTimeOffsetConverting DateTimeOffset values

Os valores de data e hora representados por DateTimeOffset objetos não têm reconhecimento total de fuso horário porque o objeto é desassociado de seu fuso horário no momento em que é instanciado.Date and time values represented by DateTimeOffset objects are not fully time-zone aware because the object is disassociated from its time zone at the time it is instantiated. No entanto, em muitos casos o aplicativo precisa apenas converter uma data e hora com base em dois deslocamentos diferentes do UTC, em vez da hora em fusos horários específicos.However, in many cases an application simply needs to convert a date and time based on two different offsets from UTC rather than on the time in particular time zones. Para executar essa conversão, você pode chamar o método da instância atual ToOffset .To perform this conversion, you can call the current instance's ToOffset method. O parâmetro único do método é o deslocamento do novo valor de data e hora que o método deve retornar.The method's single parameter is the offset of the new date and time value that the method is to return.

Por exemplo, se a data e hora da solicitação de um usuário de uma página da Web for conhecida e for serializada como uma cadeia de caracteres no formato MM/dd/aaaa hh:mm:ss zzzz, o seguinte método ReturnTimeOnServer converte esse valor de data e hora para a data e hora no servidor Web.For example, if the date and time of a user request for a Web page is known and is serialized as a string in the format MM/dd/yyyy hh:mm:ss zzzz, the following ReturnTimeOnServer method converts this date and time value to the date and time on the Web server.

public DateTimeOffset ReturnTimeOnServer(string clientString)
{
   string format = @"M/d/yyyy H:m:s zzz";
   TimeSpan serverOffset = TimeZoneInfo.Local.GetUtcOffset(DateTimeOffset.Now);

   try
   {
      DateTimeOffset clientTime = DateTimeOffset.ParseExact(clientString, format, CultureInfo.InvariantCulture);
      DateTimeOffset serverTime = clientTime.ToOffset(serverOffset);
      return serverTime;
   }
   catch (FormatException)
   {
      return DateTimeOffset.MinValue;
   }
}
Public Function ReturnTimeOnServer(clientString As String) As DateTimeOffset
    Dim format As String = "M/d/yyyy H:m:s zzz"
    Dim serverOffset As TimeSpan = TimeZoneInfo.Local.GetUtcOffset(DateTimeOffset.Now)

    Try
        Dim clientTime As DateTimeOffset = DateTimeOffset.ParseExact(clientString, format, CultureInfo.InvariantCulture)
        Dim serverTime As DateTimeOffset = clientTime.ToOffset(serverOffset)
        Return serverTime
    Catch e As FormatException
        Return DateTimeOffset.MinValue
    End Try
End Function

Se o método for passado para a cadeia de caracteres "9/1/2007 5:32:07 -05:00", que representa a data e a hora em um fuso horário cinco horas anteriores à UTC, ele retornará 9/1/2007 3:32:07 AM-07:00 para um servidor localizado no fuso horário padrão do Pacífico americano.If the method is passed the string "9/1/2007 5:32:07 -05:00", which represents the date and time in a time zone five hours earlier than UTC, it returns 9/1/2007 3:32:07 AM -07:00 for a server located in the U.S. Pacific Standard Time zone.

A TimeZoneInfo classe também inclui uma sobrecarga do TimeZoneInfo.ConvertTime(DateTimeOffset, TimeZoneInfo) método que executa conversões de fuso horário com ToOffset(TimeSpan) valores.The TimeZoneInfo class also includes an overload of the TimeZoneInfo.ConvertTime(DateTimeOffset, TimeZoneInfo) method that performs time zone conversions with ToOffset(TimeSpan) values. Os parâmetros do método são um DateTimeOffset valor e uma referência ao fuso horário no qual o tempo deve ser convertido.The method's parameters are a DateTimeOffset value and a reference to the time zone to which the time is to be converted. A chamada do método retorna um DateTimeOffset valor.The method call returns a DateTimeOffset value. Por exemplo, o ReturnTimeOnServer método no exemplo anterior poderia ser reescrito da seguinte maneira para chamar o ConvertTime(DateTimeOffset, TimeZoneInfo) método.For example, the ReturnTimeOnServer method in the previous example could be rewritten as follows to call the ConvertTime(DateTimeOffset, TimeZoneInfo) method.

public DateTimeOffset ReturnTimeOnServer(string clientString)
{
   string format = @"M/d/yyyy H:m:s zzz";

   try
   {
      DateTimeOffset clientTime = DateTimeOffset.ParseExact(clientString, format,
                                  CultureInfo.InvariantCulture);
      DateTimeOffset serverTime = TimeZoneInfo.ConvertTime(clientTime,
                                  TimeZoneInfo.Local);
      return serverTime;
   }
   catch (FormatException)
   {
      return DateTimeOffset.MinValue;
   }
}
Public Function ReturnTimeOnServer(clientString As String) As DateTimeOffset
    Dim format As String = "M/d/yyyy H:m:s zzz"

    Try
        Dim clientTime As DateTimeOffset = DateTimeOffset.ParseExact(clientString, format, CultureInfo.InvariantCulture)
        Dim serverTime As DateTimeOffset = TimeZoneInfo.ConvertTime(clientTime, TimeZoneInfo.Local)
        Return serverTime
    Catch e As FormatException
        Return DateTimeOffset.MinValue
    End Try
End Function

Confira tambémSee also